Content
How to translate
The site supports English (no URL prefix), Turkish (/tr/), German (/de/), and Russian (/ru/). The guide (/docs) stays EN + TR only. Never hardcode long sentences in .astro files — use the patterns below.
1. Static UI text (src/i18n/)
- src/i18n/hero.ts, common.ts, faq.ts, cta.ts — buttons, headings, FAQ
- src/i18n/pages/about.ts, contact.ts, privacy.ts — long page body copy
- Use t(obj, locale) in components; locale from getLangFromUrl(Astro.url) or stub pages
Text shape: four languages
import { ls, t } from "@/i18n/utils";
// ls() — DE/RU optional (default to EN)
export const myTitle = ls("Hello", "Merhaba", "Hallo", "Привет");
// Or explicit object:
export const myTitle = {
en: "Hello", tr: "Merhaba", de: "Hallo", ru: "Привет",
};
// In .astro:
const locale = getLangFromUrl(Astro.url);
<h1>{t(myTitle, locale)}</h1>
2. Nav & services (src/config/)
- nav.ts — label and href are { en, tr, de, ru } for each link
- services.ts — title, slug, description per language; URLs from sitePages
- routes.ts — sitePages.pageId.{ en, tr, de, ru } for every marketing URL
3. CMS content (Keystatic)
Blog, team, and testimonials use fields like titleEn, titleTr, titleDe, titleRu (and slugDe, slugRu for blog). Components read them with pickLocalized(data, locale).
4. Page files (thin stubs)
One shared component per page (e.g. ContactPage.astro). EN lives at src/pages/contact.astro; TR/DE/RU stubs only set locale and import the same component. Run npm run sync:routes after adding sitePages entries.
5. Check your work
- npm run validate:i18n — missing de/ru keys in core i18n files
- Switch language in the header on each page; URLs must match routes.ts
- npm run extend:i18n — copy EN into new de/ru keys in bulk (starter only)