-
Notifications
You must be signed in to change notification settings - Fork 148
Add i18n in Zetachain docs #765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
50f8aca
d514372
ea0314f
79bf011
e79c210
1ab3a06
79fa940
951289d
d4d2b06
10b88c9
b992e74
23f3ca6
b82bd39
cc99375
52a1ca4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,40 @@ | ||||||
| ## work repoter | ||||||
|
|
||||||
| I am try to reading the nextra/next.js & i18n official docs to add a touch-down button on zetachain docs. Help users can click to switch en & zh, and other languages. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve awkward phrasing. Line 3 contains ungrammatical text. Revise for clarity and correctness. -I am try to reading the nextra/next.js & i18n official docs to add a touch-down button on zetachain docs. Help users can click to switch en & zh, and other languages.
+I am trying to read the Nextra/Next.js & i18n official documentation to add a language-switch button to the ZetaChain docs, enabling users to switch between English & Chinese, and potentially other languages.📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
|
|
||||||
| ### reading | ||||||
| - https://github.com/shuding/nextra/blob/main/packages/nextra-theme-docs/src/components/locale-switch.tsx | ||||||
| - https://nextra-v2-oe0zrpzjp-shud.vercel.app/docs/guide/i18n | ||||||
|
|
||||||
| denis dev a demo to help me understand how i18n work, I have been read. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clarify awkward phrasing. Line 9 would be clearer if revised. -denis dev a demo to help me understand how i18n work, I have been read.
+Denis created a demo to help me understand how i18n works; I have reviewed it.📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
|
|
||||||
| - https://docs-v2-git-feat-i18n.zetachain.app/start/app | ||||||
| - https://docs-v2-git-feat-i18n.zetachain.app/zh-CN/start/app | ||||||
|
|
||||||
| ### developing | ||||||
| [2025.11.19 09:29] I have been modify `next.config.js` and `/src/theme.config.tsx` to add i18n languages switch feature. testing in cloud server always downtime, so I use my local pc try again. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve grammar in timestamp entry. Line 15 contains grammatical issues. Consider revising for clarity. -[2025.11.19 09:29] I have been modify `next.config.js` and `/src/theme.config.tsx` to add i18n languages switch feature. testing in cloud server always downtime, so I use my local pc try again.
+[2025.11.19 09:29] I modified `next.config.js` and `/src/theme.config.tsx` to add i18n language-switch features. Cloud server testing was consistently unavailable, so I tested locally on my machine instead.📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
|
|
||||||
| [2025.11.19 15:15] in macmini is successfully add i18n. I match the en & zh pages: | ||||||
|
|
||||||
| - [x] about | ||||||
| - [x] developers | ||||||
| - [x] nodes | ||||||
| - [x] reference | ||||||
| - [x] start | ||||||
| - [x] users | ||||||
|
|
||||||
| I add the nextra LocaleSwitch to switch languages, now is support en & zh. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve sentence structure and capitalization. Line 26 would benefit from clearer phrasing and proper capitalization. -I add the nextra LocaleSwitch to switch languages, now is support en & zh.
+I added the Nextra LocaleSwitch component to enable language switching; English (en-US) and Chinese (zh-CN) are now supported.📝 Committable suggestion
Suggested change
🧰 Tools🪛 LanguageTool[grammar] ~26-~26: Ensure spelling is correct (QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1) 🤖 Prompt for AI Agents |
||||||
|
|
||||||
| in `src` add the new file `middleware.js`, will help to match the files path. | ||||||
|
|
||||||
| every english docs is named `xxx.en-US`, every chinese docs is named `xxx.zh-CN`. | ||||||
|
|
||||||
| but now have three questions in this branch. | ||||||
|
|
||||||
| 1. <del>the sidebar is not turn with the language switch</del> | ||||||
| 2. <del>when user click someone page, the sidebar is not highlight.</del> | ||||||
| 3. in nextra setting, `index.en-US` or `index.zh-CN` will be redirect to the father path, but the true path is the children. such as view `http://localhost:3001/zh-CN/developers/evm` is 404 not found. I am check the problem, but need some times. | ||||||
|
|
||||||
| [2025.11.21 10:29] I solve the sidebar highlight issue, add a path compare tool `router.ts` in `src/lib/helpers`. the router.pathname is different from page.route, so need a tool to remove the prefix for locale and make a standard router format. | ||||||
|
|
||||||
| [2025.11.21 12:56] I solve the sidebar en & zh switch, and make sure the folders and files name is true. | ||||||
|
Comment on lines
+38
to
+40
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve grammar and technical terminology in progress notes. Lines 38–40 contain grammatical issues and could be more precise. Consider revising for consistency with other professional documentation. -[2025.11.21 10:29] I solve the sidebar highlight issue, add a path compare tool `router.ts` in `src/lib/helpers`. the router.pathname is different from page.route, so need a tool to remove the prefix for locale and make a standard router format.
+[2025.11.21 10:29] I resolved the sidebar highlight issue by adding a path normalization utility (`router.ts`) in `src/lib/helpers`. The `router.pathname` differs from `page.route`, so the utility removes the locale prefix to standardize the router format.-[2025.11.21 12:56] I solve the sidebar en & zh switch, and make sure the folders and files name is true.
+[2025.11.21 12:56] I resolved the sidebar language switching for both English and Chinese, and verified that folder and file naming conventions are correct.🤖 Prompt for AI Agents |
||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,5 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { ListItem } from "@mui/material"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { isPathStartWith, normalizePath } from "~/lib/helpers/router"; //导入工具函数 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import clsx from "clsx"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useRouter } from "next/router"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { createElement, useMemo } from "react"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -21,17 +22,30 @@ export const NavigationItem = ({ item, isOpen, withLabel = true, onClick }: Navi | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const router = useRouter(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // const isSelected = useMemo(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // if (!url) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // if (router.pathname === "/" || url === "/") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // return url === router.pathname; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // return router.pathname.startsWith(url); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // }, [url, router.pathname]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const isSelected = useMemo(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!url) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (router.pathname === "/" || url === "/") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return url === router.pathname; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const currentPath = router.asPath || router.pathname; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (currentPath === "/" || url === "/") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return normalizePath(currentPath) === normalizePath(url); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return router.pathname.startsWith(url); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, [url, router.pathname]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return isPathStartWith(currentPath, url, router); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, [url, router.asPath, router.pathname, router]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
36
to
+48
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix formatting issues and approve locale-aware navigation logic. The new logic correctly handles locale-aware path matching using the introduced helper functions. However, there are formatting issues that need to be addressed. Apply this diff to fix the ESLint prettier formatting errors: const isSelected = useMemo(() => {
if (!url) {
return false;
}
-
+
const currentPath = router.asPath || router.pathname;
-
+
if (currentPath === "/" || url === "/") {
return normalizePath(currentPath) === normalizePath(url);
}
-
+
return isPathStartWith(currentPath, url, router);
}, [url, router.asPath, router.pathname, router]);📝 Committable suggestion
Suggested change
🧰 Tools🪛 ESLint[error] 40-40: Delete (prettier/prettier) [error] 42-42: Delete (prettier/prettier) [error] 46-46: Delete (prettier/prettier) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <ListItem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,26 +1,164 @@ | ||
| // import { getAllPages } from "nextra/context"; | ||
| // import { useEffect, useMemo } from "react"; | ||
| // import { useRouter } from "next/router"; | ||
| // import { useAppDispatch } from "../lib/app.store"; | ||
| // import { setDirectories, setPages } from "../lib/directories/directories.redux"; | ||
| // import { getDirectories } from "../lib/helpers/nextra"; | ||
|
|
||
| // export const useSetDirectoriesState = () => { | ||
| // const allPages = getAllPages(); | ||
| // const router = useRouter(); | ||
| // // ✅ 临时日志:查看页面结构 | ||
| // if (allPages.length > 0) { | ||
| // console.log('🔵 getAllPages() 返回的页面:', allPages[7]); | ||
| // } | ||
| // const { flatDirectories, directoriesByRoute } = useMemo(() => getDirectories(allPages), [allPages]); | ||
|
|
||
| // const dispatch = useAppDispatch(); | ||
|
|
||
| // useEffect(() => { | ||
| // if (!allPages.length) return; | ||
|
|
||
| // dispatch(setPages(allPages)); | ||
| // }, [allPages]); | ||
|
|
||
| // useEffect(() => { | ||
| // if (!flatDirectories.length || !directoriesByRoute) return; | ||
|
|
||
| // dispatch(setDirectories({ flatDirectories, directoriesByRoute })); | ||
| // }, [flatDirectories, directoriesByRoute]); | ||
| // }; | ||
| import { getAllPages } from "nextra/context"; | ||
| import { useRouter } from "next/router"; | ||
| import { useEffect, useMemo } from "react"; | ||
|
|
||
| import { useAppDispatch } from "../lib/app.store"; | ||
| import { setDirectories, setPages } from "../lib/directories/directories.redux"; | ||
| import { getDirectories } from "../lib/helpers/nextra"; | ||
|
Comment on lines
+1
to
37
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain清理注释实现并修复 ESLint/Prettier/import-sort 报错
建议:
Also applies to: 66-71, 145-148, 159-164 Length of output: 2150 🏁 Script executed: #!/bin/bash
# Check for linting configuration files and relevant eslint/prettier rules
echo "=== Checking for linting configuration: ==="
ls -la | grep -E "(eslint|prettier)" || echo "No ESLint/Prettier files in root"
echo ""
find . -maxdepth 2 -name ".eslintrc*" -o -name "prettier.config.*" -o -name ".prettierrc*" 2>/dev/null | head -10
echo ""
echo "=== Checking package.json for lint scripts: ==="
if [ -f "package.json" ]; then
cat package.json | grep -A 5 '"scripts"' | head -15
fiLength of output: 840 🏁 Script executed: #!/bin/bash
# Search for commented import statements and old implementations in the file
echo "=== Checking for commented code patterns: ==="
rg -n "^\s*//\s*(import|export|const|function|useEffect|useMemo)" src/hooks/useSetDirectoriesState.ts || echo "No commented code patterns found"Length of output: 777 🏁 Script executed: #!/bin/bash
# Verify import sort order and formatting issues at line 1-37
echo "=== Full content with line numbers (lines 1-50): ==="
sed -n '1,50p' src/hooks/useSetDirectoriesState.ts | cat -nLength of output: 2198 Remove dead code blocks to eliminate unnecessary noise and maintenance burden. The extensive commented implementation (lines 1–30) along with additional commented hooks (lines 43, 138) should be deleted entirely. These represent obsolete code that has been superseded by the active implementation and serve only to obscure readability. The imports are already correctly ordered and formatted. No refactoring of import statements or broader formatting passes are required. Action: Delete lines 1–30 and any other commented implementation blocks (e.g., lines 43, 138) to keep the file clean and maintainable. 🧰 Tools🪛 ESLint[error] 31-37: Run autofix to sort these imports! (simple-import-sort/imports) 🤖 Prompt for AI Agents |
||
|
|
||
| export const useSetDirectoriesState = () => { | ||
| const allPages = getAllPages(); | ||
| const router = useRouter(); // 添加这一行获取当前 locale | ||
| const allPages = getAllPages(); | ||
|
|
||
| // useEffect(() => { | ||
| // if (allPages.length > 0) { | ||
| // console.log('🔵 第一个页面对象结构:', { | ||
| // route: allPages[0].route, | ||
| // locale: (allPages[0] as any).locale, | ||
| // name: (allPages[0] as any).name, | ||
| // kind: allPages[0].kind, | ||
| // }); | ||
| // // 打印前几个页面的详细信息 | ||
| // allPages.slice(0, 3).forEach((page, idx) => { | ||
| // console.log(`🔵 页面 ${idx}:`, { | ||
| // route: page.route, | ||
| // locale: (page as any).locale, | ||
| // name: (page as any).name, | ||
| // kind: page.kind, | ||
| // }); | ||
| // }); | ||
| // } | ||
| // }, [allPages]); | ||
|
|
||
| // 从文件名或 route 中提取 locale | ||
| const extractLocaleFromPage = (page: typeof allPages[0]): string | null => { | ||
| // 方法 1: 从 page.locale 属性获取(如果存在) | ||
| if ('locale' in page && (page as any).locale) { | ||
| return (page as any).locale; | ||
| } | ||
|
|
||
| // 方法 2: 从 page.name 中提取(例如 "index.zh-CN" -> "zh-CN") | ||
| if ('name' in page && (page as any).name) { | ||
| const name = (page as any).name as string; | ||
| const match = name.match(/\.(en-US|zh-CN)(\.|$)/); | ||
| if (match) { | ||
| return match[1]; | ||
| } | ||
| } | ||
|
|
||
| // 方法 3: 从 route 中提取(例如 "/zh-CN/developers/evm" -> "zh-CN") | ||
| if (page.route) { | ||
| const routeMatch = page.route.match(/\/(en-US|zh-CN)(\/|$)/); | ||
| if (routeMatch) { | ||
| return routeMatch[1]; | ||
| } | ||
| } | ||
|
|
||
| // 如果没有找到 locale,返回 null(可能是默认语言或无 locale 的页面) | ||
| return null; | ||
| }; | ||
|
|
||
| // 新增过滤逻辑(替换原来的日志代码) | ||
| // 根据当前 locale 过滤页面,避免显示重复内容 | ||
| const filteredPages = useMemo(() => { | ||
| if (!router.locale || !allPages.length) return allPages; | ||
|
|
||
| // 过滤函数:根据 locale 属性过滤页面 | ||
| const filterByLocale = (pages: typeof allPages, targetLocale: string): typeof allPages => { | ||
| return pages | ||
| .map((page) => { | ||
| if (page.kind === "Folder" && "children" in page) { | ||
| // 递归过滤子页面 | ||
| const filteredChildren = filterByLocale(page.children, targetLocale); | ||
|
|
||
| // 如果过滤后没有子页面,不显示这个文件夹 | ||
| if (filteredChildren.length === 0) return null; | ||
|
|
||
| return { | ||
| ...page, | ||
| children: filteredChildren, | ||
| }; | ||
| } else { | ||
| // 从页面对象中提取 locale | ||
| const pageLocale = extractLocaleFromPage(page); | ||
|
|
||
| // 如果页面有明确的 locale 属性 | ||
| if (pageLocale) { | ||
| // 如果匹配目标 locale,保留它 | ||
| return pageLocale === targetLocale ? page : null; | ||
| } | ||
|
|
||
| // 如果页面没有 locale 属性: | ||
| // - 如果目标是默认语言,保留它(默认语言的页面可能没有 locale 后缀) | ||
| // - 如果目标不是默认语言,过滤掉它(没有 locale 后缀的页面应该只在默认语言时显示) | ||
| if (targetLocale === router.defaultLocale) { | ||
| return page; | ||
| } | ||
|
|
||
| // 非默认语言时,没有 locale 的页面应该被过滤掉 | ||
| return null; | ||
| } | ||
| }) | ||
| .filter((page): page is typeof allPages[0] => page !== null); | ||
| }; | ||
|
|
||
| return filterByLocale(allPages, router.locale); | ||
| }, [allPages, router.locale, router.defaultLocale]); | ||
|
|
||
| const { flatDirectories, directoriesByRoute } = useMemo(() => getDirectories(allPages), [allPages]); | ||
| // useEffect(() => { | ||
| // console.log('🔵 当前 locale:', router.locale); | ||
| // console.log('🔵 所有页面数量:', allPages.length); | ||
| // console.log('🔵 过滤后页面数量:', filteredPages.length); | ||
| // console.log('🔵 过滤后的第一个页面:', filteredPages[0]?.route, (filteredPages[0] as any)?.locale); | ||
| // }, [router.locale, allPages.length, filteredPages.length]); | ||
| // 使用 filteredPages 而不是 allPages | ||
| const { flatDirectories, directoriesByRoute } = useMemo( | ||
| () => getDirectories(filteredPages), | ||
| [filteredPages] | ||
| ); | ||
|
|
||
| const dispatch = useAppDispatch(); | ||
|
|
||
| // 使用 filteredPages 而不是 allPages | ||
| useEffect(() => { | ||
| if (!allPages.length) return; | ||
| if (!filteredPages.length) return; | ||
|
|
||
| dispatch(setPages(allPages)); | ||
| }, [allPages]); | ||
| dispatch(setPages(filteredPages)); | ||
| }, [filteredPages, dispatch]); | ||
|
|
||
| useEffect(() => { | ||
| if (!flatDirectories.length || !directoriesByRoute) return; | ||
|
|
||
| dispatch(setDirectories({ flatDirectories, directoriesByRoute })); | ||
| }, [flatDirectories, directoriesByRoute]); | ||
| }; | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix typo in title.
Line 1 contains a spelling error: "repoter" should be "reporter".
🧰 Tools
🪛 LanguageTool
[grammar] ~1-~1: Ensure spelling is correct
Context: ## work repoter I am try to reading the nextra/next.js &...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents