Skip to Content

Localization

Finqu themes support multiple languages through JSON files in the locales/ directory.

Storefront translations

Each language needs a locale file:

locales/ en.json fi.json sv.json

Use translation keys in your Liquid templates:

{{ 'general.add_to_cart' | t }}

Keys are nested in the JSON file:

{ "general": { "add_to_cart": "Add to cart" } }

The active language comes from the customer’s locale (request.locale).

Schema translations

Section, block, and setting labels shown in the theme designer can be translated separately from storefront copy using schema locale files:

locales/ en.json en.schema.json fi.json fi.schema.json
FilePurpose
{lang}.jsonStrings customers see on the storefront
{lang}.schema.jsonLabels merchants see in the designer (section names, setting labels, block titles, preset names)

At runtime, schema translations are merged into the corresponding locale for the storefront. You do not need to duplicate schema labels inside fi.json unless the same string is also used on the storefront.

Translation keys (t:)

In schema JSON (sections, blocks, settings_schema.json, and settings_data.json), reference schema locale files with a t: prefix:

{ "type": "checkbox", "id": "showPromotion", "label": "t:blocks.product-title-price.settings.showPromotion.label" }

The path after t: maps to nested keys in {lang}.schema.json using dot notation:

{ "blocks": { "product-title-price": { "settings": { "showPromotion": { "label": "Näytä tarjous" } } } } }

Rules:

  • Use nested JSON objects, not flat keys like "blocks.foo.label": "...".
  • Keys are case-sensitiveproduct-template and PRODUCT-TEMPLATE are different paths.
  • If a key is missing in the active language, Finqu falls back to en.schema.json.
  • On the storefront, t: values are resolved when Liquid reads setting values.
  • In the theme designer, t: values are resolved when schemas and preset data are loaded for the active preview language.

Inline localization objects

You can also localize schema labels inline with language-keyed objects:

{% schema %} { "name": { "en": "Hero banner", "fi": "Hero-banneri" }, "settings": [ { "type": "text", "id": "heading", "label": { "en": "Heading", "fi": "Otsikko" } } ] } {% endschema %}

Both formats work in the designer:

FormatWhere translations liveBest for
t:sections.hero.namelocales/{lang}.schema.jsonLarge themes, many sections/blocks
{ "en": "...", "fi": "..." }Inline in the schema fileSmall schemas, few labels

You can mix both in the same theme.

What is translated in the designer

The theme designer resolves schema translations for the preview language (language picker in the designer navbar, stored in the fnq-designer-locale cookie). When the preview language changes, section, block, and theme labels reload in that language.

UI areaSourceSupported formats
Section sidebar titlesSection schemat: keys, inline objects
Block sidebar titlesBlock schemat: keys, inline objects
Setting labels and info textSection/block/theme schemat: keys, inline objects
Section add dialog preset variantsSection schema presetsLocale maps, arrays, t: keys, inline objects
Block add dialog preset variantsBlock schema presetsLocale maps, arrays, t: keys, inline objects
Theme style presetsconfig/settings_data.jsonpresetsLocale snapshots, t: keys, inline objects
Style editor / style picker presetssettings_schema.json setting presetsLocale maps, t: keys, inline objects
Section and block categoriessettings_schema.jsont: keys, inline objects

Presets

Presets ship default configuration for themes, sections, and blocks. To target different markets, define full preset content per locale — not just translated labels.

Finqu resolves presets for the active language:

  1. Storefront — customer’s locale (request.locale)
  2. Designer — preview language from the navbar (fnq-designer-locale cookie)

Resolution order: active locale → default → first available entry.

Preset settings can include rich text, images, block instances, and layout values. Values inside presets can also use t: keys; those resolve when the preset is loaded for the active language.

Locale-keyed preset maps

The primary format groups preset variants by locale code:

"presets": { "fi": [ { "name": "t:sections.hero.presets.default.name", "settings": { "heading": "Tervetuloa", "body": "<p>Suomenkielinen rich text -sisältö</p>" } } ], "default": [ { "name": "Default hero", "settings": { "heading": "Welcome", "body": "<p>English rich text content</p>" } } ] }

When a Finnish customer views the storefront, Finqu uses the fi preset settings. Other locales fall back to default.

You can also use a flat array when one configuration is enough for all languages:

"presets": [ { "name": "t:sections.two-columns.presets.columns-2.name", "settings": { "left_column_width": 50, "right_column_width": 50 } } ]

Theme-level presets

Whole-store style variants live in config/settings_data.json. Each preset can include locale-specific snapshots:

{ "presets": { "minimal": { "id": "minimal", "name": "t:presets.minimal.name", "default": { "settings": { }, "templates": { }, "sections": [ ] }, "fi": { "settings": { }, "templates": { }, "sections": [ ] } } } }

When a merchant picks or previews a theme preset, Finqu loads the snapshot for the active locale. Preset names still resolve via t: keys or inline { en, fi } objects:

{ "presets": { "minimal": { "name": "Minimalistinen" } } }

Section and block schema presets

Section and block schemas use locale-keyed preset maps to ship market-specific defaults — copy, rich text, images, and layout together:

{% schema %} { "name": "t:sections.footer.name", "presets": { "fi": [ { "settings": { "heading": "Ota yhteyttä", "body": "<p>Suomenkielinen sisältö</p>" } } ], "default": [ { "settings": { "heading": "Contact us", "body": "<p>English content</p>" } } ] } } {% endschema %}

When a merchant adds the section or block, the designer applies the preset for the current preview language.

For multiple layout variants within one locale, each locale entry is an array of preset objects:

"presets": { "default": [ { "name": "Columns 2", "settings": { "left_column_width": 50 } }, { "name": "Columns 3", "settings": { "left_column_width": 33 } } ], "fi": [ { "name": "Sarakkeet 2", "settings": { "left_column_width": 50 } }, { "name": "Sarakkeet 3", "settings": { "left_column_width": 33 } } ] }

Setting-level presets

Theme settings with style-editor or style-picker can wrap style presets by locale:

{ "type": "style-editor", "id": "buttons", "presets": { "fi": { "primary": { "name": "t:settings.buttons.presets.primary.name", "default": { "border_radius": 0 } } }, "default": { "primary": { "name": "Primary", "default": { "border_radius": 4 } } } } }

Or use a single id-keyed map when styles are the same across markets:

{ "type": "style-editor", "id": "buttons", "presets": { "primary": { "name": "t:settings.buttons.presets.primary.name", "default": { } } } }

Example locales/fi.schema.json

{ "sections": { "hero": { "name": "Hero-banneri", "settings": { "heading": { "label": "Otsikko" } } }, "product-template": { "name": "Tuotesivu" } }, "blocks": { "product-page-title": { "name": "Tuotteen otsikko", "settings": { "showVendor": { "label": "Näytä valmistaja" } } } }, "presets": { "minimal": { "name": "Minimalistinen" } } }

Referenced from schema as:

  • "name": "t:sections.hero.name"
  • "label": "t:blocks.product-page-title.settings.showVendor.label"
  • "name": "t:presets.minimal.name"

Best practices

  • Keep storefront copy in {lang}.json and designer labels in {lang}.schema.json or inline schema objects.
  • Use locale-keyed preset maps (fi, default, etc.) to ship market-specific defaults — rich text, images, and layout together.
  • Prefer t: keys inside preset name fields and {lang}.schema.json when labels repeat across locales.
  • Use inline { en, fi } objects for small schemas or few labels.
  • Ship a locale file for every language your theme claims to support.
  • Use the same language codes as your store’s enabled locales (en, fi, sv, etc.).
  • Keep translation key paths stable — use preset slugs and setting ids, not array indexes, in t: paths where possible.
  • Test the designer with the preview language picker, not only the merchant UI language.
  • Test the storefront with the store locale picker or localization form on a deployed store.