2.2 KiB
Rule: content and i18n
Every user-visible string is content
No hard-coded copy in components. Strings live in src/content/, typed with
Zod, and reach components as props or collection entries.
The existing shape
app.js already stores content as { en: '…', pt: '…' } objects across
phases, handsOnPrompts, modelGuide, skillSources, and
skillInstallPrompts — about 50 en: keys. That shape is fine and should be
carried across, not redesigned:
// src/content/config.ts
const localized = z.object({ en: z.string(), pt: z.string() });
Both locales are required. A missing pt must be a build error, not a
silent English fallback — that is how bilingual sites quietly become
monolingual.
Migrating strings
Copy, do not retype. These are hand-written translations with specific tone
('Transforme ambiguidade em trabalho'). Retyping introduces typos and drift.
Move the literal, then diff the extracted content against the original file to
prove nothing changed:
node .agents/scripts/extract-strings.mjs app.js > /tmp/before.json
node .agents/scripts/extract-strings.mjs src/content/guide/ > /tmp/after.json
diff /tmp/before.json /tmp/after.json
Language switching
Today the toggle swaps text client-side and updates <html lang>. Two options
for Astro, decide in task 03:
- Keep client-side swap. Both languages ship in the payload. Zero routing change, matches today exactly, no URL work. Recommended — the content is small and the current behaviour is already what people link to.
- Route-based (
/en/,/pt/). Better SEO, more correct, but it changes every existing URL. Only do this with an explicit decision plus redirects.
Whichever you pick, <html lang> must track the active language.
Rendered content
Markdown in catalog.js entries (the improved field) should become real
Markdown files in the collection, rendered at build time rather than by a
hand-rolled client-side renderer. That deletes code and improves fidelity.
Careful: skill-reviews/improved/**/SKILL.md is generated from those
entries by scripts/build-skill-review.mjs, and the generated files are
committed. Keep that generator working, or replace it and update every reference
to it.