Guides
Guide — Internationalization (i18n)
How the EN/ES bilingual setup of the website works and how to add or edit translations. Update this if the i18n system changes.
Summary
- Engine: next-intl ("no routing" mode, cookie-based).
- Primary language: English (
en). Secondary: Spanish (es). - The language is stored in the
localecookie (defaulten). - There is an EN/ES toggle in the header (
components/headers/LanguageSwitcher.tsx). - There are no
/esor/enroutes (the template's route structure was not touched).
Key files (in apps/web/)
| File | Function |
|---|---|
i18n/request.ts | Reads the locale cookie and loads messages/${locale}.json |
messages/en.json | English text (source) |
messages/es.json | Spanish translation |
next.config.ts | Registers the createNextIntlPlugin plugin |
app/layout.tsx | Wraps the app in NextIntlClientProvider and sets <html lang> |
components/headers/LanguageSwitcher.tsx | EN/ES toggle (set cookie + router.refresh()) |
How a text is translated
- In the component: use
const t = useTranslations("section")and{t("key")}. - Add the
keyto both catalogs:messages/en.json→ English textmessages/es.json→ Spanish text
- Keep the same key structure in both files.
What is translated today
- Header, Footer and the entire home (Creative Agency): Hero, About, Projects, Services, Testimonials, Blog preview, CTA.
Pending (remains in English for now)
Pages: about, contact, services, team, pricing, faq, 404, blog, projects and the other home demos. When translating new content, always do it through catalogs (do not hardcode text).
Technical note
Because the cookie is read in the layout, all routes are rendered on-demand (not static). This is the expected trade-off of the cookie mode without routing.