Type-safe internationalization (i18n) for Next.js
- 100% Type-safe: Locales in TS or JSON, type-safe
t()
, type-safe params - Small: 1.2 KB gzipped (1.7 KB uncompressed), no dependencies
- Simple: No webpack configuration, no CLI, just pure TypeScript
- SSR: Load only the required locale, SSRed
pnpm install next-international
-
Make sure that you've followed Next.js Internationalized Routing, and that
strict
is set totrue
in yourtsconfig.json
-
Create
locales/index.ts
with your locales:
import { createI18n } from 'next-international'
import type Locale from './en'
export const {
useI18n,
I18nProvider,
getLocaleStaticProps,
} = createI18n<typeof Locale>({
en: () => import('./en'),
fr: () => import('./fr'),
});
Each locale file should export a default object (don't forget as const
):
// locales/en.ts
export default {
'hello': 'Hello',
'welcome': 'Hello {name}!',
} as const
- Add
getLocaleStaticProps
to your pages if you want SSR, or wrap your existinggetStaticProps
:
// pages/index.tsx
export const getStaticProps = getLocaleStaticProps()
// or with an existing `getStaticProps` function:
export const getStaticProps = getLocaleStaticProps((ctx) => {
// your existing code
return {
...
}
})
- Use
useI18n
:
import { useI18n } from '../locales'
function App() {
const t = useI18n()
return (
<div>
<p>{t('hello')}</p>
<p>{t('welcome', { name: 'John' })}</p>
</div>
)
}
Export useChangeLocale
from createI18n
:
export const {
useChangeLocale,
...
} = createI18n({
...
});
Then use this as a hook:
import { useChangeLocale } from '../locales'
function App() {
const changeLocale = useChangeLocale()
return (
<button onClick={() => changeLocale('en')}>English</button>
<button onClick={() => changeLocale('fr')}>French</button>
)
}
Currently, this breaks the parameters type-safety, so we recommend using the TS syntax. See this issue: microsoft/TypeScript#32063.
import { createI18n } from 'next-international'
import type Locale from './en.json'
export const {
useI18n,
I18nProvider,
getLocaleStaticProps,
} = createI18n<typeof Locale>({
en: () => import('./en.json'),
fr: () => import('./fr.json'),
});