mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-14 03:30:19 +00:00
✨ feat(i18n): Add i18next and lobe-i18n internationalization configuration files and update dependencies
This commit introduces new configuration files for internationalization, deletes one file, modifies existing files, and adds new files. The changes also involve importing dependencies and updating app and document pages. Additional libraries and modules are used in a React application. The Header component is modified, the index page is updated for server-side translations, and the tsconfig.json file is modified. Description: - Added configuration files for internationalization - Deleted one file - Modified existing files - Added new files - Imported dependencies - Updated app and document pages - Used additional libraries and modules in a React application - Modified the Header component - Updated the index page for server-side translations - Modified the tsconfig.json file.
This commit is contained in:
+12
@@ -0,0 +1,12 @@
|
||||
const { description } = require('./package.json');
|
||||
|
||||
module.exports = {
|
||||
reference: description,
|
||||
entry: 'public/locales/zh_CN',
|
||||
entryLocale: 'zh_CN',
|
||||
output: 'public/locales',
|
||||
outputLocales: ['zh_HK', 'en_US', 'ja_JP', 'ko_KR'],
|
||||
splitToken: 2500,
|
||||
temperature: 0,
|
||||
modelName: 'gpt-3.5-turbo',
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
extends: ['gitmoji'],
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
const i18n = require('./.i18nrc');
|
||||
|
||||
/** @type {import('next-i18next').UserConfig} */
|
||||
module.exports = {
|
||||
debug: process.env.NODE_ENV === 'development',
|
||||
i18n: {
|
||||
defaultLocale: i18n.entryLocale,
|
||||
locales: [i18n.entryLocale, i18n.outputLocales],
|
||||
},
|
||||
localePath:
|
||||
typeof window === 'undefined' ? require('node:path').resolve('./', i18n.output) : '/locales',
|
||||
reloadOnPrerender: process.env.NODE_ENV === 'development',
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
const pc = require('picocolors');
|
||||
|
||||
const nextUtilsConfig = () => {
|
||||
const trueEnv = ['true', '1', 'yes'];
|
||||
const esmExternals = trueEnv.includes(process.env?.NEXTJS_ESM_EXTERNALS ?? 'false');
|
||||
const tsconfigPath = process.env.NEXTJS_TSCONFIG_PATH
|
||||
? process.env.NEXTJS_TSCONFIG_PATH
|
||||
: './tsconfig.json';
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
`${pc.green('warn -')} experimental.esmExternals is ${esmExternals ? 'enabled' : 'disabled'}`,
|
||||
);
|
||||
return {
|
||||
esmExternals,
|
||||
tsconfigPath,
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
loadCustomBuildParams: nextUtilsConfig,
|
||||
};
|
||||
+12
-1
@@ -1,11 +1,22 @@
|
||||
// @ts-check
|
||||
import i18nConfig from './next-i18next.config.js';
|
||||
import utilsConfig from './next-utils.config.js';
|
||||
|
||||
const API_END_PORT_URL = process.env.API_END_PORT_URL || '';
|
||||
|
||||
const { esmExternals = false, tsconfigPath } = utilsConfig.loadCustomBuildParams();
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
experimental: {
|
||||
esmExternals, // https://nextjs.org/blog/next-11-1#es-modules-support
|
||||
},
|
||||
i18n: i18nConfig.i18n,
|
||||
reactStrictMode: true,
|
||||
pageExtensions: ['page.tsx', 'api.ts'],
|
||||
transpilePackages: ['@lobehub/ui', 'antd-style'],
|
||||
typescript: {
|
||||
tsconfigPath,
|
||||
},
|
||||
webpack(config) {
|
||||
config.experiments = {
|
||||
asyncWebAssembly: true,
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"dev": "next dev -p 3010",
|
||||
"i18n": "lobe-i18n",
|
||||
"lint": "eslint \"{src,tests}/**/*.{js,jsx,ts,tsx}\" --fix",
|
||||
"lint:md": "remark . --quiet --frail --output",
|
||||
"lint:style": "stylelint \"{src,tests}/**/*.{js,jsx,ts,tsx}\" --fix",
|
||||
@@ -34,6 +35,7 @@
|
||||
"test": "vitest --passWithNoTests",
|
||||
"test:coverage": "vitest run --coverage --passWithNoTests",
|
||||
"test:update": "vitest -u",
|
||||
"toc": "i18next-resources-for-ts toc -i ./public/locales/zh_CN -o ./src/types/resources.ts",
|
||||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"lint-staged": {
|
||||
@@ -75,6 +77,7 @@
|
||||
"lucide-react": "latest",
|
||||
"nanoid": "^4",
|
||||
"next": "13.4.7",
|
||||
"next-i18next": "^14",
|
||||
"polished": "^4",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
@@ -88,6 +91,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17",
|
||||
"@lobehub/i18n-cli": "latest",
|
||||
"@lobehub/lint": "latest",
|
||||
"@next/eslint-plugin-next": "^13",
|
||||
"@testing-library/jest-dom": "^5",
|
||||
@@ -104,10 +108,12 @@
|
||||
"commitlint": "^17",
|
||||
"eslint": "^8",
|
||||
"husky": "^8",
|
||||
"i18next-resources-for-ts": "^1",
|
||||
"jsdom": "^22",
|
||||
"lint-staged": "^13",
|
||||
"next-pwa": "^5",
|
||||
"node-fetch": "^3",
|
||||
"picocolors": "^1",
|
||||
"postcss-styled-syntax": "^0.4",
|
||||
"prettier": "^2",
|
||||
"remark": "^14",
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"setting": "Setting",
|
||||
"share": "Share"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"setting": "設定",
|
||||
"share": "共有する"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"setting": "설정",
|
||||
"share": "공유"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"setting": "设置",
|
||||
"share": "分享"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"setting": "設置",
|
||||
"share": "分享"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { Namespace } from 'i18next';
|
||||
import type { SSRConfig, UserConfig } from 'next-i18next';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
|
||||
import nextI18nextConfig from '@/../next-i18next.config';
|
||||
|
||||
type ArrayElementOrSelf<T> = T extends Array<infer U> ? U[] : T[];
|
||||
|
||||
export const getServerTranslations = async (
|
||||
locale: string,
|
||||
namespacesRequired?: ArrayElementOrSelf<Namespace> | undefined,
|
||||
configOverride?: UserConfig,
|
||||
extraLocales?: string[] | false,
|
||||
): Promise<SSRConfig> => {
|
||||
const config = configOverride ?? nextI18nextConfig;
|
||||
// @ts-ignore
|
||||
return serverSideTranslations(locale, namespacesRequired, config, extraLocales);
|
||||
};
|
||||
@@ -1,15 +1,19 @@
|
||||
import { Analytics } from '@vercel/analytics/react';
|
||||
import { appWithTranslation } from 'next-i18next';
|
||||
import type { AppProps } from 'next/app';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
import Layout from '@/layout';
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
<Layout>
|
||||
<Component {...pageProps} />
|
||||
<Analytics />
|
||||
</Layout>
|
||||
<Suspense fallback="loading">
|
||||
<Layout>
|
||||
<Component {...pageProps} />
|
||||
<Analytics />
|
||||
</Layout>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
export default MyApp;
|
||||
export default appWithTranslation(MyApp);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { StyleProvider, extractStaticStyle } from 'antd-style';
|
||||
import Document, { DocumentContext, Head, Html, Main, NextScript } from 'next/document';
|
||||
|
||||
import i18nextConfig from '../../next-i18next.config.js';
|
||||
|
||||
class MyDocument extends Document {
|
||||
static async getInitialProps(ctx: DocumentContext) {
|
||||
const page = await ctx.renderPage({
|
||||
@@ -28,9 +30,37 @@ class MyDocument extends Document {
|
||||
}
|
||||
|
||||
render() {
|
||||
const currentLocale = this.props.__NEXT_DATA__.locale ?? i18nextConfig.i18n.defaultLocale;
|
||||
return (
|
||||
<Html lang="en">
|
||||
<Head></Head>
|
||||
<Html lang={currentLocale}>
|
||||
<Head>
|
||||
<link
|
||||
href="https://npm.elemecdn.com/@lobehub/assets-favicons/assets/apple-touch-icon.png"
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
/>
|
||||
<link
|
||||
href="https://npm.elemecdn.com/@lobehub/assets-favicons/assets/favicon-32x32.png"
|
||||
rel="icon"
|
||||
sizes="32x32"
|
||||
type="image/png"
|
||||
/>
|
||||
<link
|
||||
href="https://npm.elemecdn.com/@lobehub/assets-favicons/assets/favicon-16x16.png"
|
||||
rel="icon"
|
||||
sizes="16x16"
|
||||
type="image/png"
|
||||
/>
|
||||
<link
|
||||
color="#000000"
|
||||
href="https://npm.elemecdn.com/@lobehub/assets-favicons/assets/safari-pinned-tab.svg"
|
||||
rel="mask-icon"
|
||||
/>
|
||||
<meta content="LobeHub" name="apple-mobile-web-app-title" />
|
||||
<meta content="LobeHub" name="application-name" />
|
||||
<meta content="#000000" name="msapplication-TileColor" />
|
||||
<meta content="#000000" name="theme-color" />
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ActionIcon, Avatar } from '@lobehub/ui';
|
||||
import { createStyles, useTheme } from 'antd-style';
|
||||
import { ArchiveIcon, MoreVerticalIcon, Share2Icon } from 'lucide-react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { memo } from 'react';
|
||||
import { Flexbox } from 'react-layout-kit';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
@@ -19,6 +20,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
}));
|
||||
const Header = memo(() => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation('common');
|
||||
const meta = useChatStore((s) => {
|
||||
const chat = sessionSelectors.currentSession(s);
|
||||
return chat?.meta;
|
||||
@@ -62,7 +64,7 @@ const Header = memo(() => {
|
||||
onClick={() => {
|
||||
// genShareUrl();
|
||||
}}
|
||||
title={'分享'}
|
||||
title={t('share')}
|
||||
/>
|
||||
<ActionIcon icon={ArchiveIcon} title={'归档'} />
|
||||
<ActionIcon icon={MoreVerticalIcon} onClick={toggleConfig} />
|
||||
|
||||
@@ -1 +1,17 @@
|
||||
export { default } from './chat/index.page';
|
||||
import type { GetStaticProps, InferGetStaticPropsType } from 'next';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
|
||||
import Chat from './chat/index.page';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const Index = (_props: InferGetStaticPropsType<typeof getStaticProps>) => {
|
||||
return <Chat />;
|
||||
};
|
||||
|
||||
export const getStaticProps: GetStaticProps = async ({ locale }) => ({
|
||||
props: {
|
||||
...(await serverSideTranslations(locale ?? 'zh_CN', ['common'])),
|
||||
},
|
||||
});
|
||||
|
||||
export default Index;
|
||||
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
import resources from '@/types/resources';
|
||||
|
||||
declare module 'i18next' {
|
||||
interface CustomTypeOptions {
|
||||
defaultNS: 'common';
|
||||
resources: typeof resources;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import common from '@/../public/locales/zh_CN/common.json';
|
||||
|
||||
const resources = {
|
||||
common,
|
||||
} as const;
|
||||
|
||||
export default resources;
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
@@ -21,5 +22,5 @@
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules"],
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.d.ts", "**/*.tsx"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user