# 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: ```ts // 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: ```bash 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 ``. 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, `` 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.