如何在 Next.js 的服务器端访问自定义应用程序中的语言环境?
How to access locale in custom app on server-side in Next.js?
我正在将项目从 next.js 7 迁移到 10。它使用 react-intl 进行翻译并且是用打字稿写的。
在以前的版本中,我 有一个自定义 server.js 并处理 子路由 (/de,/fr 等)用于多语言目的在其中。在自定义应用程序组件中,通过 getInitialProps,我从 req 获取 locale 并将其作为道具传递给我的组件。所以整个画面是这样的:
自定义应用程序:
static async getInitialProps({ Component, ctx }) {
let pageProps = {}
const { req } = ctx;
const { locale, messages } = req || (window as any).__NEXT_DATA__.props;
const initialNow = Date.now();
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps, locale, messages, initialNow }
}
和组件
render() {
const { Component, pageProps, locale, messages, initialNow } = (this.props as any);
return (
<Container>
<IntlProvider locale={locale} messages={messages} initialNow={initialNow}>
<Component {...pageProps} />
</IntlProvider>
</Container>
)
}
现在因为我正在使用 next.js 10,出于多种原因我删除了自定义 server.js 并通过 i18n 进行了子路由,所以我在 next.config.js 中添加了这个:
module.exports = {
i18n: {
locales: ["en", "de", "fr"],
defaultLocale: "en",
},
}
唯一的问题是我需要将语言环境传递给服务器端和所有页面的 react-intl 的 IntlProvider。所以我想我应该在自定义应用程序中执行此操作,并且 getInitialProps returns 区域设置的错误值(始终默认)。而且我们不能在自定义 _app 中使用 getServerSideProps 或 getStaticProps。
所以终于!问题是:
我如何才能在一个地方访问我所有页面的服务器端语言环境?或者有没有更好的方法来解决这个问题?
(我暂时无法删除 intl 并完全使用 i18n,这个特定项目需要很多时间,而我们没有它!)
您可以通过 router
属性访问自定义应用 getInitialProps
中的 locale
。
static async getInitialProps({ Component, ctx, router }) {
let pageProps = {}
const { req } = ctx;
const { locale } = router; // Will return `fr` for `/fr/*` pages
const { messages } = req || (window as any).__NEXT_DATA__.props;
const initialNow = Date.now();
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps, locale, messages, initialNow }
}
在自定义应用程序页面之外使用 getServerSideProps
/getStaticProps
时,可以直接从上下文对象访问活动语言环境。
export async function getServerSideProps({ locale }) {
console.log(locale) // Logs current locale
// ...
}
export async function getStaticProps({ locale }) {
console.log(locale) // Logs current locale
// ...
}
有关详细信息,请查看 Next.js i18n routing documentation。
我正在将项目从 next.js 7 迁移到 10。它使用 react-intl 进行翻译并且是用打字稿写的。
在以前的版本中,我 有一个自定义 server.js 并处理 子路由 (/de,/fr 等)用于多语言目的在其中。在自定义应用程序组件中,通过 getInitialProps,我从 req 获取 locale 并将其作为道具传递给我的组件。所以整个画面是这样的:
自定义应用程序:
static async getInitialProps({ Component, ctx }) {
let pageProps = {}
const { req } = ctx;
const { locale, messages } = req || (window as any).__NEXT_DATA__.props;
const initialNow = Date.now();
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps, locale, messages, initialNow }
}
和组件
render() {
const { Component, pageProps, locale, messages, initialNow } = (this.props as any);
return (
<Container>
<IntlProvider locale={locale} messages={messages} initialNow={initialNow}>
<Component {...pageProps} />
</IntlProvider>
</Container>
)
}
现在因为我正在使用 next.js 10,出于多种原因我删除了自定义 server.js 并通过 i18n 进行了子路由,所以我在 next.config.js 中添加了这个:
module.exports = {
i18n: {
locales: ["en", "de", "fr"],
defaultLocale: "en",
},
}
唯一的问题是我需要将语言环境传递给服务器端和所有页面的 react-intl 的 IntlProvider。所以我想我应该在自定义应用程序中执行此操作,并且 getInitialProps returns 区域设置的错误值(始终默认)。而且我们不能在自定义 _app 中使用 getServerSideProps 或 getStaticProps。
所以终于!问题是: 我如何才能在一个地方访问我所有页面的服务器端语言环境?或者有没有更好的方法来解决这个问题?
(我暂时无法删除 intl 并完全使用 i18n,这个特定项目需要很多时间,而我们没有它!)
您可以通过 router
属性访问自定义应用 getInitialProps
中的 locale
。
static async getInitialProps({ Component, ctx, router }) {
let pageProps = {}
const { req } = ctx;
const { locale } = router; // Will return `fr` for `/fr/*` pages
const { messages } = req || (window as any).__NEXT_DATA__.props;
const initialNow = Date.now();
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps, locale, messages, initialNow }
}
在自定义应用程序页面之外使用 getServerSideProps
/getStaticProps
时,可以直接从上下文对象访问活动语言环境。
export async function getServerSideProps({ locale }) {
console.log(locale) // Logs current locale
// ...
}
export async function getStaticProps({ locale }) {
console.log(locale) // Logs current locale
// ...
}
有关详细信息,请查看 Next.js i18n routing documentation。