Translations
Translation settings enable multi-language support for editor labels and default values in your sections. All labels, placeholders, descriptions, and default text values used in content and design editors are resolved from translation keys defined here. These strings are visible to merchants in the Instant Site Editor and can be customized by them.
Overview
Translations are defined in a single translations.ts file inside the settings/ directory:
sections/<section-name>/settings/
└── translations.tsThe file exports a TranslationSettings object — a record keyed by language code, where each language maps translation keys to their localized strings.
Type Definition
TranslationSettings = Record<LanguageCode, Record<LabelKey, string>>Where:
LanguageCode— A valid language code matching the pattern:xxorxx_XX(e.g.,en,fr,nl,en_US,zh_Hans,pt_BR)LabelKey— A string starting with$followed by at least one character (e.g.,$label.content.title)
Validation Rules
| Rule | Constraint | Examples |
|---|---|---|
| Language code format | ^[a-z]{2}(_([a-z]{2}|[A-Z]{2}|[0-9]{3}))?$ | en, fr, nl, en_US, en_GB, zh_Hans |
| Label key format | Must start with $ | $label.content.title, $label.defaults.cta |
Factory
Use the translation.init() factory from @lightspeed/crane-api:
import { translation } from '@lightspeed/crane-api';Example
settings/translations.ts
import { translation } from '@lightspeed/crane-api';
export default translation.init({
en: {
'$label.content.title': 'Title',
'$label.content.title_placeholder': 'Enter a title...',
'$label.content.description': 'Description',
'$label.content.description_placeholder': 'Enter a description...',
'$label.content.hero_image': 'Hero Image',
'$label.content.cta_button': 'Call to Action',
'$label.defaults.title': 'Welcome to Our Store',
'$label.defaults.description': 'Discover our latest products',
'$label.defaults.cta': 'Shop Now',
'$label.design.title_style': 'Title Style',
'$label.design.background': 'Background',
},
fr: {
'$label.content.title': 'Titre',
'$label.content.title_placeholder': 'Entrez un titre...',
'$label.content.description': 'Description',
'$label.content.description_placeholder': 'Entrez une description...',
'$label.content.hero_image': 'Image principale',
'$label.content.cta_button': 'Appel à l\'action',
'$label.defaults.title': 'Bienvenue dans notre boutique',
'$label.defaults.description': 'Découvrez nos derniers produits',
'$label.defaults.cta': 'Acheter maintenant',
'$label.design.title_style': 'Style du titre',
'$label.design.background': 'Arrière-plan',
},
});Showcase Translations
Showcases can also have their own translations in a separate translations.ts file inside the showcases/ directory:
sections/<section-name>/showcases/
├── 1.ts
├── 2.ts
└── translations.tsThese translations provide localized blockName values and other showcase-specific text. See Showcases for details.
Shared Translations
Templates can define shared translations at the template level that apply across all sections. These are configured in the template's configuration and follow the same key/value format.
Shared translations are useful for common text that appears in multiple sections (e.g., "Read More", "Add to Cart").
Usage in Components
Use the useTranslation composable to access translations in your Vue components:
<script setup lang="ts">
import { useTranslation } from '@lightspeed/crane-api';
const { t } = useTranslation();
</script>
<template>
<h1>{{ t('$label.shared.title') }}</h1>
</template>ℹ️ Static vs. Merchant-Editable Text
The useTranslation composable reads from shared/translation.ts and is for static text only — developer-defined text that cannot be changed by merchants. This is different from settings/translations.ts, which provides merchant-visible labels and defaults that appear in the Instant Site Editor. For merchant-editable content, use content composables like useInputboxElementContent and useTextareaElementContent.