Pre-1.0 — the foundation is still being laid out. Issue/PR triage may be slow until Phase 1 (Recipes) ships. Bug reports are welcome on the public repo; feature suggestions tracked in FUTURE.md.
git clone https://github.com/traceapps/cooktrace.git
cd cooktrace
npm install
npm run dev # Vite dev server on :5175
node server/index.js # API on :3001- Match the surrounding code. The codebase inherits NutriTrace conventions almost entirely.
- No comments unless the WHY is non-obvious.
- Don't add features beyond what the issue/PR scope demands.
- See
CLAUDE.mdfor project-specific notes.
- Copy
src/i18n/en.jsontosrc/i18n/<your-locale>.json(e.g.fr.json,de.json,pt-BR.json) and translate the values. Leave the keys untouched. HTML / Markdown inside values (<strong>,<br>, etc.) stays as-is. - Register the locale in
src/i18n/index.js. Add aregister('<locale>', () => import('./<locale>.json'));line, and append an{ code: '<locale>', label: '<Language name in its own language>' }entry toAVAILABLE_LOCALES. Without this step the JSON sits in the repo but the language picker in Settings cannot surface it. - Run
npm run i18n:checkand confirm 100% key coverage with no missing or orphaned entries. - Open a PR. Translations are merged with the contributor's authorship preserved on the JSON file.
Every user-facing string added to the app should be extracted into en.json and rendered through svelte-i18n's $_() helper. Hardcoded English literals in templates are the reason translation coverage lags the codebase — please prevent them at PR time rather than retrofit them later.
The pattern:
<script>
import { _ } from 'svelte-i18n';
</script>
<h1>{$_('routes.recipes.title')}</h1>
<input placeholder={$_('routes.recipes.search_placeholder')} />Then in src/i18n/en.json:
"routes": {
"recipes": {
"title": "Recipes",
"search_placeholder": "Search recipes…"
}
}Guidelines:
- Group by area, not by page.
settings.notifications.sectionis better thansettings_notifications_section. - Only add English in your PR. Do not machine-translate or hand-translate into other languages you don't natively speak — that misrepresents contributor work. The
en.jsonaddition is enough; translators fill in their locale files in follow-up PRs.svelte-i18n'sfallbackLocale: 'en'renders English until a translation lands. - Skip developer-facing strings — error stacks, log messages, JSON payload keys, class names. Only pull out what a user reads on screen.
- Interpolation uses
{$_('key', { values: { name: user.name } })}and{name}in the JSON value. Prefer this over string concatenation so translators can reorder words. - Run
npm run i18n:checkbefore opening the PR. It flags orphaned keys and missing translations across every locale file, catching typos and stale entries.
If you're adding a section that has a lot of copy, group all the new keys under one namespace in en.json so they can be reviewed together.
Do not add translations for locales you don't natively speak, and do not merge machine-translated content into a contributor's locale file. If a section can't be translated at code-write time (nobody on the PR speaks the language), extract to en.json, open a follow-up "Translations wanted" issue linking the new keys, and let a native speaker fill them in. svelte-i18n's English fallback keeps the app fully functional in the meantime.
CookTrace, NutriTrace, and LiftTrace share design language and the
Trace AI assistant persona. Keep TraceFace.svelte identical across
all three repos. If you change the assistant tone or the navigation
chrome here, mirror to LiftTrace + NutriTrace in the same PR cycle.