@xtraa/tradesafe-i18n
v1.2.34
Published
A proprietary internal i18n package for team use only.
Readme
@xtraa/tradesafe-i18n
Requirements
accept-language is not a requirement to use @xtraa/tradesafe-i18n, but recommend to install to setup server side middleware for Next.js 14+ app to handle each language.
yarn add @xtraa/tradesafe-i18n accept-languageSetup root layout
For Next.js 14+ app, setup as below:
app/[lang]/layout.tsx. All pages and components should come under app/[lang] path.
import { LANGS, getAsyncI18nTranslation, Lang, TranslationProvider } from '@xtraa/tradesafe-i18n';
import { dir } from 'i18next';
// to preload static pages with each lang path
export async function generateStaticParams() {
return LANGS.map((lang) => ({ lang }));
}
export default async function RootLayout({
children,
params: { lang },
}: Readonly<{
children: React.ReactNode;
params: { lang: Lang };
}>) {
// to preload language data on server side for initial loading support with texts ready
const { i18n } = await getAsyncI18nTranslation(lang);
return (
<html lang={lang} dir={dir(lang)}>
</html>
<body>
<TranslationProvider lang={lang} resource={i18n.store.data}>
{children}
</TranslationProvider>
</body>
);
}Setup middleware
Create middleware.ts at front-end root path.
import { NextRequest, NextResponse } from 'next/server'
import acceptLanguage from 'accept-language'
import { LANGS } from '@xtraa/tradesafe-i18n';
const cookieName = 'lang';
acceptLanguage.languages([...LANGS]);
export const config = {
// matcher: '/:lng*'
matcher: ['/((?!api|_next/static|_next/image|assets|favicon.ico|sw.js|site.webmanifest).*)'],
}
export function middleware(req: NextRequest) {
let lng
const cookieValue = req.cookies.get(cookieName)?.value;
if (cookieValue) lng = acceptLanguage.get(cookieValue);
if (!lng) lng = acceptLanguage.get(req.headers.get('Accept-Language'))
if (!lng) lng = LANGS[0];
// Redirect if lng in path is not supported
if (
!LANGS.some(loc => req.nextUrl.pathname.startsWith(`/${loc}`)) &&
!req.nextUrl.pathname.startsWith('/_next')
) {
return NextResponse.redirect(new URL(`/${lng}${req.nextUrl.pathname}`, req.url))
}
const headerReferer = req.headers.get('referer');
if (headerReferer) {
const refererUrl = new URL(headerReferer)
const lngInReferer = LANGS.find((l) => refererUrl.pathname.startsWith(`/${l}`))
const response = NextResponse.next()
if (lngInReferer) response.cookies.set(cookieName, lngInReferer)
return response
}
return NextResponse.next();
}Use component or hook
Translation keys should be type-inferred.
import { Trans, useTranslation } from '@xtraa/tradesafe-i18n';
const AnyComponent = () => {
const { t } = useTranslation();
return (
<div>
{t('gen_welcome_aboard')}
<Trans t="gen_welcome_aboard" />
</div>
);
}
export default AnyComponent;