Multilingual pages (WPML and Polylang)
5 min read
With the Business plan a task can create one page per row and language: "Lyon" in English at /guides/lyon/, in German at /de/guides/lyon/ and so on, each with translated values from your data, hreflang tags and language switcher links.
For a checklist of the common multilingual problems, see Troubleshooting.
Requirements
- Plan Business or higher.
- WPML or Polylang active with at least two languages. If both are active WPML is used.
- A task in row or combination mode with a template.
Without Business the step Languages shows a plan badge and the message "This task creates pages in several languages, which your plan no longer includes. Existing pages keep working; turn the languages off to save changes." applies to tasks created earlier. Without a multilingual plugin the step says "Neither WPML nor Polylang is active. The language pages keep working, but generation pauses until the plugin is back." or, for a new task, "To create pages in several languages, install and set up WPML or Polylang." Saving a task with languages without a plugin is refused: "Pages in several languages need WPML or Polylang. Activate one, or turn the languages off." A language that is not active in the plugin is refused too: "The language "xx" is not active in the multilingual plugin."
Set it up
- Open the task, step Languages ("Create every page in each language of WPML or Polylang, with translated values from your data, hreflang tags and language switcher links.").
- Under Languages from WPML (or Polylang) tick the languages. Each shows its URL prefix or "no URL prefix", and "default" for the default language. "Leave all unchecked for one page per row. Each checked language gets its own page per row, linked with hreflang tags and the language switcher."
- Choose When a row has no translation:
- Use the base values (default language) for that page, or
- Skip the page in that language.
- Add the translated columns to your data (below), Save and run now.
Turn languages off sets the task back to one page per row.
Translated columns
Translations live in the same data table as extra columns named after the base column plus the language code:
Base column | German | French | Brazilian Portuguese |
|---|---|---|---|
|
|
|
|
|
|
|
|
The editor says it like this: "Translated values come from columns named after the base column plus the language code: “name_de” holds the “name” value for German. Variables such as {{ pseo.src.… }} then use the translation on that language’s pages."
Rules (tested):
- The code is lowercase and a dash becomes an underscore:
pt-brreadsname_pt_br. - A translated column counts only if the base column exists too.
- An empty translation falls back to the base value, per column. For
Lyonwithname_de = "Lyon DE"and an emptycountry_dethe German page usesLyon DEand the basecountry. - The translation replaces the base value everywhere on that language's page: URL pattern, title, content, SEO title, description and structured data.
- The default language page uses the base columns.
- With Skip the page in that language a non-default language page is created only if the row has at least one translated column for that language and every such column holds a value. A row with no
_decolumns at all gets no German page. The default-language page is always created.
URLs
Every language variant is a separate page with its own URL (see URL and title patterns); the patterns run on the translated row, so name_de can give a German slug.
Your multilingual plugin's URL mode | URL of the variant |
|---|---|
Language directory, default language hidden | Default: |
Language directory, default language shown |
|
Language subdomain or domain |
|
Language parameter ( |
|
Redirects between variants are allowed for the hosts of your languages only. If you change the default language later, the next run moves pages to the new paths with 301 redirects.
What a language page prints
<html lang="…">for the language,hreflangalternates for every live language variant of the same row plusx-default(the default language variant). They appear when at least two variants exist,- the language switcher of WPML (
icl_ls_languages) or Polylang (pll_the_language_link,pll_translation_url) points to the variants, not to the template's translations, - the plugin's own hreflang output is suppressed on these pages because it would describe the template post,
canonical,og:urlandog:localeof the variant,- the variant's URL in the sitemaps (Sitemaps).
The page runs in its language: WPML/Polylang switch to it, and WordPress switches the locale for strings your template prints.
Limits, counters and conversion
- Each variant counts as one page against your page limit; 500 rows in 4 languages are 2,000 pages (Limits and plans). A batch handles rows divided by the number of languages.
- At most 50 languages per task.
- Internal link lists show pages of the same language (Internal links).
- Converting a multilingual task gives every post its page's language and links the posts of one row as translations (Converting to posts).
- If the multilingual plugin is deactivated, pages keep serving; the next run stops with "The task creates pages in several languages, but neither WPML nor Polylang is active. Existing pages keep working; generation continues once the plugin is back." and removes nothing.
- After a downgrade from Business, existing language pages keep serving; generation stops with "Pages in several languages need the Business plan. Existing pages keep working."
The REST route GET /wp-json/wpmcf/v1/pseo/languages lists what the editor shows: whether languages are allowed, the plugin (wpml, polylang or none), the default language and the active languages.
Translating the field values of posts (WPML and Polylang) is a separate Business feature and is not part of Programmatic SEO.
Still stuck? Contact support