为了促进 nextjs 升级(12 -> 14),目前还不清楚如何在 SSG 应用程序中仅使用利用
pages
路由器的动态捕获所有路由来配置 i18n。
问题的关键是 NextJS 现在在配置中设置
i18n
时会出现 SSG 错误。当它被删除并且 locales
在 getStaticPaths
中侧面加载时,构建错误表明配置中未指定区域设置。
有人可以指出促进此升级所需的更改吗?
next-translate
当前用于处理 i18n,但不是维护的要求; SSG、i18n、pages
路由器和动态捕获所有路由。
next.config.js
:
const nextConfig = {
output: 'export',
i18n: {
locales, defaultLocale,
localeDetection: false,
},
./src/pages/[[...slug]].js
(动态捕获所有路线):
export const getStaticPaths = async ({ locales }) => {
const paths = [];
await Promise.all(locales?.map(async (locale) => {
// fetch and parse entries, then:
paths.push({ params: { slug }, locale });
}));
return {
paths,
fallback: false
};
};
i18n.js
:
module.exports={
"localeDetection": false,
"locales": [
"en-US",
"es"
],
"defaultLocale": "en-US",
"loadLocaleFrom": (lang, ns) => import(`./locales/${lang}/${ns}.json`).then((m) => m.default),
"pages": {
"*": [
"common"
]
},
"logBuild": false
};
版本:
鉴于先前/原始
next.config.js
,构建失败,如果还设置了 i18n
,则在 next.config.js
中指定output: 'export'
不能。然而,删除
i18n
会带来 getStaticProps
中的问题:
locales
,则 NextJS 缓存中不存在
i18n
。以前,locales
(来自 NextJS 上下文)被映射为 paths
生成的一部分,例如getStaticPaths
上面的片段。
尝试侧载
locales
w/in getStaticPaths
,例如:
import i18n from '../../i18n';
export const getStaticPaths = async () => {
const { locales } = i18n;
产生以下错误:
Error: Invalid locale returned from getStaticPaths for /[[...slug]], the locale en-US is not specified in next.config.js
patch-package
注释掉与 i18n
使用 SSG 相关的两个错误时,构建即将完成。实际上,这个补丁规避了 NextJS 施加的看似不必要的限制(至少在 v13.x.x
上)以防止静态导出的 i18n。
next+13.4.9.patch
diff --git a/node_modules/next/dist/export/index.js b/node_modules/next/dist/export/index.js
index f0579c2..57dc01a 100644
--- a/node_modules/next/dist/export/index.js
+++ b/node_modules/next/dist/export/index.js
@@ -326,9 +326,9 @@ async function exportApp(dir, options, span) {
};
}
const { i18n , images: { loader ="default" , unoptimized } } = nextConfig;
- if (i18n && !options.buildExport) {
- throw new ExportError(`i18n support is not compatible with next export. See here for more info on deploying: https://nextjs.org/docs/messages/export-no-custom-routes`);
- }
+ // if (i18n && !options.buildExport) {
+ // throw new ExportError(`i18n support is not compatible with next export. See here for more info on deploying: https://nextjs.org/docs/messages/export-no-custom-routes`);
+ // }
if (!options.buildExport) {
const { isNextImageImported } = await nextExportSpan.traceChild("is-next-image-imported").traceAsyncFn(()=>_fs.promises.readFile((0, _path.join)(distDir, _constants1.EXPORT_MARKER), "utf8").then((text)=>JSON.parse(text)).catch(()=>({})));
if (isNextImageImported && loader === "default" && !unoptimized && !_ciinfo.hasNextSupport) {
diff --git a/node_modules/next/dist/server/config.js b/node_modules/next/dist/server/config.js
index 90a4db3..dc40674 100644
--- a/node_modules/next/dist/server/config.js
+++ b/node_modules/next/dist/server/config.js
@@ -211,9 +211,9 @@ function assignDefaults(dir, userConfig, silent = false) {
...config
};
if (result.output === "export") {
- if (result.i18n) {
- throw new Error('Specified "i18n" cannot be used with "output: export". See more info here: https://nextjs.org/docs/messages/export-no-i18n');
- }
+ // if (result.i18n) {
+ // throw new Error('Specified "i18n" cannot be used with "output: export". See more info here: https://nextjs.org/docs/messages/export-no-i18n');
+ // }
if (result.rewrites) {
throw new Error('Specified "rewrites" cannot be used with "output: export". See more info here: https://nextjs.org/docs/messages/export-no-custom-routes');
}
next.config.js
:
require('dotenv').config();
const withPlugins = require('next-compose-plugins');
const nextTranslate = require('next-translate');
const i18n = require('./i18n');
const { locales, defaultLocale } = i18n;
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
i18n: { locales, defaultLocale },
};
module.exports = withPlugins(
[
[
{
generateBuildId: async () => 'build',
}
],
nextTranslate
],
nextConfig
);
当前工作版本中使用的版本(从问题中指定的版本更改):