aralroca / next-translate

Next.js plugin + i18n API for Next.js 🌍 - Load page translations and use them in an easy way!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting slug instead of locale

crs1138 opened this issue Β· comments

Discussed in #1136

Originally posted by crs1138 August 17, 2023

Problem Description

I've got some weird behaviour and I'm struggling to pin it down. In the dev server, I keep getting the values of slug in place of the locale/lang variable.

Console output:

- wait compiling /[lang]/page (client and server)...
- warn ./i18n.js
Critical dependency: the request of a dependency is an expression

Import trace for requested module:
./i18n.js
./app/[lang]/page.tsx
loadLocaleFrom(locale, namespace) :::  { locale: 'about', namespace: 'common' }
Error: Cannot find module './about/common.json'
    at /Users/jpozivil/Sites/visas/var/www/static-visas/mono-repo-visas/apps/web/out/southkorea/southkorea1/server/app/[lang]/page.js:120:12
    at runNextTicks (node:internal/process/task_queues:61:5)
    at processTimers (node:internal/timers:499:9)
    at async Promise.all (index 0) {
  code: 'MODULE_NOT_FOUND'
}
loadLocaleFrom(locale, namespace) :::  { locale: 'about', namespace: 'common' }
next-translate - compiled page: /[lang] - locale: about - namespaces: common - used loader: server /page
Error: Cannot find module './about/common.json'
    at /Users/jpozivil/Sites/visas/var/www/static-visas/mono-repo-visas/apps/web/out/southkorea/southkorea1/server/app/[lang]/page.js:120:12
    at runNextTicks (node:internal/process/task_queues:61:5)
    at processTimers (node:internal/timers:499:9)
    at async Promise.all (index 0) {
  code: 'MODULE_NOT_FOUND'
}
next-translate - compiled page: /[lang] - locale: about - namespaces: common - used loader: server /layout
loadLocaleFrom(locale, namespace) :::  { locale: 'about', namespace: 'common' }
loadLocaleFrom(locale, namespace) :::  { locale: 'about', namespace: 'common' }
Error: Cannot find module './about/common.json'
    at /Users/jpozivil/Sites/visas/var/www/static-visas/mono-repo-visas/apps/web/out/southkorea/southkorea1/server/app/[lang]/page.js:120:12
    at async Promise.all (index 0) {
  code: 'MODULE_NOT_FOUND'
}

And this keeps repeating/loading indefinitelly.

Browser output:
image

My Setup

  • Turbo monorepo
  • next@13.4.13
  • next-translate@2.5.3
  • I use app router
  • The directory structure is as follows:
apps/web/app
└── [lang]
    β”œβ”€β”€ [slug]
    β”‚   └── page.tsx
    β”œβ”€β”€ admin
    β”‚   β”œβ”€β”€ admin.d.ts
    β”‚   β”œβ”€β”€ admin.tsx
    β”‚   └── page.tsx
    β”œβ”€β”€ app-router.d.ts
    β”œβ”€β”€ editor
    β”‚   β”œβ”€β”€ EditorForm.tsx
    β”‚   β”œβ”€β”€ form.d.ts
    β”‚   β”œβ”€β”€ layout.tsx
    β”‚   β”œβ”€β”€ page.tsx
    β”‚   └── styles.tsx
    β”œβ”€β”€ layout.tsx
    └── page.tsx

My Code

/* app/[lang]/layout.tsx */
...
const { product, theme } = getProductType();

const fetchDataCTX = async (): Promise<AppContextProps> => {
	const hostUrl = process.env.NEXT_PUBLIC_HOST || '';
	const apiData = await getApiDataByUrl(hostUrl);
	const styles = await asyncStyles(product, theme);
	const variables = JSON.parse(JSON.stringify(styles));

	const newStyles = await newAsyncStyles(product, theme);
	const newVars = JSON.parse(JSON.stringify(newStyles));
	const dataCTX: AppContextProps = {
		hostUrl,
		apiData,
		variables,
		newVars,
	};
	return dataCTX;
};

export default async function RootLayout({
	children,
}: {
	children: React.ReactNode;
}) {
	const { lang } = createTranslation();
	// Redirect to default locale if lang is not supported. /second-page -> /en/second-page
	// if (!i18n.locales.includes(lang))
	// 	redirect(`/${i18n.defaultLocale}`);

	const dataCTX = await fetchDataCTX().catch((err) => {
		console.error(err);
		throw new Error(err);
	});
	return (
		<html lang={lang}>
			<body>
				<Providers dataCTX={dataCTX as AppContextProps}>
					{children}
				</Providers>
			</body>
		</html>
	);
}
/* app/[lang]/[slug]/page.tsx */

const Pages = async ({ params: { slug } }: PageProps) => {
	const dataCTX = await fetchDataCTX();
	const { variables } = dataCTX;
	const { add_section: sections }: { add_section: SectionProps[] } =
		await getStaticProps(slug);

	return (
		<>
			{sections.map((section: SectionProps) => (
				<Section
					key={section.id}
					variables={variables}
					{...section}
				/>
			))}
		</>
	);
};

export default Pages;
/* i18n.js */

module.exports = {
	allowEmptyStrings: false, // Set to false force using keys as values
	defaultLocale: 'en-US',
	keySeparator: false, // Disable separator for nested keys in JSON translation files. Useful to use natural text as keys.
	localeDetection: false, // To prevent Next.js detect the browser language to decide the language
	locales: ['en-US', 'ja-JP'],
	nsSeparator: false, // Disable translations namespacing
	defaultNS: 'common',
	pages: {
		'*': ['common'],
	},
	loadLocaleFrom: (locale, namespace) => {
		console.log('loadLocaleFrom(locale, namespace) ::: ', {
			locale,
			namespace,
		});
		return import(
			`../../../my-special-path/locales/${locale}/${namespace}.json`
		)
			.then((m) => m.default)
			.catch((err) => console.error(err));
	},
};

@crs1138 check if #1141 (comment) solves it. Having i18n in next.config makes nextRequest.nextUrl.pathname miss the [lang] fragment.