Refactor i18n client and server initialization
The refactor includes the removal of clientInstance checks as they are unnecessary. Also, i18n-provider.tsx has been updated to use react-query instead of local state for client initialization. Lastly, error handling has been added to the server initialization process and the @tanstack/react-query package has been added to the project dependencies.
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
"@kit/shared": "workspace:^",
|
"@kit/shared": "workspace:^",
|
||||||
"@kit/tailwind-config": "workspace:*",
|
"@kit/tailwind-config": "workspace:*",
|
||||||
"@kit/tsconfig": "workspace:*",
|
"@kit/tsconfig": "workspace:*",
|
||||||
|
"@tanstack/react-query": "5.29.2",
|
||||||
"i18next": "^23.11.2",
|
"i18next": "^23.11.2",
|
||||||
"i18next-browser-languagedetector": "7.2.1",
|
"i18next-browser-languagedetector": "7.2.1",
|
||||||
"i18next-resources-to-backend": "^1.2.1",
|
"i18next-resources-to-backend": "^1.2.1",
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import type { InitOptions, i18n } from 'i18next';
|
import { useSuspenseQuery } from '@tanstack/react-query';
|
||||||
|
import type { InitOptions } from 'i18next';
|
||||||
let client: i18n;
|
|
||||||
|
|
||||||
type Resolver = (
|
type Resolver = (
|
||||||
lang: string,
|
lang: string,
|
||||||
@@ -17,23 +16,32 @@ export function I18nProvider({
|
|||||||
settings: InitOptions;
|
settings: InitOptions;
|
||||||
resolver: Resolver;
|
resolver: Resolver;
|
||||||
}>) {
|
}>) {
|
||||||
// If the client is not initialized or
|
useI18nClient(settings, resolver);
|
||||||
// the language has changed, reinitialize the client
|
|
||||||
if (!client || client.language !== settings.lng) {
|
|
||||||
throw withI18nClient(settings, resolver);
|
|
||||||
}
|
|
||||||
|
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function withI18nClient(settings: InitOptions, resolver: Resolver) {
|
/**
|
||||||
if (typeof window !== 'undefined') {
|
* @name useI18nClient
|
||||||
const { initializeI18nClient } = await import('./i18n.client');
|
* @description A hook that initializes the i18n client.
|
||||||
|
* @param settings
|
||||||
|
* @param resolver
|
||||||
|
*/
|
||||||
|
function useI18nClient(settings: InitOptions, resolver: Resolver) {
|
||||||
|
return useSuspenseQuery({
|
||||||
|
queryKey: ['i18n', settings.lng],
|
||||||
|
queryFn: async () => {
|
||||||
|
const isBrowser = typeof window !== 'undefined';
|
||||||
|
|
||||||
client = await initializeI18nClient(settings, resolver);
|
if (isBrowser) {
|
||||||
} else {
|
const { initializeI18nClient } = await import('./i18n.client');
|
||||||
const { initializeServerI18n } = await import('./i18n.server');
|
|
||||||
|
|
||||||
client = await initializeServerI18n(settings, resolver);
|
return await initializeI18nClient(settings, resolver);
|
||||||
}
|
} else {
|
||||||
|
const { initializeServerI18n } = await import('./i18n.server');
|
||||||
|
|
||||||
|
return await initializeServerI18n(settings, resolver);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import LanguageDetector from 'i18next-browser-languagedetector';
|
|||||||
import resourcesToBackend from 'i18next-resources-to-backend';
|
import resourcesToBackend from 'i18next-resources-to-backend';
|
||||||
import { initReactI18next } from 'react-i18next';
|
import { initReactI18next } from 'react-i18next';
|
||||||
|
|
||||||
let clientInstance: i18n | null = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the i18n instance on the client.
|
* Initialize the i18n instance on the client.
|
||||||
* @param settings - the i18n settings
|
* @param settings - the i18n settings
|
||||||
@@ -14,10 +12,6 @@ export async function initializeI18nClient(
|
|||||||
settings: InitOptions,
|
settings: InitOptions,
|
||||||
resolver: (lang: string, namespace: string) => Promise<object>,
|
resolver: (lang: string, namespace: string) => Promise<object>,
|
||||||
): Promise<i18n> {
|
): Promise<i18n> {
|
||||||
if (clientInstance) {
|
|
||||||
return Promise.resolve(clientInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
await i18next
|
await i18next
|
||||||
.use(
|
.use(
|
||||||
resourcesToBackend(async (language, namespace, callback) => {
|
resourcesToBackend(async (language, namespace, callback) => {
|
||||||
@@ -47,7 +41,5 @@ export async function initializeI18nClient(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
clientInstance = i18next;
|
return i18next;
|
||||||
|
|
||||||
return clientInstance;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,6 @@ export async function initializeServerI18n(
|
|||||||
) {
|
) {
|
||||||
const i18nInstance = createInstance();
|
const i18nInstance = createInstance();
|
||||||
|
|
||||||
if (i18nInstance.isInitialized) {
|
|
||||||
return i18nInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
await i18nInstance
|
await i18nInstance
|
||||||
.use(
|
.use(
|
||||||
resourcesToBackend(async (language, namespace, callback) => {
|
resourcesToBackend(async (language, namespace, callback) => {
|
||||||
@@ -36,11 +32,20 @@ export async function initializeServerI18n(
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.use(initReactI18next)
|
.use(initReactI18next)
|
||||||
.init(settings);
|
.init(settings, (error) => {
|
||||||
|
if (error) {
|
||||||
|
console.error('Error initializing i18n server', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return i18nInstance;
|
return i18nInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the accept-language header value and return the languages that are included in the accepted languages.
|
||||||
|
* @param languageHeaderValue
|
||||||
|
* @param acceptedLanguages
|
||||||
|
*/
|
||||||
export function parseAcceptLanguageHeader(
|
export function parseAcceptLanguageHeader(
|
||||||
languageHeaderValue: string | null | undefined,
|
languageHeaderValue: string | null | undefined,
|
||||||
acceptedLanguages: string[],
|
acceptedLanguages: string[],
|
||||||
|
|||||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -989,6 +989,9 @@ importers:
|
|||||||
'@kit/tsconfig':
|
'@kit/tsconfig':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../tooling/typescript
|
version: link:../../tooling/typescript
|
||||||
|
'@tanstack/react-query':
|
||||||
|
specifier: 5.29.2
|
||||||
|
version: 5.29.2(react@18.2.0)
|
||||||
i18next:
|
i18next:
|
||||||
specifier: ^23.11.2
|
specifier: ^23.11.2
|
||||||
version: 23.11.2
|
version: 23.11.2
|
||||||
|
|||||||
Reference in New Issue
Block a user