This project uses @nuxtjs/i18n for internationalization with ESLint rules to prevent hardcoded text.
i18n/
├── locales/
│ ├── pt.ts # Portuguese translations
│ └── en.ts # English translations
└── README.md # This file
<template>
<div>
<!-- Simple translation -->
<h1>{{ $t('common.save') }}</h1>
<!-- With parameters -->
<p>{{ $t('footer.copyright', { year: 2025 }) }}</p>
<!-- Nested keys -->
<button>{{ $t('product.addToCart') }}</button>
<!-- Pluralization -->
<p>{{ $t('cart.items', cart.length) }}</p>
</div>
</template><script setup>
const { t, locale, setLocale } = useI18n()
// Use translations
const message = t('message.saveSuccess')
const greeting = t('nav.home')
// Get current locale
console.log(locale.value) // 'pt' or 'en'
// Change locale
await setLocale('en')
</script><script>
export default {
methods: {
showMessage() {
const msg = this.$t('message.success')
alert(msg)
}
}
}
</script>- Add the key to both locale files:
i18n/locales/pt.ts
export default {
myFeature: {
title: 'Meu Título',
description: 'Minha Descrição',
button: 'Meu Botão',
}
}i18n/locales/en.ts
export default {
myFeature: {
title: 'My Title',
description: 'My Description',
button: 'My Button',
}
}- Use in your component:
<template>
<div>
<h1>{{ $t('myFeature.title') }}</h1>
<p>{{ $t('myFeature.description') }}</p>
<button>{{ $t('myFeature.button') }}</button>
</div>
</template>The project has ESLint rules to prevent hardcoded text:
❌ Wrong (will show ESLint warning):
<template>
<h1>Welcome to our store</h1>
<button>Add to Cart</button>
</template>✅ Correct:
<template>
<h1>{{ $t('home.welcome') }}</h1>
<button>{{ $t('product.addToCart') }}</button>
</template>The rule ignores:
- Special characters:
/,-,|,•,:,,,(,),[,],{,} - Icon names:
mdi-*(e.g.,mdi-home,mdi-cart) - Pure whitespace
- Content in icon components (
VIcon,v-icon,md-icon)
plugins/**- Plugin filescomposables/**- Composable filesmiddleware/**- Middleware files*.config.*- Configuration files
common.*- Save, Cancel, Edit, Delete, etc.
nav.*- Home, Products, Cart, Orders, etc.
admin.*- Dashboard, Settings, etc.
product.*- Name, Price, Stock, Add to Cart, etc.
cart.*- Shopping cart relatedcheckout.*- Checkout process
order.*- Order status, history, tracking
form.*- Form fields and validation messages
message.*- Success, error, warning messages
payment.*- Payment methods and related
language.*- Language selector strings
footer.*- Footer links and copyright
The app automatically syncs the i18n locale with the whitelabel language setting:
- Admin changes language in
/admin/language - Setting is saved to whitelabel in database
- i18n locale updates immediately
- All translated text updates across the app
Check for hardcoded text:
bun run lintFix auto-fixable issues:
bun run lint:fix- Always use translation keys - Never hardcode user-facing text
- Keep keys organized - Group related translations
- Use descriptive key names -
product.addToCartnotbtn1 - Add translations to both files - pt.ts AND en.ts
- Test in both languages - Switch languages in
/admin/language