My translations on InertiaJS/React with i18next rerender when page fully loads, which ruins both SEO and animations. when page is initializing, first it loads the en language (even when I change the fallbackLng to something else than en, it will load en first), then when the page fully loads, it loads the specified language on the cache or storage (I used cookie). The reason might be the content on translation calls changes when the page fully loads. also I used translations for the page titles and they are not eager loaded too. My translations are on /lang/*.json.
These are my configurations:
resources/js/lib/i18n.ts
import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';
import en from '../../../lang/en.json';
import fa from '../../../lang/fa.json';
i18n.use(LanguageDetector)
.use(initReactI18next)
.init({
debug: true,
fallbackLng: 'en',
preload: ['en', 'fa'],
defaultNS: 'translation',
ns: ['translation'],
resources: {
en: {
translation: en,
},
fa: {
translation: fa,
},
},
interpolation: {
escapeValue: false,
},
detection: {
order: ['cookie', 'localStorage', 'navigator'],
caches: ['cookie'],
cookieMinutes: 43200,
},
react: {
useSuspense: false
},
});
export default i18n;
resources/js/app.ts
import '../css/app.css';
import { createInertiaApp } from '@inertiajs/react';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { createRoot } from 'react-dom/client';
import './lib/i18n';
import { t } from 'i18next';
createInertiaApp({
title: (title) => `${title} - ${t('app.name') || import.meta.env.VITE_APP_NAME || 'Laravel'}`,
resolve: (name) => resolvePageComponent(`./pages/${name}.tsx`, import.meta.glob('./pages/**/*.tsx')),
setup({ el, App, props }) {
const root = createRoot(el);
root.render(
<App {...props} />
);
},
progress: {
color: '#0000ff',
},
});
resources/js/ssr.ts
import { createInertiaApp } from '@inertiajs/react';
import createServer from '@inertiajs/react/server';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import ReactDOMServer from 'react-dom/server';
import { type RouteName, route } from 'ziggy-js';
import i18n from './lib/i18n';
import { t } from 'i18next';
createServer((page) =>
createInertiaApp({
page,
render: ReactDOMServer.renderToString,
title: (title) => `${title} - ${ t('app.name') || import.meta.env.VITE_APP_NAME || 'Laravel'}`,
resolve: (name) => resolvePageComponent(`./pages/${name}.tsx`, import.meta.glob('./pages/**/*.tsx')),
setup: ({ App, props }) => {
/* eslint-disable */
// @ts-expect-error
global.i18n = i18n;
// @ts-expect-error
global.route<RouteName> = (name, params, absolute) =>
route(name, params as any, absolute, {
// @ts-expect-error
...page.props.ziggy,
// @ts-expect-error
location: new URL(page.props.ziggy.location),
});
/* eslint-enable */
return <App {...props} />;
},
}),
);
how I build and run Inertia SSR:
npm run build:ssr // this runs: vite build && vite build --ssr
php artisan inertia:start
The browser's Output:
i18next: languageChanged en // or whatever locale changed to
i18next initialized: Object // related to configuration on i18n.ts
I want the translations be eager loaded and not rerender on page load (content don't change).
enlanguage loads and get rendered then after the full page load the translations re-render (or if language is something likefa, first it loadsentranslations and thenfaafter page load)