我们有一个现有的应用程序,默认情况下将根目录"/"
重定向到该应用程序。"/search"
它通过我们的next-redirects.js
文件运行良好:
async function redirects() {
return [
{
source: '/',
destination: '/search',
permanent: true,
},
];
}
我必须使用 实现对应用程序的翻译next-i18next
,这样我们就可以使用 NextJS 开箱即用地翻译文本 + 路由。我已按照next-i8next docs中的步骤进行操作。我将next-i18next.config.js
文件添加为:
const path = require('path');
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'es'],
},
localePath: path.resolve('./public/static/locales'), // custom path file route
};
next.config 看起来像:
const { i18n } = require('./next-i18next.config');
const defaultConfig = {
env: {
SOME_ENV,
},
images: {
deviceSizes: [980],
domains: [
'd1',
'd2',
],
},
i18n,
redirects: require('./next-redirects'),
webpack: (config, options) => {
if (!options.isServer) {
config.resolve.alias['@sentry/node'] = '@sentry/browser';
}
if (
NODE_ENV === 'production'
) {
config.plugins.push(
new SentryWebpackPlugin({
include: '.next',
ignore: ['node_modules'],
urlPrefix: '~/_next',
release: VERCEL_GITHUB_COMMIT_SHA,
})
);
}
return config;
},
};
module.exports = withPlugins([withSourceMaps], defaultConfig);
根据 nextJS 文档,我们有一个使用 HOC 包装的自定义_app
文件,并使用 getInitialProps 进行设置:appWithTranslation
function MyApp({ Component, pageProps }) {
const [mounted, setMounted] = useState(false);
useEffect(() => {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentNode.removeChild(jssStyles);
}
TagManager.initialize(tagManagerArgs);
setMounted(true);
}, []);
const Layout = Component.Layout || Page;
return (
<>
<Head>
<link rel="icon" href="/favicon.png" type="image/ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</Head>
<AppProviders>
<Context {...pageProps}>
<Layout {...pageProps}>
<>
<Component {...pageProps} />
<Feedback />
<PageLoader />
</>
</Layout>
</Context>
</AppProviders>
</>
);
}
MyApp.getInitialProps = async ({ Component, ctx }) => {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps({ ctx });
}
const cookies = Cookie.parse(ctx?.req?.headers?.cookie || '');
if (Object.keys(cookies).length) {
const { token } = JSON.parse(cookies?.user || '{}');
let user = null;
if (token) {
const { data } = await get('api/users', { token });
if (data) {
user = data;
user.token = token;
}
}
pageProps.user = user;
pageProps.cart = cookies?.cart;
pageProps.defaultBilling = cookies?.defaultBilling;
pageProps.reservationEstimateItem = cookies?.reservationEstimateItem;
pageProps.reservationEstimate = cookies?.reservationEstimate;
}
return { pageProps };
};
export default appWithTranslation(MyApp);
我们有我们的_document
文件来处理一些情感主题:
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
const styles = extractCritical(initialProps.html);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
<style
data-emotion-css={styles.ids.join(' ')}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: styles.css }}
/>
</>
),
};
}
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
<script
type="text/javascript"
src="https://js.stripe.com/v2/"
async
/>
</body>
</Html>
);
}
}
// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with server-side generation (SSG).
MyDocument.getInitialProps = async ctx => {
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: App => props => sheets.collect(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [
...React.Children.toArray(initialProps.styles),
sheets.getStyleElement(),
],
};
};
此时,重定向逻辑应继续导航到search
设置如下的页面:
export const SearchPage = () => {
const router = useRouter();
const { t } = useTranslation('search');
return (
<>
<Head>
<title>{`${t('searchTitle')}`}</title>
<meta
property="og:title"
content={`${t('searchTitle')}`}
key="title"
/>
<meta
name="description"
content={t('metaDescription')}
/>
</Head>
<Search />
</>
);
};
SearchPage.namespace = 'SearchPage';
export const getStaticPaths = () => ({
paths: [], // indicates that no page needs be created at build time
fallback: 'blocking' // indicates the type of fallback
});
export const getStaticProps = async ({ locale }) => ({
// exposes `_nextI18Next` as props which includes our namespaced files
props: {
...await serverSideTranslations(locale, ['common', 'search']),
}
});
export default SearchPage;
根据所有页面级文件的需要,搜索页面具有getStaticPaths
&getStaticProps
功能,每个next-i18next
.
为什么此设置不再适用于重定向?
这意味着重写不起作用。但是 i18n 怎么办?
它是 _app 或 _document 文件中的内容吗?
- 如果我
/search
直接导航到,它加载得很好,所以页面路由似乎没问题。
其他注意事项:
- NextJS
"next": "^10.0.2",
- 下一个-i18下一个
"next-i18next": "^7.0.1",