Internationalization (i18n)
Meno supports multi-language websites out of the box. You define which locales your project supports, then provide translations per locale for any text content. At build time, each locale gets its own set of HTML pages with the correct language content and URL prefixes.
Setting Up Locales
Open Settings in the sidebar (or edit
project.config.jsondirectly).Under Internationalization, add the locales your site supports.
Set one locale as the default locale. This locale has no URL prefix -- its pages live at the root (e.g.
/about). All other locales get a prefix (e.g./pl/about).Save. A locale switcher appears in the editor toolbar, letting you preview content in each language.
Configuration in project.config.json
{
"i18n": {
"defaultLocale": "en",
"locales": [
{
"code": "en",
"name": "EN",
"nativeName": "EN",
"langTag": "en-US",
"icon": "/icons/us.svg"
},
{
"code": "pl",
"name": "PL",
"nativeName": "PL",
"langTag": "pl-PL",
"icon": "/icons/pl.svg"
},
{
"code": "de",
"name": "DE",
"nativeName": "DE",
"langTag": "de-DE",
"icon": "/icons/de.svg"
}
]
}
}Each locale object has these fields:
Field | Description |
|---|---|
| Short locale code used in URLs and data (e.g. |
| Display name in the default language |
| Display name in the locale's own language |
| BCP 47 language tag for the |
| Optional path to a flag icon |
Translating Content in the Editor
Use the locale switcher in the toolbar to select a locale.
Select any element on the canvas.
In the Properties panel, text fields show per-locale inputs when i18n is configured. Type the translation for the currently selected locale.
Switch to another locale and enter its translation.
The canvas updates in real time to show content for the active locale.
The editor stores translations using the _i18n object format (described in
the "Under the Hood" section below). You do not need to write this format
manually -- the editor handles it for you.
URL Structure
Meno generates locale-prefixed URLs for all non-default locales:
Locale | URL |
|---|---|
|
|
|
|
|
|
For CMS items, the same pattern applies. A blog post with slug my-post:
Locale | URL |
|---|---|
|
|
|
|
If the CMS item has an i18n slug field, the slug itself can differ per locale,
allowing fully localized URLs like /pl/blog/moj-post.
Adding a Language Switcher
To let visitors switch languages on the live site, add a Locale List node.
Select the element where you want the switcher (typically a nav bar).
Open the Command Palette (Cmd+E / Ctrl+E) and choose Add Locale List.
The node appears in the structure tree. Select it to configure its properties.
Locale List Properties
Property | Type | Description |
|---|---|---|
| string | How to show locale text: |
| boolean | Show the flag icon next to the label |
| boolean | Include the currently active locale in the list |
| boolean | Show a separator between locale links |
Styling
The Locale List supports these style slots:
Slot | Applies to |
|---|---|
| The outer container |
| Each locale link |
| The link for the current locale |
| The separator element |
| The flag icon |
All style slots accept the same responsive style format used throughout Meno
(with base, tablet, and mobile breakpoints).
CMS i18n Fields
CMS collections can have per-locale content using the i18n and i18n-text
field types.
When defining a collection schema, set a field's type to
i18n(for single-line text) ori18n-text(for multi-line text).In the CMS field editor, an input appears for each configured locale. Fill in the translation for each language.
In templates, use the same
{{cms.fieldName}}expression. The correct locale value is resolved automatically based on the page's current locale.
Example Schema with i18n Fields
In the template page's meta.cms.fields:
{
"title": {
"type": "i18n",
"required": true,
"label": "Title"
},
"description": {
"type": "i18n-text",
"label": "Description"
},
"slug": {
"type": "i18n",
"required": true,
"label": "URL Slug"
},
"category": {
"type": "select",
"options": ["tech", "design"],
"label": "Category"
}
}The title, description, and slug fields store a value per locale. The
category field is shared across all locales.
Under the Hood
The _i18n Object Format
Internationalized prop values use a special object format with the _i18n
flag:
{
"text": {
"_i18n": true,
"en": "Hello",
"pl": "Czesc",
"de": "Hallo"
}
}When the page is rendered for a given locale, the system resolves this object
to the correct string. For the pl locale, {{text}} becomes "Czesc". If
a translation is missing, it falls back to the default locale.
Locale List Node JSON
{
"type": "locale-list",
"displayType": "nativeName",
"showFlag": true,
"showCurrent": false,
"showSeparator": true,
"style": {
"base": {
"display": "flex",
"gap": "8px",
"alignItems": "center"
}
},
"itemStyle": {
"base": {
"textDecoration": "none",
"color": "#333",
"fontSize": "14px"
}
},
"activeItemStyle": {
"base": {
"fontWeight": "bold",
"color": "#000"
}
},
"flagStyle": {
"base": {
"width": "20px",
"height": "14px"
}
}
}Build Output
At build time, Meno generates a complete copy of every page for each locale:
dist/
index.html # en (default locale)
about.html
blog/
my-post.html
pl/
index.html # pl
about.html
blog/
my-post.html # or moj-post.html if slug is i18n
de/
index.html # de
about.html
blog/
my-post.htmlThe generated HTML includes the correct lang attribute on the <html> tag,
hreflang link elements for SEO, and all text content resolved to the
appropriate locale.
Page-Level i18n Props
Any component prop can be made locale-aware by using the _i18n object format
in the page JSON:
{
"type": "component",
"component": "HeroBanner",
"props": {
"heading": {
"_i18n": true,
"en": "Welcome to our site",
"pl": "Witamy na naszej stronie",
"de": "Willkommen auf unserer Seite"
},
"buttonLabel": {
"_i18n": true,
"en": "Get Started",
"pl": "Rozpocznij",
"de": "Loslegen"
},
"maxWidth": 1200
}
}Non-i18n props (like maxWidth above) work the same in every locale.
Next Steps
CMS -- Set up collections with i18n fields
Lists -- Display localized content in lists
Filtering and Search -- Filter content on the client side
Deployment -- Build and deploy multi-language sites