Every piece of static UI text in the template — navigation labels, button copy, form placeholders, empty-state messages, SEO titles, and structured headings — is stored as a translation key rather than a hardcoded string inside a component. TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Ozcaar/real-estate-template/llms.txt
Use this file to discover all available pages before exploring further.
@nuxtjs/i18n module resolves the active locale at runtime and returns the matching string from a JSON file. The template ships with English (en) and Spanish (es) locale files. Adding a third language is a matter of registering it in nuxt.config.ts and creating a new JSON file in i18n/locales/ — no component changes needed.
Setup and strategy
The template uses the'no_prefix' routing strategy, which means routes are not prefixed with a locale code. /properties serves both English and Spanish content depending on the visitor’s detected locale, rather than routing to /en/properties or /es/properties. Locale detection uses a cookie named i18n_locale so a visitor’s preference persists across sessions.
The default locale is 'en'. The agency.defaultLocale field in the agency config is the source of truth for which locale the site opens with on first visit.
Locale file structure
en.json but not in es.json, the Spanish locale falls back to English silently — the visitor sees an untranslated string with no error. Always add a key to both files at the same time.
Translation key groups
Keys are organized into top-level groups matching the domain they describe. The full key tree in the shippeden.json covers:
| Group | Purpose |
|---|---|
nav.* | Navigation link labels (home, properties, developments, agents, about, contact) |
common.* | Reusable labels shared across pages (contact, viewDetails, learnMore, loading, empty, openMenu, etc.) |
home.* | All homepage copy: hero, search bar, featured section, services, about band, locations, testimonials, CTA |
properties.* | Property catalog page, detail page, filters, sort options, status badges, type labels |
developments.* | Developments catalog page, status labels, card fields |
agents.* | Agents page, card actions (call, email, WhatsApp), empty state |
contact.* | Contact page and form fields |
about.* | About page: story, values, stats, CTA |
footer.* | Footer tagline, section headings, rights notice |
Partial example: en.json
i18n/locales/en.json
Using translations in Vue templates
Access translations with the$t() helper in templates, or useI18n().t() in <script setup>:
{agencyName}, {rating}, {count}) — pass the values as the second argument to $t(). The SEO title keys, for instance, embed the agency name: "Properties for sale and rent | {agencyName}".
Adding a new locale
Register the locale in nuxt.config.ts
Add the new locale code to the
defaultI18nLocales list (or the equivalent locales array in the i18n module config):nuxt.config.ts
Create the JSON translation file
Copy
i18n/locales/en.json to i18n/locales/pt.json and translate every value:i18n/locales/pt.json
Update the agency config
Add
'pt' to availableLocales in the agency config so the AppLanguageSwitcher component includes it and so validateAgencyConfig() does not throw a missing-locale error:app/config/agencies/default.agency.ts
Agency content vs. i18n keys
The template draws a clear line between two kinds of text:i18n keys (en.json / es.json)
Static UI strings that are the same for every agency using the template: button labels, navigation entries, form field labels, empty-state messages, filter headings, and SEO title patterns. All of these use translation keys.
Agency content (data files)
Dynamic content specific to this agency: property titles, agent names and bios, development descriptions, testimonial quotes, city names, and statistics. These are plain strings in the data files — not i18n keys.
| String | Where it lives | Why |
|---|---|---|
"Browse properties" (hero CTA label) | home.hero.ctaPrimary in en.json | Same label for any agency; translatable |
"Modern Hillside Villa" (property title) | properties.ts data file | Agency-specific content |
"For sale" (operation type badge) | properties.operations.sale in en.json | Fixed UI vocabulary; translatable |
"María González" (agent name) | agents.ts data file | Agency-specific content |
"Mon–Fri 9am–5pm" (business hours) | agency.contact.businessHours in agency config | Agency-specific identity |
useSiteConfig().agency rather than from the locale files. This means they appear in the same language regardless of the active locale (which is correct: a phone number or street address does not change with language).
The AppLanguageSwitcher component
The AppLanguageSwitcher component reads agency.availableLocales, renders a selector for each locale, and calls @nuxtjs/i18n’s setLocale() when the user picks a language. The selection is persisted in the i18n_locale cookie. No configuration beyond adding the locale to the agency config and registering it in nuxt.config.ts is required to make the switcher work.