Skip to content

Add a language

Adding a language takes four small code changes and then the translation itself. Routing, the sitemap, hreflang links, the language switcher and the CMS all pick the new language up by themselves.

  1. Register it in src/i18n/config.ts:

    src/i18n/config.ts
    export const locales = {
    en: { label: 'English', short: 'EN', htmlLang: 'en', dateLocale: 'en-GB', ogLocale: 'en_GB' },
    de: { label: 'Deutsch', short: 'DE', htmlLang: 'de', dateLocale: 'de-DE', ogLocale: 'de_DE' },
    fr: { label: 'Français', short: 'FR', htmlLang: 'fr', dateLocale: 'fr-FR', ogLocale: 'fr_FR' },
    // …
    } as const;
    Key Meaning
    the key The URL prefix: /fr/work
    label The language’s own name, shown in the menu
    short Two letters for the header switcher
    htmlLang The lang attribute and hreflang value
    dateLocale Used by formatDate() and number formatting
    ogLocale The og:locale value for social cards
  2. Create the dictionary. Copy src/i18n/ui/en.ts to src/i18n/ui/fr.ts and change its first lines so it is typed against English:

    src/i18n/ui/fr.ts
    import type { Translation } from './en';
    const fr: Translation = {
    meta: {
    siteTitle: 'Swift, studio de design indépendant',
    // …translate every value, keep every key
    },
    };
    export default fr;

    Remove the export type Translation line from the copy; it belongs in en.ts only.

  3. Load the dictionary in src/i18n/utils.ts:

    src/i18n/utils.ts
    import en, { type Translation } from './ui/en';
    import fr from './ui/fr';
    const dictionaries: Record<Locale, Translation> = { en, de, id, fr };
  4. Check it. Run npm run check. Any key you missed or misspelled in fr.ts is listed with its path. Then npm run dev and open /fr.

  5. Translate content you want in French by adding fr/ folders to the collections. Anything you don’t translate is shown in English. See Translating content.

Translate values, never keys. A few entries need care:

  • Placeholders such as {count}, {date} or {email} must stay exactly as they are; they are replaced when the page is built.
  • services.packages holds prices as numbers. They are formatted in the page language with currency from site.ts, so 18000 needs no change.
  • taxonomy translates disciplines and industries. The keys must match src/content/taxonomy.ts.
  • contact.budgets is shown as written; use local amounts if you like.

The default language is the one without a URL prefix, and the one whose content sits at the root of each collection folder. To make German the default:

  1. Set defaultLocale to 'de' in src/i18n/config.ts.
  2. In each collection, move the English files into a new en/ folder and move the German files from de/ to the root.
  3. Update relative image paths: files that moved one level deeper need one more ../, and files that moved up need one fewer.

The RSS feed follows the default language.

SwiftAgency is made byLessCodexLicence