-
We've added localization to our Remix app following this example: https://sergiodxa.com/tutorials/add-i18n-to-a-remix-vite-app This works, but we would like the language detector to also pick up on the locale as a prefix in the url: http://localhost:3000 <- default language If I'm checking the Typescript type |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 8 replies
-
Create an optional route segment (https://remix.run/docs/en/main/file-conventions/routes#optional-segments) and read yourself from the params object in the root loader. |
Beta Was this translation helpful? Give feedback.
-
@sergiodxa When intercepting params from optional segments in the root.tsx loader, the default language flashes before the correct language (obtained from the route param) is displayed. How can this be avoided? Sample code below: // root.tsx
import type { LinksFunction, LoaderFunctionArgs } from '@remix-run/node';
import { json } from '@remix-run/node';
import {
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
useLoaderData,
} from '@remix-run/react';
import { useTranslation } from 'react-i18next';
import { useChangeLanguage } from 'remix-i18next/react';
import i18next from '~/i18next.server';
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
// let locale = await i18next.getLocale(request);
const locale = params.lang
return json({
locale,
});
};
// https://github.com/sergiodxa/remix-i18next?tab=readme-ov-file#usage
export let handle = {
i18n: 'translation',
};
export default function App() {
const { locale } = useLoaderData<typeof loader>();
let { i18n } = useTranslation();
console.log({ locale });
useChangeLanguage(locale);
return (
<html lang={locale} dir={i18n.dir()}>
<head>
<Meta />
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" href="https://fav.farm/🤘" />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}
|
Beta Was this translation helpful? Give feedback.
-
I did this on my app because the loader's class CustomDetector extends LanguageDetector {
private urlSegmentPosition = 1;
constructor(private options: LanguageDetectorOption) {
super(options);
}
private fromUrlSegment(request: Request) {
const url = new URL(request.url);
const segment = url.pathname.split('/');
return segment;
}
public async detect(request: Request): Promise<string> {
const url = new URL(request.url);
const segments = url.pathname.split('/');
const maybeLocale = segments[this.urlSegmentPosition];
if (this.options.supportedLanguages.includes(maybeLocale)) {
return maybeLocale;
}
return this.options.fallbackLanguage;
}
}
// @ts-ignore
class CustomRemixI18Next extends RemixI18Next {
private detector: CustomDetector;
// eslint-disable-next-line no-useless-constructor
constructor(private options: RemixI18NextOption) {
super(options);
this.detector = new CustomDetector(this.options.detection);
}
} The If useful I can do a proper PR to add this method @sergiodxa . |
Beta Was this translation helpful? Give feedback.
Create an optional route segment (https://remix.run/docs/en/main/file-conventions/routes#optional-segments) and read yourself from the params object in the root loader.