diff --git a/__tests__/getT.test.js b/__tests__/getT.test.js
index c22ebae..49ecc73 100644
--- a/__tests__/getT.test.js
+++ b/__tests__/getT.test.js
@@ -1,5 +1,4 @@
import getT from '../src/getT'
-import store from '../src/_store'
const mockLoadLocaleFrom = jest.fn()
@@ -10,7 +9,7 @@ global.i18nConfig = {
describe('getT', () => {
beforeEach(() => {
- store.set()
+ globalThis.__NEXT_TRANSLATE__ = {}
mockLoadLocaleFrom.mockImplementation((__lang, ns) => {
if (ns === 'ns1') {
return Promise.resolve({
@@ -46,12 +45,12 @@ describe('getT', () => {
test('should work inside appDir', async () => {
const mockAppDirLoadLocaleFrom = jest.fn()
- store.set({
+ globalThis.__NEXT_TRANSLATE__ = {
config: {
keySeparator: false,
loadLocaleFrom: (...args) => mockAppDirLoadLocaleFrom(...args),
},
- })
+ }
mockAppDirLoadLocaleFrom.mockImplementationOnce(async (__lang, ns) => ({
'example-app-dir': 'works',
}))
diff --git a/__tests__/useTranslation.test.js b/__tests__/useTranslation.test.js
index 040ee60..adcd3ac 100644
--- a/__tests__/useTranslation.test.js
+++ b/__tests__/useTranslation.test.js
@@ -2,7 +2,6 @@ import React, { useState } from 'react'
import { render, cleanup, fireEvent } from '@testing-library/react'
import I18nProvider from '../src/I18nProvider'
import useTranslation from '../src/useTranslation'
-import _store from '../src/_store'
const Inner = ({ i18nKey, query }) => {
const { t } = useTranslation()
@@ -1526,7 +1525,7 @@ describe('useTranslation', () => {
})
describe('Next.js 13 app-dir', () => {
- test('should work without context (with _store)', () => {
+ test('should work without context (with globalThis.__NEXT_TRANSLATE__)', () => {
const Inner = () => {
const { t } = useTranslation()
const text = t('ns:interpolation', {
@@ -1537,7 +1536,7 @@ describe('useTranslation', () => {
const expected = 'There are 3 cats.'
- _store.set({
+ globalThis.__NEXT_TRANSLATE__ = {
namespaces: {
ns: {
interpolation: 'There are {{count}} cats.',
@@ -1545,7 +1544,7 @@ describe('useTranslation', () => {
},
lang: 'en',
config: {},
- })
+ }
const { container } = render()
expect(container.textContent).toContain(expected)
diff --git a/examples/basic/package.json b/examples/basic/package.json
index 0809478..d95571f 100644
--- a/examples/basic/package.json
+++ b/examples/basic/package.json
@@ -14,6 +14,6 @@
"react-dom": "link:../../node_modules/react-dom"
},
"devDependencies": {
- "next-translate-plugin": "2.4.0"
+ "next-translate-plugin": "2.4.1"
}
}
diff --git a/examples/complex/package.json b/examples/complex/package.json
index 71945cb..70b25d4 100644
--- a/examples/complex/package.json
+++ b/examples/complex/package.json
@@ -21,7 +21,7 @@
"@next/bundle-analyzer": "13.4.7",
"@types/node": "20.3.1",
"@types/react": "18.2.13",
- "next-translate-plugin": "2.4.0",
+ "next-translate-plugin": "2.4.1",
"typescript": "5.1.3"
},
"resolutions": {
diff --git a/examples/with-app-directory/package.json b/examples/with-app-directory/package.json
index de66c06..a70c8d9 100644
--- a/examples/with-app-directory/package.json
+++ b/examples/with-app-directory/package.json
@@ -22,7 +22,7 @@
"@next/bundle-analyzer": "13.4.6",
"@types/node": "20.3.1",
"@types/react": "18.2.12",
- "next-translate-plugin": "2.4.0",
+ "next-translate-plugin": "2.4.1",
"typescript": "5.1.3"
},
"resolutions": {
diff --git a/package.json b/package.json
index ca8f564..1b2d008 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "next-translate",
- "version": "2.4.0",
+ "version": "2.4.1",
"description": "Tiny and powerful i18n tools (Next plugin + API) to translate your Next.js pages.",
"license": "MIT",
"keywords": [
@@ -42,12 +42,12 @@
"useTranslation*",
"setLanguage*",
"index*",
- "_store*"
+ "AppDirI18nProvider*"
],
"scripts": {
"build": "yarn clean && cross-env NODE_ENV=production && yarn tsc",
"clean": "yarn clean:build && yarn clean:examples",
- "clean:build": "rm -rf lib appWith* Dynamic* I18n* index context loadNa* setLang* Trans* useT* withT* getP* getC* *.d.ts getT transC* wrapT* types formatElements _store*",
+ "clean:build": "rm -rf lib appWith* Dynamic* I18n* index context loadNa* setLang* Trans* useT* withT* getP* getC* *.d.ts getT transC* wrapT* types formatElements AppDirI18nProvider*",
"clean:examples": "rm -rf examples/**/.next && rm -rf examples/**/node_modules && rm -rf examples/**/yarn.lock",
"example": "yarn example:complex",
"example:basic": "yarn build && yarn --cwd examples/basic && yarn --cwd examples/basic dev",
diff --git a/src/AppDirI18nProvider.tsx b/src/AppDirI18nProvider.tsx
new file mode 100644
index 0000000..8a091b3
--- /dev/null
+++ b/src/AppDirI18nProvider.tsx
@@ -0,0 +1,27 @@
+'use client'
+
+import { I18nDictionary, LoaderConfig } from '.'
+
+type AppDirI18nProviderProps = {
+ lang: string
+ namespaces: Record
+ config: LoaderConfig
+ children: React.ReactNode
+}
+
+/**
+ * @description AppDirI18nProvider for internal use (next-translate-plugin) only.
+ * Is required because this is a RCC (React Client Component) and this way we
+ * provide a global i18n context for client components.
+ */
+export default function AppDirI18nProvider({
+ lang,
+ namespaces = {},
+ config,
+ children,
+}: AppDirI18nProviderProps) {
+ globalThis.__NEXT_TRANSLATE__ = { lang, namespaces, config }
+
+ // It return children and avoid re-renders and also allow children to be RSC (React Server Components)
+ return children
+}
diff --git a/src/_store.ts b/src/_store.ts
deleted file mode 100644
index 5ff4bdf..0000000
--- a/src/_store.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { DataForStoreType } from '.'
-
-let data: DataForStoreType
-
-export default {
- set(storeData: DataForStoreType) {
- data = {
- ...storeData,
- namespaces: {
- ...(data?.namespaces || {}),
- ...(storeData?.namespaces || {}),
- },
- }
- },
- get(): DataForStoreType {
- return data
- },
-}
diff --git a/src/getT.tsx b/src/getT.tsx
index a472637..850e77e 100644
--- a/src/getT.tsx
+++ b/src/getT.tsx
@@ -1,6 +1,5 @@
import getConfig from './getConfig'
import transCore from './transCore'
-import store from './_store'
import wrapTWithDefaultNs from './wrapTWithDefaultNs'
import { I18nDictionary, LocaleLoader } from './index'
@@ -8,7 +7,7 @@ export default async function getT(
locale = '',
namespace: string | string[] = ''
) {
- const appDir = store.get()
+ const appDir = globalThis.__NEXT_TRANSLATE__
const config = appDir?.config ?? getConfig()
const defaultLoader = async () => Promise.resolve({})
const lang = locale || config.defaultLocale || ''
diff --git a/src/index.tsx b/src/index.tsx
index 20ef5dc..407ff6f 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -121,7 +121,7 @@ declare global {
var __NEXT_TRANSLATE__: {
namespaces: Record
lang: string
- pathname?: string
+ config: LoaderConfig
}
namespace NodeJS {
diff --git a/src/loadNamespaces.tsx b/src/loadNamespaces.tsx
index 12edde1..9960b17 100644
--- a/src/loadNamespaces.tsx
+++ b/src/loadNamespaces.tsx
@@ -1,4 +1,4 @@
-import { LoaderConfig, LocaleLoader } from '.'
+import { I18nDictionary, LoaderConfig, LocaleLoader } from '.'
import getConfig from './getConfig'
import getPageNamespaces from './getPageNamespaces'
@@ -6,7 +6,7 @@ export default async function loadNamespaces(
config: LoaderConfig = {} as LoaderConfig
): Promise<{
__lang: string
- __namespaces?: Record
+ __namespaces?: Record
}> {
const conf = { ...getConfig(), ...config }
const localesToIgnore = conf.localesToIgnore || ['default']
@@ -48,10 +48,13 @@ export default async function loadNamespaces(
return {
__lang,
- __namespaces: namespaces.reduce((obj: Record, ns, i) => {
- obj[ns] = pageNamespaces[i] || (null as unknown as object)
- return obj
- }, {}),
+ __namespaces: namespaces.reduce(
+ (obj: Record, ns, i) => {
+ obj[ns] = pageNamespaces[i] || (null as unknown as I18nDictionary)
+ return obj
+ },
+ {}
+ ),
}
}
diff --git a/src/useTranslation.tsx b/src/useTranslation.tsx
index fed89ba..bd1cbba 100644
--- a/src/useTranslation.tsx
+++ b/src/useTranslation.tsx
@@ -1,6 +1,5 @@
import { useContext, useMemo } from 'react'
import { I18n } from '.'
-import store from './_store'
import wrapTWithDefaultNs from './wrapTWithDefaultNs'
import I18nContext from './context'
import transCore from './transCore'
@@ -17,7 +16,7 @@ function useTranslationInPages(defaultNS?: string): I18n {
}
function useTranslationAppDir(defaultNS?: string) {
- const { lang, namespaces, config } = store.get()
+ const { lang, namespaces, config } = globalThis.__NEXT_TRANSLATE__ ?? {}
const localesToIgnore = config.localesToIgnore || ['default']
const ignoreLang = localesToIgnore.includes(lang)
const t = transCore({
@@ -31,7 +30,7 @@ function useTranslationAppDir(defaultNS?: string) {
}
export default function useTranslation(defaultNS?: string): I18n {
- const appDir = store.get()
+ const appDir = globalThis.__NEXT_TRANSLATE__
const useT = appDir?.config ? useTranslationAppDir : useTranslationInPages
return useT(defaultNS)
}