Repository: Quilljou/transmart Branch: main Commit: 012411f14183 Files: 73 Total size: 349.2 KB Directory structure: gitextract_t6167sma/ ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github/ │ └── ISSUE_TEMPLATE/ │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md ├── .gitignore ├── .prettierrc.js ├── CONTRIBUTING.md ├── LICENSE ├── README-zh_CN.md ├── README.md ├── commitlint.config.js ├── examples/ │ ├── README.md │ ├── chrome-extension/ │ │ ├── README.md │ │ ├── _locales/ │ │ │ └── en/ │ │ │ └── messages.json │ │ ├── feed.html │ │ ├── manifest.json │ │ ├── package.json │ │ └── transmart.config.js │ └── next.js/ │ ├── @types/ │ │ └── i18next.d.ts │ ├── components/ │ │ ├── Footer.tsx │ │ └── Header.tsx │ ├── next-env.d.ts │ ├── next-i18next.config.js │ ├── next-utils.config.js │ ├── next.config.js │ ├── package.json │ ├── pages/ │ │ ├── _app.tsx │ │ ├── _document.tsx │ │ ├── index.tsx │ │ └── second-page.tsx │ ├── public/ │ │ ├── app.css │ │ └── locales/ │ │ └── en/ │ │ ├── common.json │ │ ├── footer.json │ │ └── second-page.json │ ├── transmart.config.js │ ├── tsconfig.json │ └── vercel.json ├── lerna.json ├── package.json ├── packages/ │ ├── cli/ │ │ ├── README.md │ │ ├── bin/ │ │ │ └── transmart.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── cli.ts │ │ │ ├── index.ts │ │ │ ├── options.ts │ │ │ └── types.ts │ │ └── tsconfig.build.json │ └── core/ │ ├── README.md │ ├── package.json │ ├── src/ │ │ ├── index.ts │ │ ├── language.ts │ │ ├── limit.ts │ │ ├── split.ts │ │ ├── task.ts │ │ ├── translate.ts │ │ ├── transmart.ts │ │ ├── types.ts │ │ └── util.ts │ ├── test/ │ │ └── locales/ │ │ ├── de/ │ │ │ ├── common.json │ │ │ └── tos.json │ │ ├── en/ │ │ │ ├── common.json │ │ │ ├── large-file.json │ │ │ └── tos.json │ │ ├── jp/ │ │ │ └── common.json │ │ ├── zh-CN/ │ │ │ ├── common.json │ │ │ ├── large-file.json │ │ │ └── tos.json │ │ └── zh-TW/ │ │ ├── common.json │ │ └── tos.json │ └── tsconfig.build.json └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ # http://editorconfig.org root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true # Use 4 spaces for the Python and HTML files [*.py, *.html] indent_size = 4 # The JSON files contain newlines inconsistently [*.json] insert_final_newline = ignore # Minified JavaScript files shouldn't be changed [**.min.js] indent_style = ignore insert_final_newline = ignore # Makefiles always use tabs for indentation [Makefile] indent_style = tab # Batch files use tabs for indentation [*.bat] indent_style = tab [*.md] trim_trailing_whitespace = false ================================================ FILE: .eslintignore ================================================ examples ================================================ FILE: .eslintrc ================================================ { "root": true, "parser": "@typescript-eslint/parser", "env": { "browser": true, "node": true, "es6": true }, "ignorePatterns": ["lib"], "plugins": [ "@typescript-eslint", "prettier" ], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", "prettier" ] } ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve title: '' labels: '' assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. iOS] - Browser [e.g. chrome, safari] - Version [e.g. 22] **Smartphone (please complete the following information):** - Device: [e.g. iPhone6] - OS: [e.g. iOS8.1] - Browser [e.g. stock browser, safari] - Version [e.g. 22] **Additional context** Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/custom.md ================================================ --- name: Custom issue template about: Describe this issue template's purpose here. title: '' labels: '' assignees: '' --- ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: '' labels: '' assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .gitignore ================================================ # Created by https://www.toptal.com/developers/gitignore/api/node,macOS # Edit at https://www.toptal.com/developers/gitignore?templates=node,macOS ### macOS ### # General .DS_Store .AppleDouble .LSOverride # Icon must end with two \r Icon # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns .com.apple.timemachine.donotpresent # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk ### macOS Patch ### # iCloud generated files *.icloud ### Node ### # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* lerna-debug.log* .pnpm-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json # Runtime data pids *.pid *.seed *.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage *.lcov # nyc test coverage .nyc_output # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) bower_components # node-waf configuration .lock-wscript # Compiled binary addons (https://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ jspm_packages/ # Snowpack dependency directory (https://snowpack.dev/) web_modules/ # TypeScript cache *.tsbuildinfo # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Optional stylelint cache .stylelintcache # Microbundle cache .rpt2_cache/ .rts2_cache_cjs/ .rts2_cache_es/ .rts2_cache_umd/ # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz # Yarn Integrity file .yarn-integrity # dotenv environment variable files .env .env.development.local .env.test.local .env.production.local .env.local # parcel-bundler cache (https://parceljs.org/) .cache .parcel-cache # Next.js build output .next out # Nuxt.js build / generate output .nuxt dist # Gatsby files .cache/ # Comment in the public line in if your project uses Gatsby and not Next.js # https://nextjs.org/blog/next-9-1#public-directory-support # public # vuepress build output .vuepress/dist # vuepress v2.x temp and cache directory .temp # Docusaurus cache and generated files .docusaurus # Serverless directories .serverless/ # FuseBox cache .fusebox/ # DynamoDB Local files .dynamodb/ # TernJS port file .tern-port # Stores VSCode versions used for testing VSCode extensions .vscode-test # yarn v2 .yarn/cache .yarn/unplugged .yarn/build-state.yml .yarn/install-state.gz .pnp.* ### Node Patch ### # Serverless Webpack directories .webpack/ # Optional stylelint cache # SvelteKit build / generate output .svelte-kit # End of https://www.toptal.com/developers/gitignore/api/node,macOS n lib package-lock.json # for testing packages/core/transmart.config.js examples/**/locales/* !examples/**/locales/en examples/**/_locales/* !examples/**/_locales/en ================================================ FILE: .prettierrc.js ================================================ module.exports = { printWidth: 120, tabWidth: 2, useTabs: false, semi: false, singleQuote: true, quoteProps: 'as-needed', trailingComma: 'all', bracketSpacing: true, arrowParens: 'always', requirePragma: false, insertPragma: false, proseWrap: 'preserve', htmlWhitespaceSensitivity: 'ignore', endOfLine: 'auto', embeddedLanguageFormatting: 'auto', singleAttributePerLine: false } ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to Transmart 1. Fork this repo 2. Clone your forked repo 3. Run it ``` npm install npm run build:watch ``` 4. Make changes, pass linters, push to your repo 5. Create a pull request ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2023 Quill Zhou Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README-zh_CN.md ================================================

Transmart - 利用 AI 自动化您的 i18n

简体中文 | [English](./README.md) ![alt](./assets/record.gif) ![npm](https://img.shields.io/npm/v/@transmart/cli?style=flat-square) [![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?logo=codesandbox)](https://codesandbox.io/p/sandbox/v12-12v2h6?file=%2FREADME.md) Transmart 是一个开源的开发者工具,利用 ChatGPT 实现 i18n 翻译自动化。给定一个基础语言并指定需要输出的所有语言,运行它将生成所有 i18n 区域设置文件。 它由两部分组成:Cli 和 Core。Core 是 Transmart 的 NodeJS 核心实现,而 Cli 是封装了 Core 的命令行工具。在大多数情况下,只使用 Cli 就足够了。 该项目目前正在积极开发中,欢迎 PR,也可以在[Twitter](https://twitter.com/quillzhou)上联系我 ## 特征 - [x] 支持大型文件,不必担心 4096 个标记限制 - [x] 支持使用[Intl.DisplayNames](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames/DisplayNames)显示的所有语言,以及可以通过 ChatGPT 处理的所有语言。 - [x] 支持覆盖 AI 翻译值 - [x] 支持[i18next](https://www.i18next.com/) - [ ] 支持[vue-i18n](https://kazupon.github.io/vue-i18n/) - [x] 支持[Chrome.i18n](https://developer.chrome.com/docs/webstore/i18n/#choosing-locales-to-support) - [x] 支持 Glob 名称空间匹配 - [x] 支持自定义 OpenAI 模型、API 端点 - [ ] 支持自定义区域设置文件结构 - [ ] 支持 iOS - [ ] 支持 Android ## 设置 > Transmart 要求 Node 版本 13 或更高。 ### 1. 安装 要安装 Transmart,请运行: ````sh npm install @transmart/cli -D # or yarn add @transmart/cli ### 2. 项目配置 首先,在项目根目录中创建一个transmart.config.js文件,或任何其他文件格式 `cosmiconfig` 可以搜索到的 transmart.config.js ```js module.exports = { baseLocale: 'en', locales: ['fr', 'jp', 'de'], localePath: 'public/locales', openAIApiKey: 'your-own-openai-api-key', overrides: { 'zh-CN': { common: { create_app: 'Create my Application', }, }, }, } ```` 所有选项可 [参考](#选项) ### 3. 翻译。 向您的 npm 脚本添加 transmart 命 令 ```json { "translate": "transmart" } ``` 然后执行 ```sh npm run translate ``` 或者您可以在命令行中直接使用 npx 前缀执行 ```sh npx transmart ``` 如果对 AI 翻译的结果不满意,请使用 [overrides](#选项) 选项部分覆盖生成的 JSON 享受 i18n 吧 🎉🎉 ## 选项 | 名称 | 类型 | 描述 | 是否必须 | | ---------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------ | :------: | | baseLocale | string | Transmart 将用作翻译参考的语言。 | 是 | | locales | string[] | 所有需要翻译的语言 | 是 | | localePath | string | 存储国际化文件的位置 | 是 | | openAIApiKey | string | OpenAI API 密钥 | 是 | | context | string | 提供一些上下文让翻译更准确 | 否 | | openAIApiModel | string | OpenAI API 模型,默认为“gpt-3.5-turbo-16k-0613” | 否 | | overrides | `Record>>` | 如果你不满意 AI 翻译结果,用于部分覆盖生成的 JSON (locale-namespace-key:value) | 否 | | namespaceGlob | string\|string[] | 命名空间匹配项 | 否 | | openAIApiUrl | string | 可选基本 OpenAI API url 地址,在使用代理时很有用 | 否 | | openAIApiUrlPath | string | 可选的 OpenAI API url 地址, 在使用代理时很有用 | 否 | | | ## 贡献 要贡献到 Transmart,请参阅[contributing.md](./CONTRIBUTING.md) ## 受以下启发 - https://chatgpt-i18n.vercel.app/ - https://twitter.com/forgebitz/status/1634100746617597955 - https://github.com/yetone/openai-translator ================================================ FILE: README.md ================================================

Transmart - Automate your i18n localization with AI.

English | [简体中文](./README-zh_CN.md) ![alt](./assets/record.gif) ![npm](https://img.shields.io/npm/v/@transmart/cli?style=flat-square) [![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?logo=codesandbox)](https://codesandbox.io/p/sandbox/v12-12v2h6?file=%2FREADME.md) Transmart is an open-source developer tool that utilizes ChatGPT to automate i18n translation. Given a base language and specifying all the languages that need to be output, running it will generate all i18n locale files. It consists of two parts: Cli and Core. Core is the NodeJS core implementation of Transmart, while Cli is a command-line tool that encapsulates Core. In most cases, only Cli is used. This project is currently under active development,PRs are welcome,reach me at [Twitter](https://twitter.com/quillzhou) ## Features - [x] Supports large size files,don't worry about the 4096 tokens limit - [x] Supports all languages that can be displayed using [Intl.DisplayNames](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames/DisplayNames) and can be processed by ChatGPT. - [x] Supports override AI translated values - [x] Supports [i18next](https://www.i18next.com/) - [ ] Supports [vue-i18n](https://kazupon.github.io/vue-i18n/) - [x] Supports [Chrome.i18n](https://developer.chrome.com/docs/webstore/i18n/#choosing-locales-to-support) - [x] Supports Glob namespace matching - [x] Supports customizing OpenAI Model、API endpoint - [ ] Supports custom locale file structure - [ ] Supports iOS - [ ] Supports Android ## Setup > Transmart requires Node version 13 or higher. ### 1. Installation To install Transmart, run: ```sh npm install @transmart/cli -D # or yarn add @transmart/cli ``` ### 2. Project setup First, create a transmart.config.js file in the root of your project. or any others file format [cosmiconfig](https://www.npmjs.com/package/cosmiconfig?activeTab=readme) can search for `transmart.config.js` ```js module.exports = { baseLocale: 'en', locales: ['fr', 'jp', 'de'], localePath: 'public/locales', openAIApiKey: 'your-own-openai-api-key', overrides: { 'zh-CN': { common: { create_app: 'Create my Application', }, }, }, } ``` All Options [Reference](#options) ### 3. Translate. Add transmart command to your npm scripts ```sh { "translate": "transmart" } ``` And then execute ```sh npm run translate ``` Or you can execute directly with `npx` prefix in command line ``` npx transmart ``` If you are not satisfied with the result of AI translation,use [`overrides`](#options) option to overwrite the generated JSON partially 🎉🎉 Enjoy i18n ## Examples - [next.js](./examples/next.js) - [chrome extension](./examples/chrome-extension/) ## Options | Name | Type | Description | Required | |-------------------------|------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| :------: | | baseLocale | string | The language that Transmart will use as translation ref. | Yes | | locales | string[] | All languages that need to be translated | Yes | | localePath | string | Where you store your locale files | Yes | | openAIApiKey | string | The OpenAI API Key. | Yes | | context | string | Provide some context for a more accurate translation. | No | | openAIApiModel | string | OpenAI API model, default to `gpt-3.5-turbo-16k-0613` | No | | overrides | `Record>>` | used to overwrite the generated JSON if you are not satisfied with the result of AI translation (locale-namespace-key:value) | No | | namespaceGlob | string\|string[] | Glob for namespace(s) to process, useful to include or exclude some files, learn more [glob](https://www.npmjs.com/package/glob#usage) | No | | openAIApiUrl | string | Optional base url of OpenAI API, useful with proxy | No | | openAIApiUrlPath | string | Optional URL endpoint of OpenAI API, useful with proxy | No | | modelContextLimit | number | Optional max context window that the model supports. For example for gpt-4-32k, the context is 32768 tokens. Default to 4096 (gpt-3.5-turbo) | No | | modelContextSplit | number | Optional ratio to split between number of input / output tokens. For example, if the input language is English and output is Spanish, you may expect 1 input token to produce 2 output tokens. In this case, the variable is set to 1/2. By default, modelContextSplit is set to 1/1 | No | | systemPromptTemplate | function | (For advanced usage) Custom prompt template. See "translate.ts" for the default prompt. | No | | additionalReqBodyParams | any | (For advanced usage) Custom parameters to be passed into request body. Useful if you use a self-hosted model and you want to customize model parameters. For example, see [llama.cpp server example](https://github.com/ggerganov/llama.cpp/tree/master/examples/server) | No | | singleFileMode | boolean | singleFileMode will use a single file for all namespaces. For example, if you have a single file `en.json` and you want to translate it to `zh.json`, you can set `singleFileMode` to true. This will translate it to `zh.json` . In this mode, the `namespace` will be ignored and set to `app`. | No | ## Contributing To contribute to Transmart,refer to [contributing.md](./CONTRIBUTING.md) ## Inspired by - https://chatgpt-i18n.vercel.app/ - https://twitter.com/forgebitz/status/1634100746617597955 - https://github.com/yetone/openai-translator ================================================ FILE: commitlint.config.js ================================================ module.exports = { extends: ['@commitlint/config-conventional'], } ================================================ FILE: examples/README.md ================================================ This Folder contain All examples using transmart Since we need to use the OpenAI API key, we need to load it into the environment variable. Run in root of the transmart project ```sh cp .env.example .env ``` Please enter your API key and API proxy URL (the latter is optional). ```sh source .env ``` ================================================ FILE: examples/chrome-extension/README.md ================================================ ================================================ FILE: examples/chrome-extension/_locales/en/messages.json ================================================ { "name": { "message": "News Reader", "description": "Extension name in manifest." }, "description": { "message": "Displays the first 5 items from the '$Google$ News - top news' RSS feed in a popup.", "description": "Extension description in manifest.", "placeholders": { "google": { "content": "Google", "example": "Google" } } }, "default_title": { "message": "$Google$ News", "description": "Extension browser action tooltip text in manifest.", "placeholders": { "google": { "content": "Google", "example": "Google" } } }, "unknown_title": { "message": "Unknown title", "description": "Unknown news title." }, "error": { "message": "Error: $error$", "description": "Generic error template. Expects error parameter to be passed in.", "placeholders": { "error": { "content": "$1", "example": "Failed to fetch RSS feed." } } }, "failed_to_fetch_rss": { "message": "Failed to fetch RSS feed.", "description": "User visible error message." }, "not_a_valid_feed": { "message": "Not a valid feed.", "description": "User visible error message." }, "more_stories": { "message": "To $Google$ News \u00BB", "description": "Link name to more Google News.", "placeholders": { "google": { "content": "Google", "example": "Google" } } }, "newsUrl": { "message": "http://news.google.com", "description": "Url to Google News." } } ================================================ FILE: examples/chrome-extension/feed.html ================================================
================================================ FILE: examples/chrome-extension/manifest.json ================================================ { "name": "__MSG_name__", "version": "1.1", "description": "__MSG_description__", "icons": { "128": "news_icon.png" }, "browser_action": { "default_title": "__MSG_default_title__", "default_icon": "news_action.png", "default_popup": "feed.html" }, "permissions": [ "tabs", "http://news.google.com/*", "http://news.google.es/*" ], "default_locale": "en" } ================================================ FILE: examples/chrome-extension/package.json ================================================ { "name": "chrome-extension", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "translate": "transmart" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@transmart/cli": "^0.0.3" } } ================================================ FILE: examples/chrome-extension/transmart.config.js ================================================ // eslint-disable-next-line @typescript-eslint/no-var-requires module.exports = { baseLocale: 'en', locales: ['zh_CN', 'pt_BR', 'es_419'], localePath: '_locales', openAIApiKey: process.env.OPENAI_API_KEY, openAIApiUrl: process.env.OPENAI_API_URL, } ================================================ FILE: examples/next.js/@types/i18next.d.ts ================================================ /** * If you want to enable locale keys typechecking and enhance IDE experience. * * Requires `resolveJsonModule:true` in your tsconfig.json. * * @link https://www.i18next.com/overview/typescript */ import 'i18next' import type common from '../public/locales/en/common.json' import type footer from '../public/locales/en/footer.json' import type secondPage from '../public/locales/en/second-page.json' interface I18nNamespaces { common: typeof common footer: typeof footer 'second-page': typeof secondPage } declare module 'i18next' { interface CustomTypeOptions { defaultNS: 'common' resources: I18nNamespaces } } ================================================ FILE: examples/next.js/components/Footer.tsx ================================================ import pkg from 'next-i18next/package.json' import { useTranslation, Trans } from 'next-i18next' import type { FC } from 'react' export const Footer: FC = () => { const { t } = useTranslation('footer') return (

{t('description')}

next-i18next v{pkg.version}

With using locize you directly support the future of i18next .

) } ================================================ FILE: examples/next.js/components/Header.tsx ================================================ import Head from 'next/head' import type { FC } from 'react' type Props = { heading: string title: string } export const Header: FC = ({ heading, title }) => ( <> {title}

next-i18next

{heading}

) ================================================ FILE: examples/next.js/next-env.d.ts ================================================ /// /// // NOTE: This file should not be edited // see https://nextjs.org/docs/basic-features/typescript for more information. ================================================ FILE: examples/next.js/next-i18next.config.js ================================================ // @ts-check /** * @type {import('next-i18next').UserConfig} */ module.exports = { // https://www.i18next.com/overview/configuration-options#logging debug: process.env.NODE_ENV === 'development', i18n: { defaultLocale: 'en', locales: ['en', 'de', 'fr', 'es', 'zh', 'ja', 'ko', 'pt', 'it', 'ru'], }, /** To avoid issues when deploying to some paas (vercel...) */ localePath: typeof window === 'undefined' ? require('path').resolve('./public/locales') : '/locales', reloadOnPrerender: process.env.NODE_ENV === 'development', /** * @link https://github.com/i18next/next-i18next#6-advanced-configuration */ // saveMissing: false, // strictMode: true, // serializeConfig: false, // react: { useSuspense: false } } ================================================ FILE: examples/next.js/next-utils.config.js ================================================ 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, } ================================================ FILE: examples/next.js/next.config.js ================================================ // @ts-check const { i18n } = require('./next-i18next.config.js') // You can remove the following 2 lines when integrating our example. const { loadCustomBuildParams } = require('./next-utils.config') const { esmExternals = false, tsconfigPath } = loadCustomBuildParams() /** @type {import('next').NextConfig} */ const nextConfig = { experimental: { esmExternals, // https://nextjs.org/blog/next-11-1#es-modules-support }, i18n, reactStrictMode: true, typescript: { tsconfigPath, }, } module.exports = nextConfig ================================================ FILE: examples/next.js/package.json ================================================ { "name": "v12", "version": "1.0.0", "main": "index.js", "license": "MIT", "scripts": { "dev": "next", "build": "next build", "start": "next start -p ${PORT:=3000}", "typecheck": "tsc --project ./tsconfig.json --noEmit", "clean": "rimraf .next", "translate": "transmart", "nuke:install": "rimraf ./node_modules ./package-lock.json" }, "dependencies": { "@transmart/cli": "^0.0.3", "i18next": "^22.4.11", "next": "^13.2.4", "next-i18next": "^13.2.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-i18next": "^12.2.0" }, "devDependencies": { "@types/node": "^18.15.0", "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "eslint-config-next": "^13.2.4", "picocolors": "^1.0.0", "rimraf": "^4.4.0", "typescript": "^4.9.5" } } ================================================ FILE: examples/next.js/pages/_app.tsx ================================================ import type { AppProps } from 'next/app' import { appWithTranslation } from 'next-i18next' // import nextI18NextConfig from '../next-i18next.config.js' const MyApp = ({ Component, pageProps }: AppProps) => ( ) // https://github.com/i18next/next-i18next#unserializable-configs export default appWithTranslation(MyApp /*, nextI18NextConfig */) ================================================ FILE: examples/next.js/pages/_document.tsx ================================================ import Document, { Html, Head, Main, NextScript, } from 'next/document' import type { DocumentProps } from 'next/document' import i18nextConfig from '../next-i18next.config' type Props = DocumentProps & { // add custom document props } class MyDocument extends Document { render() { const currentLocale = this.props.__NEXT_DATA__.locale ?? i18nextConfig.i18n.defaultLocale return (
) } } export default MyDocument ================================================ FILE: examples/next.js/pages/index.tsx ================================================ import Link from 'next/link' import { useRouter } from 'next/router' import type { GetStaticProps, InferGetStaticPropsType, GetServerSideProps } from 'next' import { useTranslation, Trans } from 'next-i18next' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import { Header } from '../components/Header' import { Footer } from '../components/Footer' type Props = { // Add custom props here } const Homepage = (_props: InferGetStaticPropsType) => { const router = useRouter() const { t } = useTranslation('common') const { changeTo } = _props // eslint-disable-next-line @typescript-eslint/no-unused-vars const onToggleLanguageClick = (newLocale: string) => { const { pathname, asPath, query } = router router.push({ pathname, query }, asPath, { locale: newLocale }) } return ( <>

{t('blog.appDir.question')}

Then check out this blog post.

{t('blog.optimized.question')}

Then you may have a look at this blog post.

{t('blog.ssg.question')}

Then you may have a look at this blog post.


{/* alternative language change without using Link component */}