Structure Locales by Language
Organize translations under app/locales/{lng} and re-export them in a single resource map.
Why
- Keeps locale resources explicit and discoverable
- Enables type-safe parity checks between languages
- Makes server and client loaders consistent
Pattern
// app/locales/en/translation.ts
export default {
title: "Example",
description: "A React Router + remix-i18next example",
};
// app/locales/en/index.ts
import type { ResourceLanguage } from "i18next";
import translation from "./translation";
export default { translation } satisfies ResourceLanguage;// app/locales/es/translation.ts
export default {
title: "Ejemplo",
description: "Un ejemplo de React Router + remix-i18next",
} satisfies typeof import("~/locales/en/translation").default;
// app/locales/es/index.ts
import type { ResourceLanguage } from "i18next";
import translation from "./translation";
export default { translation } satisfies ResourceLanguage;// app/locales/index.ts
import type { Resource } from "i18next";
import en from "./en";
import es from "./es";
export default { en, es } satisfies Resource;Rules
- Keep
enas the default source of truth for keys - Use
satisfiesto enforce parity between locales - Export a single
resourcesobject for middleware