Skip to content

Internationalisation

Wouter Meetsma edited this page Jun 3, 2026 · 4 revisions

Internationalisation

Rubric Maker uses i18next and react-i18next for UI translations. The active language is auto-detected from the browser and can be changed in the application's Settings page.


Supported languages

Language File Status
English src/locales/en.json Complete
Dutch src/locales/nl.json Complete
French src/locales/fr.json Complete
German src/locales/de.json Complete
Spanish src/locales/es.json Complete

Adding a new language

  1. Copy the English locale file:

    cp src/locales/en.json src/locales/<lang-code>.json
    # e.g. cp src/locales/en.json src/locales/de.json
  2. Translate the values in the new file. Keys must stay identical to en.json; only the values change.

  3. Register the locale in src/i18n.ts. Import the new JSON file and add it to the resources object:

    import de from './locales/de.json';
    
    i18next.init({
      resources: {
        en: { translation: en },
        nl: { translation: nl },
        de: { translation: de },   // add this line
      },
      // ...
    });
  4. Add the language to the Settings UI so users can select it. Look for the language selector in src/pages/SettingsPage.tsx.

  5. Test by switching the language in Settings and verifying all pages render correctly without missing keys.


Using translations in components

import { useTranslation } from 'react-i18next';

function MyComponent() {
  const { t } = useTranslation();

  return <h1>{t('myComponent.title')}</h1>;
}

Add the corresponding key to all locale files — en.json, nl.json, fr.json, de.json, and es.json — at the same time as writing the component, so keys never go missing.


Nested keys

The locale files use nested JSON objects to group related strings:

{
  "rubricBuilder": {
    "title": "Rubric Builder",
    "addCriterion": "Add criterion",
    "scoringMode": {
      "totalPoints": "Total Points",
      "weighted": "Weighted Score"
    }
  }
}

Access nested keys with dot notation: t('rubricBuilder.scoringMode.totalPoints').


Missing keys

If a translation key is missing in a locale file, i18next falls back to the en locale. Missing keys in the en locale are returned as the key string itself. Check the browser console for i18next::translator: missingKey warnings during development.


Date and number formatting

i18next does not handle date/number formatting directly. Use the browser's built-in Intl API:

const formatted = new Intl.NumberFormat(i18n.language).format(score);
const date = new Intl.DateTimeFormat(i18n.language).format(new Date());

Clone this wiki locally