From db719139d8cf03ff2c000eba1768bc879f5dadba Mon Sep 17 00:00:00 2001 From: Quentin Date: Wed, 20 Dec 2023 21:03:41 +0100 Subject: [PATCH 1/6] fix: execute import function in `I18nProviderWrapper` instead of `I18nProvider` --- examples/next-app/locales/client.ts | 10 ++----- .../client/create-i18n-provider-client.tsx | 30 +++++++++---------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/examples/next-app/locales/client.ts b/examples/next-app/locales/client.ts index 45bbb32..33b7f62 100644 --- a/examples/next-app/locales/client.ts +++ b/examples/next-app/locales/client.ts @@ -4,14 +4,8 @@ import { createI18nClient } from 'next-international/client'; export const { useI18n, useScopedI18n, I18nProviderClient, useChangeLocale, defineLocale, useCurrentLocale } = createI18nClient( { - en: async () => { - await new Promise(resolve => setTimeout(resolve, 100)); - return import('./en'); - }, - fr: async () => { - await new Promise(resolve => setTimeout(resolve, 100)); - return import('./fr'); - }, + en: () => import('./en'), + fr: () => import('./fr'), }, { // Uncomment to set base path diff --git a/packages/next-international/src/app/client/create-i18n-provider-client.tsx b/packages/next-international/src/app/client/create-i18n-provider-client.tsx index 462fbed..bc6478c 100644 --- a/packages/next-international/src/app/client/create-i18n-provider-client.tsx +++ b/packages/next-international/src/app/client/create-i18n-provider-client.tsx @@ -12,6 +12,8 @@ type I18nProviderWrapperProps = { locale: string; fallback?: ReactNode; children: ReactNode; + + importLocale: Promise>; }; export const localesCache = new Map>(); @@ -21,21 +23,9 @@ export function createI18nProviderClient( locales: ImportedLocales, fallbackLocale?: Record, ) { - function I18nProvider({ locale, children }: I18nProviderProps) { - let clientLocale: any = localesCache.get(locale); - - if (!clientLocale) { - const newLocale = locales[locale as keyof typeof locales]; - - if (!newLocale) { - error(`The locale '${locale}' is not supported. Defined locales are: [${Object.keys(locales).join(', ')}].`); - notFound(); - } - - clientLocale = use(newLocale()).default; - localesCache.set(locale, clientLocale); - } - + function I18nProvider({ locale, importLocale, children }: I18nProviderProps) { + const clientLocale = use(importLocale).default as Record; + localesCache.set(locale, clientLocale); const value = useMemo( () => ({ localeContent: flattenLocale(clientLocale), @@ -49,9 +39,17 @@ export function createI18nProviderClient( } return function I18nProviderWrapper({ locale, fallback, children }: I18nProviderWrapperProps) { + const importFnLocale = locales[locale as keyof typeof locales]; + if (!importFnLocale) { + error(`The locale '${locale}' is not supported. Defined locales are: [${Object.keys(locales).join(', ')}].`); + notFound(); + } + return ( - {children} + + {children} + ); }; From e397f36e048308a9f926f5c8edd6da986d362c78 Mon Sep 17 00:00:00 2001 From: Quentin Date: Thu, 21 Dec 2023 09:39:52 +0100 Subject: [PATCH 2/6] ref: remove unused `localesCache` variable --- .../src/app/client/create-i18n-provider-client.tsx | 3 --- .../src/app/client/create-use-change-locale.ts | 5 +---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/next-international/src/app/client/create-i18n-provider-client.tsx b/packages/next-international/src/app/client/create-i18n-provider-client.tsx index bc6478c..9a92d40 100644 --- a/packages/next-international/src/app/client/create-i18n-provider-client.tsx +++ b/packages/next-international/src/app/client/create-i18n-provider-client.tsx @@ -16,8 +16,6 @@ type I18nProviderWrapperProps = { importLocale: Promise>; }; -export const localesCache = new Map>(); - export function createI18nProviderClient( I18nClientContext: Context | null>, locales: ImportedLocales, @@ -25,7 +23,6 @@ export function createI18nProviderClient( ) { function I18nProvider({ locale, importLocale, children }: I18nProviderProps) { const clientLocale = use(importLocale).default as Record; - localesCache.set(locale, clientLocale); const value = useMemo( () => ({ localeContent: flattenLocale(clientLocale), diff --git a/packages/next-international/src/app/client/create-use-change-locale.ts b/packages/next-international/src/app/client/create-use-change-locale.ts index 1986ccd..fd12da8 100644 --- a/packages/next-international/src/app/client/create-use-change-locale.ts +++ b/packages/next-international/src/app/client/create-use-change-locale.ts @@ -1,7 +1,6 @@ import { useRouter, usePathname, useSearchParams } from 'next/navigation'; import type { I18nChangeLocaleConfig, I18nClientConfig } from '../../types'; import type { ImportedLocales } from 'international-types'; -import { localesCache } from './create-i18n-provider-client'; export function createUseChangeLocale( useCurrentLocale: () => LocalesKeys, @@ -30,9 +29,7 @@ export function createUseChangeLocale( } return function changeLocale(newLocale: LocalesKeys) { - locales[newLocale as keyof typeof locales]().then(module => { - localesCache.set(newLocale as string, module.default); - + locales[newLocale as keyof typeof locales]().then(() => { push(`/${newLocale}${pathWithoutLocale}${finalSearchParams}`); refresh(); }); From 5f886c363fe602adaf3cdc982141419a99f7f7fe Mon Sep 17 00:00:00 2001 From: Quentin Date: Thu, 21 Dec 2023 18:19:52 +0100 Subject: [PATCH 3/6] ref: re-add artificial delay --- examples/next-app/locales/client.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/next-app/locales/client.ts b/examples/next-app/locales/client.ts index 33b7f62..45bbb32 100644 --- a/examples/next-app/locales/client.ts +++ b/examples/next-app/locales/client.ts @@ -4,8 +4,14 @@ import { createI18nClient } from 'next-international/client'; export const { useI18n, useScopedI18n, I18nProviderClient, useChangeLocale, defineLocale, useCurrentLocale } = createI18nClient( { - en: () => import('./en'), - fr: () => import('./fr'), + en: async () => { + await new Promise(resolve => setTimeout(resolve, 100)); + return import('./en'); + }, + fr: async () => { + await new Promise(resolve => setTimeout(resolve, 100)); + return import('./fr'); + }, }, { // Uncomment to set base path From 9ef269ab33b48b4b0b265aab784e1221be8a42ca Mon Sep 17 00:00:00 2001 From: Quentin Date: Sat, 23 Dec 2023 17:44:03 +0100 Subject: [PATCH 4/6] feat: reimplement `localesCache` --- .../src/app/client/create-i18n-provider-client.tsx | 9 +++++++-- .../src/app/client/create-use-change-locale.ts | 8 +++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/next-international/src/app/client/create-i18n-provider-client.tsx b/packages/next-international/src/app/client/create-i18n-provider-client.tsx index 9a92d40..1a97543 100644 --- a/packages/next-international/src/app/client/create-i18n-provider-client.tsx +++ b/packages/next-international/src/app/client/create-i18n-provider-client.tsx @@ -1,5 +1,5 @@ -import { notFound } from 'next/navigation'; import type { BaseLocale, ImportedLocales } from 'international-types'; +import { notFound } from 'next/navigation'; import type { Context, ReactNode } from 'react'; import React, { Suspense, use, useMemo } from 'react'; import { flattenLocale } from '../../common/flatten-locale'; @@ -16,13 +16,18 @@ type I18nProviderWrapperProps = { importLocale: Promise>; }; +export const localesCache = new Map>(); + export function createI18nProviderClient( I18nClientContext: Context | null>, locales: ImportedLocales, fallbackLocale?: Record, ) { function I18nProvider({ locale, importLocale, children }: I18nProviderProps) { - const clientLocale = use(importLocale).default as Record; + const clientLocale = (localesCache.get(locale) ?? use(importLocale).default) as Record; + if (!localesCache.has(locale)) { + localesCache.set(locale, clientLocale); + } const value = useMemo( () => ({ localeContent: flattenLocale(clientLocale), diff --git a/packages/next-international/src/app/client/create-use-change-locale.ts b/packages/next-international/src/app/client/create-use-change-locale.ts index fd12da8..13be991 100644 --- a/packages/next-international/src/app/client/create-use-change-locale.ts +++ b/packages/next-international/src/app/client/create-use-change-locale.ts @@ -1,6 +1,7 @@ -import { useRouter, usePathname, useSearchParams } from 'next/navigation'; -import type { I18nChangeLocaleConfig, I18nClientConfig } from '../../types'; import type { ImportedLocales } from 'international-types'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import type { I18nChangeLocaleConfig, I18nClientConfig } from '../../types'; +import { localesCache } from './create-i18n-provider-client'; export function createUseChangeLocale( useCurrentLocale: () => LocalesKeys, @@ -29,7 +30,8 @@ export function createUseChangeLocale( } return function changeLocale(newLocale: LocalesKeys) { - locales[newLocale as keyof typeof locales]().then(() => { + locales[newLocale as keyof typeof locales]().then(module => { + localesCache.set(newLocale as string, module.default); push(`/${newLocale}${pathWithoutLocale}${finalSearchParams}`); refresh(); }); From 7dd5426609bff08f0077b7feb6c9aed6d3f821aa Mon Sep 17 00:00:00 2001 From: Quentin Date: Sat, 23 Dec 2023 17:48:18 +0100 Subject: [PATCH 5/6] fix: check if newLocale is supported in `changeLocale` --- .../src/app/client/create-use-change-locale.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/next-international/src/app/client/create-use-change-locale.ts b/packages/next-international/src/app/client/create-use-change-locale.ts index 13be991..1ee0256 100644 --- a/packages/next-international/src/app/client/create-use-change-locale.ts +++ b/packages/next-international/src/app/client/create-use-change-locale.ts @@ -1,3 +1,4 @@ +import { warn } from '../../helpers/log'; import type { ImportedLocales } from 'international-types'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; import type { I18nChangeLocaleConfig, I18nClientConfig } from '../../types'; @@ -30,7 +31,13 @@ export function createUseChangeLocale( } return function changeLocale(newLocale: LocalesKeys) { - locales[newLocale as keyof typeof locales]().then(module => { + const importFnLocale = locales[newLocale as keyof typeof locales]; + if (!importFnLocale) { + warn(`The locale '${newLocale}' is not supported.`); + return; + } + + importFnLocale().then(module => { localesCache.set(newLocale as string, module.default); push(`/${newLocale}${pathWithoutLocale}${finalSearchParams}`); refresh(); From fdd3efeb5780aa0bfef172e0621d89ffc1eb7655 Mon Sep 17 00:00:00 2001 From: Tom Lienard Date: Sun, 24 Dec 2023 08:15:04 +0100 Subject: [PATCH 6/6] fix: warn in changeLocale shows defined locales --- .../src/app/client/create-i18n-provider-client.tsx | 6 ++++-- .../src/app/client/create-use-change-locale.ts | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/next-international/src/app/client/create-i18n-provider-client.tsx b/packages/next-international/src/app/client/create-i18n-provider-client.tsx index 1a97543..e13e493 100644 --- a/packages/next-international/src/app/client/create-i18n-provider-client.tsx +++ b/packages/next-international/src/app/client/create-i18n-provider-client.tsx @@ -11,9 +11,8 @@ type I18nProviderProps = Omit; type I18nProviderWrapperProps = { locale: string; fallback?: ReactNode; - children: ReactNode; - importLocale: Promise>; + children: ReactNode; }; export const localesCache = new Map>(); @@ -25,9 +24,11 @@ export function createI18nProviderClient( ) { function I18nProvider({ locale, importLocale, children }: I18nProviderProps) { const clientLocale = (localesCache.get(locale) ?? use(importLocale).default) as Record; + if (!localesCache.has(locale)) { localesCache.set(locale, clientLocale); } + const value = useMemo( () => ({ localeContent: flattenLocale(clientLocale), @@ -42,6 +43,7 @@ export function createI18nProviderClient( return function I18nProviderWrapper({ locale, fallback, children }: I18nProviderWrapperProps) { const importFnLocale = locales[locale as keyof typeof locales]; + if (!importFnLocale) { error(`The locale '${locale}' is not supported. Defined locales are: [${Object.keys(locales).join(', ')}].`); notFound(); diff --git a/packages/next-international/src/app/client/create-use-change-locale.ts b/packages/next-international/src/app/client/create-use-change-locale.ts index 1ee0256..d866050 100644 --- a/packages/next-international/src/app/client/create-use-change-locale.ts +++ b/packages/next-international/src/app/client/create-use-change-locale.ts @@ -32,13 +32,15 @@ export function createUseChangeLocale( return function changeLocale(newLocale: LocalesKeys) { const importFnLocale = locales[newLocale as keyof typeof locales]; + if (!importFnLocale) { - warn(`The locale '${newLocale}' is not supported.`); + warn(`The locale '${newLocale}' is not supported. Defined locales are: [${Object.keys(locales).join(', ')}].`); return; } importFnLocale().then(module => { localesCache.set(newLocale as string, module.default); + push(`/${newLocale}${pathWithoutLocale}${finalSearchParams}`); refresh(); });