i18n - config
Locale files for a Psychic app live in src/conf/locales/. By default, an English translation file is set up for you, but any other languages you wish to support can be provided as well.
// src/conf/locales/en.ts
export default {
labels: {
nutrition: {
calories: 'calories',
},
},
}
// src/conf/locales/es.ts
export default {
labels: {
nutrition: {
calories: 'calorias',
},
},
}
Within each translation file, you will want to make sure to provide the same payload shape, so that translations can be correctly resolved in all locales.
Map the locale keys to their files in src/conf/locales/index.ts:
// src/conf/locales/index.ts
import en from './en.js'
import es from './es.js'
export default {
en,
es,
}
Tie supported locales to the database enum
Resist the urge to hand-write a union type for your supported locales (type SupportedLocales = 'en' | 'es') alongside this file. Instead, back your locale column with a database enum in a migration, and let the generated LocalesEnum / LocalesEnumValues types (in @src/types/db.js) be the single source of truth. That way the list of supported locales is defined in exactly one place — the migration — and flows through the type system from there, instead of drifting out of sync with a manually maintained type.
Expose the supported locales for runtime validation (for example, when checking an incoming Accept-Language header) from the same file that builds your i18n function:
// src/utils/i18n.ts
import locales from '@conf/locales/index.js'
import { I18nProvider } from '@rvoh/psychic/system'
import { LocalesEnumValues } from '@src/types/db.js'
export function supportedLocales() {
return LocalesEnumValues
}
export default I18nProvider.provide(locales, 'en')
See usage for how I18nProvider.provide uses these locale files, and for using supportedLocales() to validate the locale a request asks for.
Regional locale resolution
While configurations demonstrate base locales like en and es, Psychic also supports more specific locale resolutions, such as en-US vs en-UK. To create locales which can resolve to these specific regions, you can simply provide direct overrides for each region, like so:
// src/conf/locales/index.ts
import en from './en.js'
import enUk from './en-UK.js'
export default {
en,
['en-UK']: enUk,
}
With this in place, Psychic will carefully resolve the en-UK locale to the provided override. Any other en-* locale value is matched by its language prefix and resolved to the base en file — for example, a request with locale en-AU resolves to en, not en-UK.