_app.tsx Next.js 中的 getServerSideProps
getServerSideProps in _app.tsx in Next.js
那么,情况是这样的。
我正在尝试在应用程序初始化中获取“语言”cookie 以相应地更改 UI。
例如,如果语言是“阿拉伯语”(ar),我会将布局恢复为“RTL”,反之亦然。
有两种方法可以实现,第一种方法是在"useEffect()"中获取cookie,像这样...
import { parseCookies } from "nookies";
import { useEffect, useLayoutEffect, useState } from "react";
import { StyleSheetManager, ThemeProvider } from "styled-components";
import rtlPlugin from "stylis-plugin-rtl";
function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
const [appLanguage, setAppLanguage] = useState("en");
useEffect(() => {
const cookies = parseCookies();
setAppLanguage(cookies.language);
}, []);
useEffect(() => {
history.scrollRestoration = "manual";
if (appLanguage === "ar") {
document.documentElement.classList.add("rtl");
document.documentElement.dir = "rtl";
} else {
document.documentElement.classList.remove("rtl");
document.documentElement.dir = "ltr";
}
}, [appLanguage]);
console.log("Appp Language", appLanguage);
return (
<>
<ThemeProvider theme={theme}>
<StyleSheetManager stylisPlugins={[rtlPlugin]}>
<>
<GlobalStyle />
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
</>
</StyleSheetManager>
</ThemeProvider>
</>
);
}
export default wrapper.withRedux(MyApp);
这行得通,但您可以想象的问题是,在执行 useEffect()
之前,默认“英语”布局的页面会短暂闪烁。
避免这种闪烁行为的另一种方法当然是在 _app.tsx 级别上使用 getInitialProps
,就像这样...
MyApp.getInitialProps = async (appContext: AppContext) => {
const cookies = nookies.get(appContext)
const appLanguage = cookies.language;
const appProps = await App.getInitialProps(appContext);
return { appLanguage, ...appProps };
};
现在您可以在根 _app 级别上使用“appLanguage”道具来做任何您想做的事情。
这种方法的唯一问题是“Next.js”团队不建议在 _app 级别使用“getInitialProps”,因为根据文档...
"this disables the ability to perform automatic static optimization,
causing every page in your app to be server-side rendered."
另一方面,您似乎无法在根 _app 级别使用“getServerSideProps”。
所以,我的问题是,如何两全其美?获取状态以从根“_app”级别共享它而不使用 getInitialProps 不让服务器端呈现每个页面?
这可能吗?或者有没有办法在根“_app”文件中使用“getServerSideProps”?
感谢任何帮助。
我不确定这是否有帮助,但可能有一种方法可以避免闪烁。 Next.js 实际上具有可配置的 i18n routing, which tries to detect the user's preferred locale using browser headers. There's even cookie support,而不是默认的英语/LTR,但它必须是硬编码的 NEXT_LOCALE
cookie。
即使您已经探索过该解决方案,我也会将它留在这里供遇到类似问题的其他人使用。
============= 使用 NEXT.JS i18n 路由的解决方案 ===========
感谢@Summer 的建议,我能够使用 Next.js 内置的 i18n 路由解决方案解决我的问题,我不知道它存在。
导致 UI 闪烁的问题之所以发生,是因为我一直在等待 useEffect()
函数在 _app.tsx 中执行,以便添加某种特殊的 CSS class 或 HTML 属性标记,以便能够在 CSS 文件中定位 CSS class 并切换方向或执行任何其他操作CSS 修改。
但是现在通过使用内置的 Next.js i18n 路由,Next.js 可以通过查找“NEXT_LOCALE”cookie 或者他是否可以检测您应用程序的语言'发现他将默认为您选择的默认语言,这样做 Next.js 会自动向您的标签添加一个直接来自服务器的“lang”属性,然后您可以在您的CSS 切换布局方向...
html {
&[lang="ar"] {
direction: rtl;
}
}
而且不会造成任何布局闪烁。
再次感谢@Summer 的帮助。
这是一篇关于使用 Next.js 国际化路由的好文章。
https://blog.logrocket.com/complete-guide-internationalization-nextjs/
P.S:我决定编辑该答案以感谢@Summer。
目前不支持在 _app.tsx
上使用 getServerSideProps()
。
您可以关注 Github 上的讨论:https://github.com/vercel/next.js/discussions/10874
那么,情况是这样的。
我正在尝试在应用程序初始化中获取“语言”cookie 以相应地更改 UI。 例如,如果语言是“阿拉伯语”(ar),我会将布局恢复为“RTL”,反之亦然。
有两种方法可以实现,第一种方法是在"useEffect()"中获取cookie,像这样...
import { parseCookies } from "nookies";
import { useEffect, useLayoutEffect, useState } from "react";
import { StyleSheetManager, ThemeProvider } from "styled-components";
import rtlPlugin from "stylis-plugin-rtl";
function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
const [appLanguage, setAppLanguage] = useState("en");
useEffect(() => {
const cookies = parseCookies();
setAppLanguage(cookies.language);
}, []);
useEffect(() => {
history.scrollRestoration = "manual";
if (appLanguage === "ar") {
document.documentElement.classList.add("rtl");
document.documentElement.dir = "rtl";
} else {
document.documentElement.classList.remove("rtl");
document.documentElement.dir = "ltr";
}
}, [appLanguage]);
console.log("Appp Language", appLanguage);
return (
<>
<ThemeProvider theme={theme}>
<StyleSheetManager stylisPlugins={[rtlPlugin]}>
<>
<GlobalStyle />
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
</>
</StyleSheetManager>
</ThemeProvider>
</>
);
}
export default wrapper.withRedux(MyApp);
这行得通,但您可以想象的问题是,在执行 useEffect()
之前,默认“英语”布局的页面会短暂闪烁。
避免这种闪烁行为的另一种方法当然是在 _app.tsx 级别上使用 getInitialProps
,就像这样...
MyApp.getInitialProps = async (appContext: AppContext) => {
const cookies = nookies.get(appContext)
const appLanguage = cookies.language;
const appProps = await App.getInitialProps(appContext);
return { appLanguage, ...appProps };
};
现在您可以在根 _app 级别上使用“appLanguage”道具来做任何您想做的事情。
这种方法的唯一问题是“Next.js”团队不建议在 _app 级别使用“getInitialProps”,因为根据文档...
"this disables the ability to perform automatic static optimization, causing every page in your app to be server-side rendered."
另一方面,您似乎无法在根 _app 级别使用“getServerSideProps”。
所以,我的问题是,如何两全其美?获取状态以从根“_app”级别共享它而不使用 getInitialProps 不让服务器端呈现每个页面?
这可能吗?或者有没有办法在根“_app”文件中使用“getServerSideProps”?
感谢任何帮助。
我不确定这是否有帮助,但可能有一种方法可以避免闪烁。 Next.js 实际上具有可配置的 i18n routing, which tries to detect the user's preferred locale using browser headers. There's even cookie support,而不是默认的英语/LTR,但它必须是硬编码的 NEXT_LOCALE
cookie。
即使您已经探索过该解决方案,我也会将它留在这里供遇到类似问题的其他人使用。
============= 使用 NEXT.JS i18n 路由的解决方案 ===========
感谢@Summer 的建议,我能够使用 Next.js 内置的 i18n 路由解决方案解决我的问题,我不知道它存在。
导致 UI 闪烁的问题之所以发生,是因为我一直在等待 useEffect()
函数在 _app.tsx 中执行,以便添加某种特殊的 CSS class 或 HTML 属性标记,以便能够在 CSS 文件中定位 CSS class 并切换方向或执行任何其他操作CSS 修改。
但是现在通过使用内置的 Next.js i18n 路由,Next.js 可以通过查找“NEXT_LOCALE”cookie 或者他是否可以检测您应用程序的语言'发现他将默认为您选择的默认语言,这样做 Next.js 会自动向您的标签添加一个直接来自服务器的“lang”属性,然后您可以在您的CSS 切换布局方向...
html {
&[lang="ar"] {
direction: rtl;
}
}
而且不会造成任何布局闪烁。
再次感谢@Summer 的帮助。
这是一篇关于使用 Next.js 国际化路由的好文章。 https://blog.logrocket.com/complete-guide-internationalization-nextjs/
P.S:我决定编辑该答案以感谢@Summer。
目前不支持在 _app.tsx
上使用 getServerSideProps()
。
您可以关注 Github 上的讨论:https://github.com/vercel/next.js/discussions/10874