This site uses Lingui with Next.js for internationalization. Translation catalogs are .po files in src/locales/.
User-facing strings are wrapped with the t` ` tagged template from useLingui():
import { useLingui } from '@lingui/react/macro'
const MyComponent = () => {
const { t } = useLingui()
return <Text>{t`Hello world`}</Text>
}Strings with dynamic values use interpolation inside the tagged template:
{
t`${count} items found`
}Avoid concatenating translated fragments — use a single tagged template so translators see the full sentence:
// Bad: translators get disconnected fragments
;`${value} ` + t`hours`
// Good: translators see the full string
t`${value} hours`Any page that uses translated strings (directly or through shared components like Header/Footer) needs to load the translation catalog in getStaticProps:
import { loadCatalog } from '../i18n'
export const getStaticProps = async (ctx) => {
const translation = await loadCatalog(ctx.locale)
return {
props: {
translation,
},
}
}Without this, translations will not load when users visit the page directly. Blog posts are an exception — they are not translated and do not need this.
- Add the locale code to
src/config/i18n.mjs - Run
npx lingui extractto create the new.pofile - The new locale will be available for translation on Crowdin after merging