一句话总结
当我在await serverSideTranslations
里面getStaticProps
时,loading
来自的价值useSession()
仍然停留在true
.
语境
我使用next-auth.js
(v3) 进行身份验证。我已经(感激地)使用了一年没有问题。
const [session, loading]
=useSession()
是检查某人是否登录的钩子。
该
loading
选项表示会话状态正在更新;它是true
在获取会话数据并false
完成检查时。 https://stackoverflow.com/a/63191786/870121
我正在添加next-i18next
到我的项目中。大部分都在工作,但我遇到了一些困难。
我已按照.next-i18next
它适用于具有以下功能的页面getServerSideProps
:页面加载,next-authuseSession()
仍然有效,并且翻译工作没有警告或错误(示例)。例如,像这样/login
使用getServerSideProps
:
export const getServerSideProps = async (context) => {
const { locale } = context;
console.log("Have locale, ", locale);
return {
props: {
csrfToken: await csrfToken(context),
...(await serverSideTranslations(locale, ["common", "login"])),
},
};
};
并且适用于/de/login 和/en/login 或仅适用于 /login
您可能会在这两个页面上的导航栏(桌面上)的左上角短暂地看到“正在加载......”这个词。这出现在loading
是真的,但很快就消失了。
问题
当我使用它时遇到了一些困难getStaticProps
。具体来说,loading
由useSession()
res . 返回true
。
案例 A:当我在页面级别使用此代码时,翻译工作,但“加载”值 useSession() 仍然为真
export const getStaticProps = async ({ locale }) => {
const mood = "determined";
return {
props: {
mood,
...(await serverSideTranslations(locale, ["common", "test-page"])),
},
};
};
注意await
before serverSideTranslations
there 的使用;这是故意的,正如我见过的所有文档中所建议的那样。
以上导致该行无法按预期工作;loading
停留在true
...因此我不知道用户是否已登录。
import { useSession } from "next-auth/client";
const MyComponent = ()=>{
const [session, loading] = useSession();
return <div>loading is {loading ? "true" : "false"}</div>
}
关于 的某些东西await serverSideTranslations
导致useSession()
总是返回[undefined, true]
。
注意:我使用的是 next-auth v3,而不是 v4。
案例B:我可以删除await
之前的关键字serverSideTranslations
,然后useSession()
正常工作……但是翻译不起作用。
有小费吗?
到目前为止我已经尝试过:
我一直专注于尝试适应next-i18next
不需要的await
关键字。这让我陷入了连续警告/错误的困境,每个都是由先前的修复引起的:
serverSideTranslations
在in之前删除“await”getStaticProps
。- 尝试按照https://stackoverflow.com/a/69311205/870121添加
react: { useSuspense: false }
到 next-i18next.config.js (没有帮助)。 - 得到错误
react-i18next:: You will need to pass in an i18next instance by using initReactI18next
。→ 尝试通过添加use: [initReactI18next],
来修复next-i18next.config.js
。 - 得到错误,“appWithTranslation 调用没有配置”→通过添加到修复
_app.js
import nextI18NextConfig from "../../next-i18next.config.js"; // in page-level components: ...(await serverSideTranslations( locale, ["common", "login"], nextI18NextConfig )), // in pages/_app.js export default appWithTranslation(AwesoundApp, nextI18NextConfig);
- 获取诸如“错误:
._nextI18Next.userConfig.use[0].init
从getStaticProps
;返回的错误序列化”之类的错误 → 添加serializeConfig=false
到 next-i18next.config.js 并appWithTranslation
按照“不可序列化配置”说明将配置传递给。
但是,没有一个next-i18next
文档建议删除该await
关键字,因此这感觉像是一场失败的战斗/可能会带来一些意想不到的后果
我想要帮助的:
我可以在通话中留下await
之前的关键字,但仍然没有坚持吗?我可以按照这些文档的建议保留我的使用,但是以某种方式修改我的钩子,这样就不会坚持下去吗?我只是在代码中的其他地方遗漏了一些关键字吗?serverSideTranslations
getStaticProps
loading
true
next-i18next
nextauth
loading
await
示例代码
比较这两个页面:
- /de/test/no-await → 翻译不起作用。
- /de/test/with-await → 翻译工作,但
loading
卡住了true
,我不知道用户是否登录。
明确一点:我们想loading
迅速成为false
.
这两个页面具有以下代码。
next.config.js
(提炼):
const webpack = require("webpack");
const { i18n } = require("./next-i18next.config");
const moduleExports = {
i18n, // see require import above
webpack: (config, options) => {
config.resolve.fallback = {
perf_hooks: false, // as per "Quick Solution" on https://dev.to/marcinwosinek/how-to-add-resolve-fallback-to-webpack-5-in-nextjs-10-i6j
fs: false, // 2022-02-02 hack to fix i18n errors, per https://github.com/isaachinman/next-i18next/issues/935#issuecomment-970024608
path: false, // 2022-02-02 hack to fix i18n errors, per https://github.com/isaachinman/next-i18next/issues/935#issuecomment-970024608
};
return config;
},
…
}
next-i18next.config.js
(全部):
const path = require("path");
module.exports = {
i18n: {
defaultLocale: "en",
locales: ["en", "de"],
localePath: path.resolve("./public/locales"),
},
// react: { useSuspense: false },
// useSuspense false does NOT prevent the warning,
// "react-i18next:: You will need to pass in an i18next instance by using initReactI18next" on pages that use getStaticProps and serverSideTranslations
// per https://stackoverflow.com/a/69311205/870121
// We only get this initReactI18next error when we do NOT use await before serverSideTranslations.
debug: true,
};
pages/with-await.jsx
(全部):
见https://awesound-web-iow8f7d1o-awesound.vercel.app/de/test/with-await
// Similar to https://github.com/isaachinman/next-i18next/blob/ee5965183436d9b13d85c9187b3e09983b34ce7f/examples/simple/pages/second-page.js
// This has getStaticProps but not getStaticPaths
// Using 'await' with serverSideTranslations breaks next-auth useSession()
import Layout from "../../components/layout";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import TranslationTestContent from "../../components/test/translationTest";
const usesAwait = true;
const TestPage = ({ mood }) => {
return (
<Layout>
<TranslationTestContent mood={mood} usesAwait={usesAwait} />
</Layout>
);
};
export const getStaticProps = async ({ locale }) => {
const mood = "determined";
return {
props: {
mood,
...(await serverSideTranslations(locale, ["common", "test-page"])),
},
};
};
export default TestPage;
pages/no-await.jsx
(全部):
请参阅https://awesound-web-iow8f7d1o-awesound.vercel.app/de/test/no-await
注意它与pages/with-await.jsx
但 usesAwait 是错误的
// Similar to https://github.com/isaachinman/next-i18next/blob/ee5965183436d9b13d85c9187b3e09983b34ce7f/examples/simple/pages/second-page.js
// This has getStaticProps but not getStaticPaths
// Using 'await' with serverSideTranslations breaks next-auth useSession()
import Layout from "../../components/layout";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import TranslationTestContent from "../../components/test/translationTest";
const usesAwait = false;
const TestPage = ({ mood }) => {
return (
<Layout>
<TranslationTestContent mood={mood} usesAwait={usesAwait} />
</Layout>
);
};
export const getStaticProps = async ({ params, locale }) => {
const mood = "determined";
return {
props: {
mood,
...serverSideTranslations(locale, ["common", "test-page"]),
},
};
};
export default TestPage;
共享组件,
import { useTranslation } from "next-i18next";
import Link from "next/link";
import { useSession } from "next-auth/client";
import { useRouter } from "next/router";
import ExclamationTriangleIcon from "../icons/exclamationTriangle";
import CheckCircleIcon from "../icons/checkCircle";
const TranslationTestContent = ({ mood, usesAwait = true }) => {
const [session, loading] = useSession({ required: true });
const { locale } = useRouter();
const { t } = useTranslation("test-page");
return (
<main className="p-12">
<div className="">Test static page with getStaticProps</div>
<div className="">Do a full page refresh if you make any changes.</div>
<h1>This page uses await: {usesAwait ? "yes" : "no"}</h1>
<div>
{usesAwait ? (
<>
Result: translations work, but the `loading` stays true; we don't
know if user is logged in.
</>
) : (
<>
Result: translations don't work, but the `loading` does become
false.
</>
)}
</div>
<h3>Test translation</h3>
<div className="p-4 bg-seco-200 m-4 flex space-x-6">
<div>locale: {locale}</div>
<div>language: {t("language")}</div>
<div>
{t("language") === "language" ? (
<ExclamationTriangleIcon />
) : (
<CheckCircleIcon />
)}
</div>
</div>
<Link href="/">
<button type="button" className="btn btn-prim">
{t("Test page button")}
</button>
</Link>
<h3 className="mt-12">
Test <pre className="inline">`loading`</pre>
</h3>
<div className="p-4 bg-seco-200 m-4">
<div className="flex space-x-2 items-center">
<pre className="inline">loading</pre>:{" "}
<span className="inline">{loading ? "true" : "false"}</span>
{loading ? <ExclamationTriangleIcon /> : <CheckCircleIcon />}
</div>
<div>
<pre className="inline">session</pre> exists?{" "}
<span className="inline">{session ? "true" : "false"}</span>
</div>
</div>
<div className="border p-2 overflow-x-scroll">
session: {JSON.stringify(session)}
</div>
<h3>Look at other props</h3>
<div className="flex space-x-1 gap-x-1">
Via <pre>props</pre>, we have <pre>mood</pre> = <pre>[{mood}]</pre>.
</div>
</main>
);
};
export default TranslationTestContent;