diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 25b858c..25a48b0 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -31,6 +31,8 @@ DASH_DEV=1 go run ./cmd/dash # API on :8080
- No auth, no YAML-as-source-of-truth, no external database. These are
non-goals for v1.
- Standard library before dependencies; existing helpers before new ones.
+- User-visible strings go through `t("key")` from `src/i18n` — add the key to
+ `en.ts` rather than inlining literals in new UI.
## Before pushing
diff --git a/ROADMAP.md b/ROADMAP.md
index 01b22b7..8423a74 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -197,7 +197,7 @@ Beszel-style server monitoring, push-based.
- [x] `README.md` hero: screenshots, `docker run` one-liner (demo GIF deferred — pngs suffice for v1.0.0)
- [x] goreleaser → binaries; GHCR image on tag; semver + `CHANGELOG.md`
- [x] `CONTRIBUTING.md`, issue/PR templates, code of conduct, security policy
-- [ ] i18n scaffolding (en default)
+- [x] i18n scaffolding (`src/i18n/` — typed `t()` + `en` dict; full string extraction deferred to first real locale)
- [ ] Public repo flip + announcement assets
**Exit:** a stranger can `docker run`, import their Homepage config, and have a working board in under two minutes.
diff --git a/apps/frontend/src/App.tsx b/apps/frontend/src/App.tsx
index e3d40f0..77005f8 100644
--- a/apps/frontend/src/App.tsx
+++ b/apps/frontend/src/App.tsx
@@ -18,6 +18,7 @@ import { StatusPagesPage } from "@/pages/StatusPagesPage";
import { StatusPublicPage } from "@/pages/StatusPublicPage";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
+import { t, type Key } from "@/i18n";
import type { Item } from "@/types";
export default function App() {
@@ -28,13 +29,13 @@ export default function App() {
);
}
-const NAV = [
- { href: "/", label: "Board", icon: LayoutGrid },
- { href: "/monitors", label: "Monitors", icon: Activity },
- { href: "/domains", label: "Domains", icon: Globe },
- { href: "/systems", label: "Systems", icon: Server },
- { href: "/incidents", label: "Incidents", icon: AlertTriangle },
- { href: "/status", label: "Status", icon: Megaphone },
+const NAV: { href: string; labelKey: Key; icon: typeof LayoutGrid }[] = [
+ { href: "/", labelKey: "nav.board", icon: LayoutGrid },
+ { href: "/monitors", labelKey: "nav.monitors", icon: Activity },
+ { href: "/domains", labelKey: "nav.domains", icon: Globe },
+ { href: "/systems", labelKey: "nav.systems", icon: Server },
+ { href: "/incidents", labelKey: "nav.incidents", icon: AlertTriangle },
+ { href: "/status", labelKey: "nav.status", icon: Megaphone },
];
function Shell() {
@@ -94,14 +95,14 @@ function Shell() {
)}
>