提交 1f129d7a 编写于 作者: P Peter Pan

pack languages into static htmls

上级 3210f089
...@@ -26,6 +26,8 @@ const Aside = styled.aside` ...@@ -26,6 +26,8 @@ const Aside = styled.aside`
position: fixed; position: fixed;
top: ${headerHeight}; top: ${headerHeight};
right: 0; right: 0;
overflow-x: hidden;
overflow-y: auto;
`; `;
type ContentProps = { type ContentProps = {
......
...@@ -14,6 +14,11 @@ const APP = { ...@@ -14,6 +14,11 @@ const APP = {
keywords: pkg.keywords.join(',') keywords: pkg.keywords.join(',')
}; };
const DEFAULT_LANGUAGE = 'en';
const LOCALE_PATH = 'public/locales';
const LANGUAGES = ['en', 'zh'];
const otherLanguages = LANGUAGES.filter(lang => lang !== DEFAULT_LANGUAGE);
module.exports = { module.exports = {
target: 'serverless', target: 'serverless',
assetPrefix: publicPath, assetPrefix: publicPath,
...@@ -21,9 +26,21 @@ module.exports = { ...@@ -21,9 +26,21 @@ module.exports = {
poweredByHeader: false, poweredByHeader: false,
env: { env: {
...APP, ...APP,
DEFAULT_LANGUAGE,
LOCALE_PATH,
LANGUAGES,
PUBLIC_PATH: publicPath, PUBLIC_PATH: publicPath,
API_URL: apiUrl API_URL: apiUrl
}, },
exportPathMap: defaultPathMap => {
return {
...defaultPathMap,
...Object.entries(defaultPathMap).reduce((prev, [path, router]) => {
otherLanguages.forEach(lang => (prev[`/${lang}${path}`] = router));
return prev;
}, {})
};
},
webpack: config => { webpack: config => {
config.resolve = config.resolve || {}; config.resolve = config.resolve || {};
config.resolve.alias = config.resolve.alias || {}; config.resolve.alias = config.resolve.alias || {};
......
import '~/public/style/vdl-icon.css'; import '~/public/style/vdl-icon.css';
import React from 'react'; import React from 'react';
import App from 'next/app'; import {NextPageContext} from 'next';
import App, {AppContext} from 'next/app';
import Head from 'next/head'; import Head from 'next/head';
import NProgress from 'nprogress'; import NProgress from 'nprogress';
import {SWRConfig} from 'swr'; import {SWRConfig} from 'swr';
import {Router, appWithTranslation} from '~/utils/i18n'; import {i18n, Router, appWithTranslation} from '~/utils/i18n';
import {fetcher} from '~/utils/fetch'; import {fetcher} from '~/utils/fetch';
import {GlobalStyle} from '~/utils/style'; import {GlobalStyle} from '~/utils/style';
import Layout from '~/components/Layout'; import Layout from '~/components/Layout';
import {I18n} from 'next-i18next';
Router.events.on('routeChangeStart', () => NProgress.start()); Router.events.on('routeChangeStart', () => NProgress.start());
Router.events.on('routeChangeComplete', () => NProgress.done()); Router.events.on('routeChangeComplete', () => NProgress.done());
Router.events.on('routeChangeError', () => NProgress.done()); Router.events.on('routeChangeError', () => NProgress.done());
type I18nReq = {
i18n?: I18n;
locale?: string;
lng?: string;
language?: string;
};
type I18nRes = {
locals?: {
language?: string;
languageDir?: string;
};
};
class VDLApp extends App { class VDLApp extends App {
static async getInitialProps(appContext: AppContext) {
const req = appContext.ctx.req as (NextPageContext['req'] & I18nReq) | undefined;
if (req && !req.i18n) {
const {router} = appContext;
const result = router.asPath.match(/^\/(.*?)\//);
const lng = result ? result[1] : process.env.DEFAULT_LANGUAGE;
req.i18n = i18n.cloneInstance({initImmediate: false, lng});
const res = appContext.ctx.res as (NextPageContext['res'] & I18nRes) | undefined;
const setContextLocale = (lng?: string) => {
// SEE: i18n-express-middleware
req.language = req.locale = req.lng = lng;
if (res) {
res.locals = res.locals || {};
res.locals.language = lng;
res.locals.languageDir = i18n.dir(lng);
}
};
setContextLocale(lng);
i18n.on('languageChanged', setContextLocale);
}
const appProps = await App.getInitialProps(appContext);
return {...appProps};
}
render() { render() {
const {Component, pageProps} = this.props; const {Component, pageProps} = this.props;
......
...@@ -3,6 +3,7 @@ import {ServerStyleSheet} from '~/utils/style'; ...@@ -3,6 +3,7 @@ import {ServerStyleSheet} from '~/utils/style';
interface VDLDocumentProps extends DocumentProps { interface VDLDocumentProps extends DocumentProps {
language: string; language: string;
languageDir: string;
} }
export default class VDLDocument extends Document<VDLDocumentProps> { export default class VDLDocument extends Document<VDLDocumentProps> {
...@@ -18,12 +19,11 @@ export default class VDLDocument extends Document<VDLDocumentProps> { ...@@ -18,12 +19,11 @@ export default class VDLDocument extends Document<VDLDocumentProps> {
}); });
const initialProps = await Document.getInitialProps(ctx); const initialProps = await Document.getInitialProps(ctx);
// stealed from https://github.com/isaachinman/next-i18next/issues/20#issuecomment-558799264 // stealed from https://github.com/isaachinman/next-i18next/issues/20#issuecomment-558799264
// FIXME: https://github.com/i18next/i18next-express-middleware/blob/master/src/index.js#L23-L26 // FIXME: https://github.com/i18next/i18next-express-middleware/blob/master/src/index.js#L23-L26
const additionalProps = { const additionalProps = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
language: (ctx.res as any)?.locals?.language ?? 'en' ...((ctx.res as any)?.locals || {})
}; };
return { return {
...@@ -42,9 +42,9 @@ export default class VDLDocument extends Document<VDLDocumentProps> { ...@@ -42,9 +42,9 @@ export default class VDLDocument extends Document<VDLDocumentProps> {
} }
render() { render() {
const {language} = this.props; const {language, languageDir} = this.props;
return ( return (
<html lang={language}> <html lang={language} dir={languageDir}>
<Head /> <Head />
<body> <body>
<Main /> <Main />
......
...@@ -11,7 +11,7 @@ const Index: NextI18NextPage = () => { ...@@ -11,7 +11,7 @@ const Index: NextI18NextPage = () => {
Index.getInitialProps = () => { Index.getInitialProps = () => {
return { return {
namespacesRequired: [] namespacesRequired: ['common']
}; };
}; };
......
import {NextComponentType, NextPageContext} from 'next'; import {NextComponentType, NextPageContext} from 'next';
import NextI18Next from 'next-i18next'; import NextI18Next from 'next-i18next';
import {env} from '../next.config';
const defaultLanguage = env.DEFAULT_LANGUAGE;
const allLanguages = env.LANGUAGES;
const otherLanguages = allLanguages.filter(lang => lang !== defaultLanguage);
const isDev = process.env.NODE_ENV === 'development'; const isDev = process.env.NODE_ENV === 'development';
const nextI18Next = new NextI18Next({ const nextI18Next = new NextI18Next({
localePath: 'public/locales', localePath: env.LOCALE_PATH,
browserLanguageDetection: !isDev, browserLanguageDetection: !isDev,
serverLanguageDetection: !isDev, serverLanguageDetection: !isDev,
defaultLanguage: 'en', cleanCode: true,
otherLanguages: ['zh'], defaultLanguage,
localeSubpaths: { otherLanguages,
zh: 'zh' localeSubpaths: otherLanguages.reduce((prev, curr) => {
} prev[curr] = curr;
return prev;
}, {} as Record<string, string>)
}); });
// from ~/node_modules/next/types/index.d.ts // from ~/node_modules/next/types/index.d.ts
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册