Skip to content

Localization (i18n) ​

Nuxt Users comes with built-in support for multiple languages, making it easy to provide a localized experience for your users. The module includes translations for all UI components and labels.

Supported Languages ​

Out of the box, Nuxt Users supports:

  • English (en) - Default
  • Hungarian (hu) - Informal variant (tegező)
  • Hungarian Formal (hu-formal) - Formal variant (magázó)

Quick Start ​

Minimal Setup (No Configuration Required) ​

The module works out of the box with English (en) as the default locale. You don't need to configure anything to start using translations:

typescript
export default defineNuxtConfig({
  modules: ['nuxt-users']
  // No locale configuration needed - defaults to English
})

You can immediately use translations in your components:

vue
<script setup>
const { t } = useNuxtUsersLocale()
</script>

<template>
  <h1>{{ t('login.title') }}</h1>
  <!-- Output: "Welcome Back" -->
</template>

Changing the Locale ​

To use a different locale, configure it in your nuxt.config.ts:

typescript
export default defineNuxtConfig({
  modules: ['nuxt-users'],
  
  runtimeConfig: {
    public: {
      nuxtUsers: {
        locale: {
          default: 'hu',              // Current locale (optional, defaults to 'en')
          fallbackLocale: 'en',      // Fallback when translation missing (optional, defaults to 'en')
        }
      }
    }
  }
})

Note: The locale configuration is completely optional. If you don't specify it, the module will use:

  • default: 'en'
  • fallbackLocale: 'en'

Using Translations in Components ​

Use the useNuxtUsersLocale() composable to access translations:

vue
<script setup>
const { t, currentLocale, fallbackLocale } = useNuxtUsersLocale()
</script>

<template>
  <div>
    <h1>{{ t('login.title') }}</h1>
    <p>{{ t('login.subtitle') }}</p>
    
    <!-- With parameters -->
    <p>{{ t('userCard.deleteConfirm', ['John Doe']) }}</p>
    
    <!-- Current locale: {{ currentLocale }} -->
  </div>
</template>

Custom Translations ​

Override Existing Translations ​

You can override default translations or add new ones. The locale configuration is optional - you only need to include it if you want to customize translations:

typescript
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      nuxtUsers: {
        locale: {
          default: 'en',
          fallbackLocale: 'en',
          texts: {
            en: {
              login: {
                title: 'Sign In',           // Override default
                welcomeBack: 'Welcome!'     // Add new translation
              }
            }
          }
        }
      }
    }
  }
})

Add New Language ​

⚠️ Temporary Solution (Config-Based) ​

You can temporarily add a new language by providing translations in your config. However, this approach has limitations:

  • Won't survive module updates: When the module adds new translation keys (new components, features, etc.), your custom translations won't include them
  • Manual maintenance: You'll need to manually add translations for every new key
  • Incomplete coverage: You'll only have translations for the keys you explicitly define

Quick and dirty approach (for testing or temporary use):

typescript
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      nuxtUsers: {
        locale: {
          default: 'de',
          fallbackLocale: 'en',
          texts: {
            de: {
              login: {
                title: 'Willkommen zurück',
                subtitle: 'Melden Sie sich in Ihrem Konto an',
                emailLabel: 'E-Mail',
                passwordLabel: 'Passwort',
                submit: 'Anmelden',
                forgotPassword: 'Passwort vergessen?',
                rememberMe: 'Angemeldet bleiben'
              },
              register: {
                title: 'Konto erstellen',
                // ... more translations
              }
            }
          }
        }
      }
    }
  }
})

For proper, long-term language support, please create a locale file and submit a Pull Request to the module repository. This ensures:

  • ✅ Automatic updates: New translation keys will be added to your locale file when the module is updated
  • ✅ Community benefit: Other users can benefit from your translations
  • ✅ Maintained: The translation will be kept up-to-date with module changes

To contribute a new language:

  1. Create a new locale file in the module's src/runtime/locales/ directory (e.g., de.ts)
  2. Export a complete LocaleMessages object with all required translation keys
  3. Add the locale to src/runtime/locales/index.ts
  4. Submit a Pull Request

See the Developer Guide on Localization for detailed instructions on creating locale files.

Translation Keys ​

Common Keys ​

typescript
common: {
  email: 'Email'
  password: 'Password'
  name: 'Name'
  fullName: 'Full Name'
  role: 'Role'
  active: 'Active'
  yes: 'Yes'
  no: 'No'
  edit: 'Edit'
  delete: 'Delete'
  loading: 'Loading...'
  error: 'Error'
}

Login Form ​

typescript
login: {
  title: 'Welcome Back'
  subtitle: 'Sign in to your account'
  emailLabel: 'Email'
  emailPlaceholder: 'Enter your email'
  passwordLabel: 'Password'
  passwordPlaceholder: 'Enter your password'
  rememberMe: 'Remember me'
  submit: 'Sign In'
  submitting: 'Signing in...'
  forgotPassword: 'Forgot your password?'
}

Registration Form ​

typescript
register: {
  title: 'Create Account'
  subtitle: 'Sign up for a new account'
  nameLabel: 'Full Name'
  namePlaceholder: 'Enter your full name'
  emailLabel: 'Email'
  emailPlaceholder: 'Enter your email'
  passwordLabel: 'Password'
  confirmPasswordLabel: 'Confirm Password'
  passwordMismatch: 'Passwords do not match'
  submit: 'Create Account'
  submitting: 'Creating Account...'
  alreadyHaveAccount: 'Already have an account?'
  signInLink: 'Sign in here'
}

Password Reset ​

typescript
resetPassword: {
  titleReset: 'Reset Password'
  titleChange: 'Change Password'
  currentPasswordLabel: 'Current Password'
  newPasswordLabel: 'New Password'
  confirmPasswordLabel: 'Confirm New Password'
  submitReset: 'Reset Password'
  submitUpdate: 'Update Password'
  submittingReset: 'Resetting...'
  submittingUpdate: 'Updating...'
  passwordHelpText: 'Password must contain at least'
  secureResetInfo: 'You are resetting your password using a secure link.'
  emailLabel: 'Email:'
}

Password Strength ​

typescript
passwordStrength: {
  label: 'Password Requirements:'
  strength: {
    weak: 'Weak'
    medium: 'Medium'
    strong: 'Strong'
    veryStrong: 'Very Strong'
  }
  requirements: {
    minLength: 'At least {0} characters'          // {0} is replaced with parameter
    uppercase: 'Contains uppercase letter'
    lowercase: 'Contains lowercase letter'
    numbers: 'Contains number'
    specialChars: 'Contains special character'
  }
}

Email Confirmation ​

typescript
emailConfirmation: {
  successTitle: 'Email Confirmed!'
  errorTitle: 'Confirmation Failed'
  loginButton: 'Continue to Login'
  backToLogin: 'Back to Login'
  processing: 'Processing...'
  processingMessage: 'Please wait while we process your email confirmation.'
  successMessage: 'Your email has been confirmed and your account is now active.'
  errorMessage: 'The confirmation link is invalid or has expired.'
}

Parameter Replacement ​

Use placeholders in translations for dynamic values:

typescript
// Translation with placeholder
userCard: {
  deleteConfirm: 'Are you sure you want to delete user {0}?'
}

// Usage with parameter
t('userCard.deleteConfirm', ['John Doe'])
// Result: "Are you sure you want to delete user John Doe?"

Multiple Parameters ​

typescript
// Translation with multiple placeholders
notification: {
  newMessage: '{0} sent you {1} new message(s)'
}

// Usage
t('notification.newMessage', ['John', 3])
// Result: "John sent you 3 new message(s)"

Hungarian Formal vs Informal ​

The module provides two Hungarian variants:

Informal (tegező) - hu ​

Used for casual, friendly communication:

typescript
login: {
  rememberMe: 'Emlékezz rám'          // informal "you"
  forgotPassword: 'Elfelejtetted...?' // informal
}

Formal (magázó) - hu-formal ​

Used for professional, respectful communication:

typescript
login: {
  rememberMe: 'Maradjon bejelentkezve'    // formal "you"
  forgotPassword: 'Elfelejtette...?'      // formal
}

Both variants share a common base for non-contextual terms (like "Email", "Password") to maintain consistency.

Composable API ​

useNuxtUsersLocale() ​

Returns an object with:

typescript
{
  t: (key: string, params?: (string | number)[]) => string
  currentLocale: ComputedRef<string>
  fallbackLocale: ComputedRef<string>
}

t(key, params?) ​

Get a translated string:

typescript
const { t } = useNuxtUsersLocale()

// Simple translation
const title = t('login.title')

// With parameters
const message = t('userCard.deleteConfirm', ['John'])

currentLocale ​

Get the current locale:

typescript
const { currentLocale } = useNuxtUsersLocale()

console.log(currentLocale.value) // 'en', 'hu', etc.

fallbackLocale ​

Get the fallback locale:

typescript
const { fallbackLocale } = useNuxtUsersLocale()

console.log(fallbackLocale.value) // 'en'

Best Practices ​

1. Always Use Translation Keys ​

❌ Don't hardcode strings in components:

vue
<template>
  <h1>Welcome Back</h1>
</template>

✅ Do use translation keys:

vue
<script setup>
const { t } = useNuxtUsersLocale()
</script>

<template>
  <h1>{{ t('login.title') }}</h1>
</template>

2. Provide Fallback Locale ​

When using a non-English locale, configure a fallback locale for missing translations:

typescript
locale: {
  default: 'de',
  fallbackLocale: 'en',  // Falls back to English if German translation missing
}

Note: If you don't specify fallbackLocale, it defaults to 'en', so you only need to configure it if you want a different fallback.

3. Use Descriptive Keys ​

Use nested, descriptive keys for better organization:

typescript
// Good
login.emailPlaceholder
register.passwordMismatch
profile.updateSuccess

// Avoid
email
password
success

4. Parameter Count Validation ​

The module validates parameter counts in development mode:

typescript
// Translation expects 1 parameter
deleteConfirm: 'Delete {0}?'

// Warning in development if count doesn't match
t('deleteConfirm', ['John', 'Extra'])  // Warns about extra parameter
t('deleteConfirm')                      // Warns about missing parameter

Complete Example ​

Here's a complete example with custom German translations. Remember, the locale configuration is optional - you only need it if you want to change from the default English locale:

typescript
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-users'],
  
  runtimeConfig: {
    public: {
      nuxtUsers: {
        locale: {
          default: 'de',
          fallbackLocale: 'en',
          texts: {
            de: {
              login: {
                title: 'Willkommen zurück',
                subtitle: 'Melden Sie sich an',
                emailLabel: 'E-Mail',
                emailPlaceholder: 'E-Mail eingeben',
                passwordLabel: 'Passwort',
                passwordPlaceholder: 'Passwort eingeben',
                rememberMe: 'Angemeldet bleiben',
                submit: 'Anmelden',
                submitting: 'Anmeldung...',
                forgotPassword: 'Passwort vergessen?'
              },
              register: {
                title: 'Konto erstellen',
                subtitle: 'Registrieren Sie sich',
                nameLabel: 'Vollständiger Name',
                emailLabel: 'E-Mail',
                passwordLabel: 'Passwort',
                confirmPasswordLabel: 'Passwort bestätigen',
                submit: 'Registrieren'
              }
            }
          }
        }
      }
    }
  }
})
vue
<!-- pages/login.vue -->
<script setup>
const { t } = useNuxtUsersLocale()
</script>

<template>
  <div>
    <h1>{{ t('login.title') }}</h1>
    <NUsersLoginForm />
  </div>
</template>

Released under the MIT License.