Either way, a page in a language renders in that language, gets
<html lang>, reciprocal hreflang links, a self canonical and sitemap
alternates, and can show a language switcher and a “this page is also in
Romanian” prompt. See SEO for multilingual sites
and Language prompt and switcher.
Nothing changes for a brand that does not use it: a page without a language
renders exactly as before.
Set up your languages
Both models start with the brand’s languages. Open Pages → Advanced → Translations.
1
Add a language
Click Add language and enter:
2
Add the default language too
Add your main language (usually
en) and switch on Default language.
Without it, ElasticFunnels cannot tell which version is the main one for
hreflang="x-default" or for text fallbacks.Codes are matched exactly.
pt and pt-br are two languages: add both if you
need both. A language that pages or components use can’t be deleted or have
its code changed; the error says how many use it.Linked pages: one page per language
Each language version is its own page with its own slug, HTML, SEO title and description, revisions and split tests. One page is the original; the others are its translations. Together they are a translation group. The CLI calls the original the source.Give the original its language
Open the original page’s settings and the Language tab. Set Page language to the language it is written in. Not set keeps the page as it was before languages existed.
Make a translation
In the Translations panel on the same tab, pick a language in Add translation in, check the URL, and click Add translation. ElasticFunnels makes a draft copy of the original in that language, links the two, and proposes the URL<prefix>/<original slug>:
Change the URL to a translated one if you want (
ro/despre). Then translate
the copy, the SEO title and description, and publish the page. If the brand
has no languages yet, the panel says Add your languages first. with a link
to Go to Translations.
The panel lists every version: Original, (this one) for the page you
are on, the language of each, and links to Open the page and Open its
settings.
With the CLI:
Link pages you already have
If the Romanian page already exists, link it instead of copying. This is done with the CLI:- A group has at most one page per language.
- One level only: a translation’s original is never itself a translation. Link every translation to the same original.
- An original with no language counts as the default language.
- Unlinking or deleting a translation leaves the other pages as they are. Deleting the original makes its first translation the new original.
When the original changes
A translation remembers the text of its original at the moment it was made or last marked up to date (the SEO title, the SEO description and the page’s visible text; markup, scripts and styles do not count). When the original’s text changes, the translation shows Out of date in the Translations panel. Update the translation, then click Mark up to date. In the CLI,ef i18n check
lists every stale and missing translation and exits with an error when one is
stale, so you can use it before you publish:
Components in a language
A page in Romanian that includes theheader component uses the Romanian
translation of header when there is one, and the base header otherwise.
Make a component translation the same way as a page translation, from the
component’s Translations panel (it asks for a Code instead of a URL), or
with the CLI:
{{ t('nav.home') }}. Those follow the page’s language too (see below). Pick
by what differs:
For links in shared navigation, use
page_url('<slug>') instead of writing
the path. It returns the URL of that page’s translation in the current page’s
language, and the page itself when there is no translation:
/ro/despre this links to /ro, /ro/features and /ro/pricing when
those translations exist.
Funnels keep the visitor’s language
When a funnel step or a/page?id= link sends a visitor to a page that has a
translation in the language of the page they are on, they land on that
translation. Build the funnel once, with the original pages.
Dictionary pages: one page, texts per language
A dictionary page is one page for every language. Its texts are keys, and the brand dictionary holds one value per language.Add texts
The Texts section of Pages → Advanced → Translations lists every text in every language, with a Language column. Pick a language in the filter to see one.
- Click Add text.
- Pick the Language. It starts on the brand’s default language.
- Enter a Key (for example
hero.title) and the Text, then save.
hero.title, checkout.cta,
faq.refund_policy. Use letters, numbers, underscores and dots. The same key
repeats in every language: that is how ElasticFunnels knows the English
hero.title and the Romanian hero.title are the same text.
Bulk edit opens a spreadsheet-style editor for one language at a time. If
the list is on All languages, it switches to the default language first.
Add or change many keys, then click Save all changes. The batch saves
together: if a row fails, nothing is saved.
With the CLI, the dictionary is one JSON file per language:
Use texts in a page
A missing text falls back.
t() and | t look in the page’s language,
then the default language, then ElasticFunnels’ built-in texts, and finally
show the last part of the key (hero.title shows title). data-ef-hl uses
the default language’s text, then keeps the element’s own markup.
getTranslation() returns '' when no language has the key. So a key only
needs a value in the languages where it differs, and visitors never see a raw
key such as hero.title.
Prefix routing
In Pages → Advanced → Translations, under Language URLs, switch on Serve pages under language folders (prefix routing), or runef i18n settings --prefix-routing on. Then a request for
/<prefix>/<slug> serves the dictionary page <slug> in that language:

A real page always wins: if a page with the slug
ro/about exists, /ro/about
serves it. Prefix routing only applies to pages without a language; a linked
page in a language is served at its own slug. Each prefixed URL has its own
canonical, and gets hreflang and sitemap alternates like a linked page.
Using translations in backend scripts
Backend scripts (<script scope="backend">) have the same helpers, all async:
await t('key'). See
Backend scripts → Data functions.
Which language a page renders in
- The page’s language. A page with a language always renders in it,
whatever the visitor’s browser or a
?hl=parameter says. - The URL prefix, for a dictionary page served under prefix routing.
- For a page with neither, the old order still applies, first match wins:
a
hlorlocaleplaceholder in a wildcard route (such as the slugdocs/{hl}), then?hl=,?locale=or?lang=, then the visitor’s session, the domain’s and the brand’s language setting, the browser’sAccept-Language, and finally the default language.
?hl= keeps working on pages without a language, which suits checkouts that
need the visitor’s language from the page before. It gives one URL for every
language, so search engines can index only one version: use linked pages or
prefix routing for pages you want found in search.
Template variables
Every page in a translation group, and every page served under a prefix, has these in its template:
A switcher written in the template:
Permissions
Languages and texts follow the Translations permissions in your role:view, create, update, delete. Page translations follow the Pages
permissions.
Patterns and pitfalls
- Set a default language before you link pages, so
x-defaultand the text fallback have a target. - Keep keys stable. Renaming a key in the dictionary does not change your templates. Rename only when the meaning of the text changes.
- Do not redirect by language in a script. Search engines crawl mostly
from the US with no
Accept-Language, so a redirect hides your other versions. The language prompt suggests instead. - Keep a translation offline until it is ready. A page with the status
draft still answers on its live URL, and a new translation starts as a draft
copy of the original’s text.
ef pages settings ro/about --status offlinehides it; set it to published when the copy is translated.
Related
- Language prompt and switcher: suggest the visitor’s language and let them switch.
- SEO:
hreflang, canonical links and sitemap alternates. - Multilingual sites from the ef CLI: every command, and a publish check for stale translations.
- Wildcard routes: placeholders in slugs.
- Privacy & consent: the cookie banner picks the page’s language.