Conversation
✅ Deploy Preview for tools-aiwan-run ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a locale-aware BIP-39 mnemonic generator and supporting wordlist modules, re-exports for main routing, sitemap builder consolidation, UI/SEO/showcase updates, new translations, and a dependency on Changes
sequenceDiagram
participant User as User
participant Page as Mnemonic Page
participant Wordlist as Wordlist Loader
participant Validator as BIP39 Validator
participant Derivation as Seed Derivation
User->>Page: Select wordlist & word count
Page->>Wordlist: Load selected wordlist
Wordlist-->>Page: Return words
User->>Page: Enter or generate mnemonic
Page->>Validator: Validate phrase + checksum
Validator-->>Page: Valid/Invalid & checksum bits
alt valid
Page->>Derivation: Compute entropy & PBKDF2 seed
Derivation-->>Page: Entropy hex & seed hex
Page-->>User: Show results (seed masked/unmasked)
else invalid
Page-->>User: Show validation error
end
User->>Page: Copy action (mnemonic/entropy/seed)
Page-->>User: Clipboard confirmation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (3)
src/app/sitemap-shared.ts (1)
26-32: Consider differentiating priority values between root and tool pages.Setting
priority: 1for all entries (root and tools) may not be optimal for SEO. Typically, the homepage should have priority 1.0, while subpages have lower values (e.g., 0.8).♻️ Suggested improvement
{ url: baseUrl, lastModified, changeFrequency: 'weekly', priority: 1, }, ...TOOL_SITEMAP_PATHS.map((path) => ({ url: `${baseUrl}/${path}`, lastModified, changeFrequency: 'weekly' as const, - priority: 1, + priority: 0.8, })),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/sitemap-shared.ts` around lines 26 - 32, The sitemap currently sets priority: 1 for both the root entry and all tool pages; update the tool entries created in the TOOL_SITEMAP_PATHS.map callback to use a lower priority (e.g., 0.8) while leaving the root entry at 1.0—locate the mapping that builds entries with url: `${baseUrl}/${path}`, lastModified and changeFrequency, and change priority: 1 to priority: 0.8 for those tool pages so the homepage remains highest priority.src/app/(locale)/[locale]/mnemonic/wordlists.ts (1)
1-10: Split the wordlist metadata from the actual wordlist payloads.
src/app/(locale)/[locale]/mnemonic/page.tsx:20-25imports this module from a client component, so the eager imports on Line 1-Line 10 and the staticWORDLISTSmap on Line 69-Line 80 put every official 2048-word list on the client path. That is a lot of mostly-unused text for the default English case; dynamically loading the selected list would keep this route much lighter.Also applies to: 69-80
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`(locale)/[locale]/mnemonic/wordlists.ts around lines 1 - 10, The module currently eagerly imports every 2048-word payload (e.g., the imports like englishWordlist, frenchWordlist and the static WORDLISTS map), which causes all lists to be bundled into the client; change this file to export only small metadata (language keys, display names) and replace the static WORDLISTS payload map with an async loader function (e.g., export async function loadWordlist(lang: string)) that performs dynamic imports (import('.../english.js') / import('./traditional-chinese-wordlist') etc.) and returns the payload, leaving only light-weight metadata exported (rename WORDLISTS -> WORDLIST_META or similar) and removing the top-level imports such as englishWordlist/traditionalChineseWordlist so the actual wordlists are loaded on demand.src/app/(locale)/[locale]/mnemonic/traditional-chinese-wordlist.ts (1)
1-2: Avoid reaching intonode_moduleswith a relative path.Line 2 is coupled to the current folder depth and a physical
node_moduleslayout, so a file move or a different package-manager topology can break resolution. If the upstream exports map is wrong, a local vendored copy or a small dependency patch is safer than importing../../../../../node_modules/...directly.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`(locale)/[locale]/mnemonic/traditional-chinese-wordlist.ts around lines 1 - 2, The file currently re-exports wordlist by reaching into node_modules which is brittle; instead vendor a local copy or shim and re-export that. Create a local module (e.g., traditional-chinese.ts or traditional-chinese-wordlist-vendored.ts) that contains/export the same `wordlist` data from `@scure/bip39`, commit it into the repo, and update the export in `traditional-chinese-wordlist.ts` to `export { wordlist } from './traditional-chinese'` (removing the ../../../../../node_modules path); alternatively apply a small dependency patch that fixes the package exports and then import via the package name, but do not reference node_modules with a relative path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/`(locale)/[locale]/mnemonic/page.tsx:
- Around line 244-269: The Textarea components rendering mnemonic and other
read-only outputs (the Textarea with value={mnemonic} and onChange={(event) =>
setMnemonic(event.target.value)} and the two other Textarea instances further
down) lack accessible names; add either a visible <label> tied via htmlFor to
the Textarea id or add aria-label / aria-labelledby attributes to each Textarea
so screen readers get a descriptive name (e.g., "Mnemonic phrase", "Seed hex",
"Derived address"); ensure the id/aria-labelledby references match the Textarea
props and update any CopyButton usage to reference the same label if needed for
context.
In `@src/app/`(locale)/[locale]/sitemap.ts:
- Around line 12-15: The sitemap function currently hardcodes the locale
(`/zh`); change sitemap to accept route params and derive the locale dynamically
(e.g., export default async function sitemap({ params }: { params: { locale:
string } }) ) and build the baseUrl with
`${baseUrlWithoutLocale}/${params.locale}` instead of `/zh`, then call
buildToolSitemap(baseUrl); this ensures the sitemap uses the locale provided by
the route (see sitemap, params.locale, baseUrlWithoutLocale, and
buildToolSitemap).
In `@src/constants.ts`:
- Line 29: Replace the English string 'mnemonic generator' used inside the isZh
branches with a Chinese localized term (e.g., "助记词生成器") in both occurrences in
src/constants.ts; locate the two places that check isZh and currently emit
'mnemonic generator' and update those array entries so the metadata/SEO uses the
Chinese text consistently.
In `@src/locales/en/messages.po`:
- Around line 151-161: The English PO catalog contains unresolved merge markers
(e.g., msgid "Error" and msgid "Generate" have msgstr values like "<<<<<<< HEAD"
or ">>>>>>> origin/main"); open src/locales/en/messages.po, search for merge
markers (<<<<<<<, =======, >>>>>>>) and resolve each conflict by choosing or
reconstructing the correct msgstr for the corresponding msgid (examples:
"Error", "Generate" and other msgids reported), remove all conflict markers,
ensure msgstr entries are valid UTF-8 strings, and run any localization
build/validation to confirm no remaining conflicts.
In `@src/locales/zh/messages.po`:
- Around line 429-452: The PO catalog contains leftover merge markers in several
msgstr entries (search for the msgid texts "This is the raw secret entropy
behind the mnemonic.", "transform base64 data to png", "Underscore", and "Valid
BIP-39 mnemonic.")—clean each corresponding msgstr by removing conflict markers
like <<<<<<<, =======, >>>>>>> and reconcile the correct Chinese translation (or
re-translate if uncertain) so the msgstr contains only the final localized
string; ensure no extraneous whitespace or markers remain and run a PO
syntax/validation check after editing.
---
Nitpick comments:
In `@src/app/`(locale)/[locale]/mnemonic/traditional-chinese-wordlist.ts:
- Around line 1-2: The file currently re-exports wordlist by reaching into
node_modules which is brittle; instead vendor a local copy or shim and re-export
that. Create a local module (e.g., traditional-chinese.ts or
traditional-chinese-wordlist-vendored.ts) that contains/export the same
`wordlist` data from `@scure/bip39`, commit it into the repo, and update the
export in `traditional-chinese-wordlist.ts` to `export { wordlist } from
'./traditional-chinese'` (removing the ../../../../../node_modules path);
alternatively apply a small dependency patch that fixes the package exports and
then import via the package name, but do not reference node_modules with a
relative path.
In `@src/app/`(locale)/[locale]/mnemonic/wordlists.ts:
- Around line 1-10: The module currently eagerly imports every 2048-word payload
(e.g., the imports like englishWordlist, frenchWordlist and the static WORDLISTS
map), which causes all lists to be bundled into the client; change this file to
export only small metadata (language keys, display names) and replace the static
WORDLISTS payload map with an async loader function (e.g., export async function
loadWordlist(lang: string)) that performs dynamic imports
(import('.../english.js') / import('./traditional-chinese-wordlist') etc.) and
returns the payload, leaving only light-weight metadata exported (rename
WORDLISTS -> WORDLIST_META or similar) and removing the top-level imports such
as englishWordlist/traditionalChineseWordlist so the actual wordlists are loaded
on demand.
In `@src/app/sitemap-shared.ts`:
- Around line 26-32: The sitemap currently sets priority: 1 for both the root
entry and all tool pages; update the tool entries created in the
TOOL_SITEMAP_PATHS.map callback to use a lower priority (e.g., 0.8) while
leaving the root entry at 1.0—locate the mapping that builds entries with url:
`${baseUrl}/${path}`, lastModified and changeFrequency, and change priority: 1
to priority: 0.8 for those tool pages so the homepage remains highest priority.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d61c5655-7d09-465b-b006-cfb543b79d13
⛔ Files ignored due to path filters (2)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yamlpublic/mnemonic/icon.svgis excluded by!**/*.svg
📒 Files selected for processing (15)
package.jsonsrc/app/(locale)/[locale]/mnemonic/layout.tsxsrc/app/(locale)/[locale]/mnemonic/page.tsxsrc/app/(locale)/[locale]/mnemonic/seo.tsxsrc/app/(locale)/[locale]/mnemonic/traditional-chinese-wordlist.tssrc/app/(locale)/[locale]/mnemonic/wordlists.tssrc/app/(locale)/[locale]/sitemap.tssrc/app/(main)/mnemonic/layout.tsxsrc/app/(main)/mnemonic/page.tsxsrc/app/sitemap-shared.tssrc/app/sitemap.tssrc/components/show-case.tsxsrc/constants.tssrc/locales/en/messages.posrc/locales/zh/messages.po
| <div className='rounded-3xl border p-5'> | ||
| <div className='mb-3 flex items-center justify-between gap-3'> | ||
| <div> | ||
| <h2 className='font-medium'> | ||
| <Trans>Mnemonic phrase</Trans> | ||
| </h2> | ||
| <p className='text-muted-foreground mt-1 text-sm'> | ||
| <Trans> | ||
| The selected wordlist is {activeWordlistLabel}. English is | ||
| usually the safest choice for wallet interoperability. | ||
| </Trans> | ||
| </p> | ||
| </div> | ||
| <CopyButton text={mnemonic} /> | ||
| </div> | ||
|
|
||
| <Textarea | ||
| className='min-h-40 resize-y text-sm leading-7' | ||
| value={mnemonic} | ||
| autoCapitalize='none' | ||
| autoComplete='off' | ||
| autoCorrect='off' | ||
| placeholder={t`Generate or paste a BIP-39 mnemonic phrase`} | ||
| spellCheck={false} | ||
| onChange={(event) => setMnemonic(event.target.value)} | ||
| /> |
There was a problem hiding this comment.
Give the textarea controls an accessible name.
The textareas on Line 260, Line 316, and Line 353 are only visually associated with nearby headings. Without a label, aria-label, or aria-labelledby, assistive tech will announce anonymous multiline fields here, especially for the two read-only outputs.
♿ Example fix
- <h2 className='font-medium'>
+ <h2 id='mnemonic-phrase-heading' className='font-medium'>
<Trans>Mnemonic phrase</Trans>
</h2>
@@
<Textarea
+ aria-labelledby='mnemonic-phrase-heading'
className='min-h-40 resize-y text-sm leading-7'
value={mnemonic}
@@
- <h2 className='font-medium'>
+ <h2 id='entropy-heading' className='font-medium'>
<Trans>Entropy (hex)</Trans>
</h2>
@@
<Textarea
+ aria-labelledby='entropy-heading'
readOnly
className='min-h-28 resize-none font-mono text-xs leading-6'
value={derivedResult.entropyHex}
@@
- <h2 className='font-medium'>
+ <h2 id='seed-heading' className='font-medium'>
<Trans>Seed (hex)</Trans>
</h2>
@@
<Textarea
+ aria-labelledby='seed-heading'
readOnly
className='min-h-36 resize-none font-mono text-xs leading-6'
value={seedPreview}Also applies to: 301-358
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/app/`(locale)/[locale]/mnemonic/page.tsx around lines 244 - 269, The
Textarea components rendering mnemonic and other read-only outputs (the Textarea
with value={mnemonic} and onChange={(event) => setMnemonic(event.target.value)}
and the two other Textarea instances further down) lack accessible names; add
either a visible <label> tied via htmlFor to the Textarea id or add aria-label /
aria-labelledby attributes to each Textarea so screen readers get a descriptive
name (e.g., "Mnemonic phrase", "Seed hex", "Derived address"); ensure the
id/aria-labelledby references match the Textarea props and update any CopyButton
usage to reference the same label if needed for context.
| export default async function sitemap(): Promise<MetadataRoute.Sitemap> { | ||
| const baseUrl = `${baseUrlWithoutLocale}/zh` | ||
|
|
||
| return [ | ||
| { | ||
| url: baseUrl, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/base64`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/base64-to-png`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/battery`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/code-diff`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/dice-roller`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/generate-query`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/keep-screen-on`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/miwifi-sn`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/pinyin`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/random-name`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| { | ||
| url: `${baseUrl}/vscode-extension-download`, | ||
| lastModified: new Date(), | ||
| changeFrequency: 'weekly', | ||
| priority: 1, | ||
| }, | ||
| ] | ||
| return buildToolSitemap(baseUrl) |
There was a problem hiding this comment.
Hardcoded locale in sitemap URL construction.
The baseUrl is hardcoded to /zh, but generateStaticParams returns all non-source locales. If additional locales are added in the future, this sitemap will incorrectly generate URLs with /zh prefix for all of them. The locale should be derived from the route params.
🐛 Proposed fix to use dynamic locale
-export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
- const baseUrl = `${baseUrlWithoutLocale}/zh`
+export default async function sitemap({
+ params,
+}: {
+ params: Promise<{ locale: string }>
+}): Promise<MetadataRoute.Sitemap> {
+ const { locale } = await params
+ const baseUrl = `${baseUrlWithoutLocale}/${locale}`
return buildToolSitemap(baseUrl)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export default async function sitemap(): Promise<MetadataRoute.Sitemap> { | |
| const baseUrl = `${baseUrlWithoutLocale}/zh` | |
| return [ | |
| { | |
| url: baseUrl, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| { | |
| url: `${baseUrl}/base64`, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| { | |
| url: `${baseUrl}/base64-to-png`, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| { | |
| url: `${baseUrl}/battery`, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| { | |
| url: `${baseUrl}/code-diff`, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| { | |
| url: `${baseUrl}/dice-roller`, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| { | |
| url: `${baseUrl}/generate-query`, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| { | |
| url: `${baseUrl}/keep-screen-on`, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| { | |
| url: `${baseUrl}/miwifi-sn`, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| { | |
| url: `${baseUrl}/pinyin`, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| { | |
| url: `${baseUrl}/random-name`, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| { | |
| url: `${baseUrl}/vscode-extension-download`, | |
| lastModified: new Date(), | |
| changeFrequency: 'weekly', | |
| priority: 1, | |
| }, | |
| ] | |
| return buildToolSitemap(baseUrl) | |
| export default async function sitemap({ | |
| params, | |
| }: { | |
| params: Promise<{ locale: string }> | |
| }): Promise<MetadataRoute.Sitemap> { | |
| const { locale } = await params | |
| const baseUrl = `${baseUrlWithoutLocale}/${locale}` | |
| return buildToolSitemap(baseUrl) | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/app/`(locale)/[locale]/sitemap.ts around lines 12 - 15, The sitemap
function currently hardcodes the locale (`/zh`); change sitemap to accept route
params and derive the locale dynamically (e.g., export default async function
sitemap({ params }: { params: { locale: string } }) ) and build the baseUrl with
`${baseUrlWithoutLocale}/${params.locale}` instead of `/zh`, then call
buildToolSitemap(baseUrl); this ensures the sitemap uses the locale provided by
the route (see sitemap, params.locale, baseUrlWithoutLocale, and
buildToolSitemap).
| 'generate query', | ||
| 'keep screen on', | ||
| 'miwifi sn', | ||
| 'mnemonic generator', |
There was a problem hiding this comment.
Localize zh metadata entry instead of reusing English term.
On Line 29 and Line 96, the isZh branches use 'mnemonic generator' in English. This is likely an i18n miss for locale-specific SEO/structured metadata. Please use the Chinese localized term (e.g., 助记词生成器) in both arrays for consistency.
Also applies to: 96-96
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/constants.ts` at line 29, Replace the English string 'mnemonic generator'
used inside the isZh branches with a Chinese localized term (e.g., "助记词生成器") in
both occurrences in src/constants.ts; locate the two places that check isZh and
currently emit 'mnemonic generator' and update those array entries so the
metadata/SEO uses the Chinese text consistently.
Summary by CodeRabbit
New Features
Localization
Chores