Add internationalization (i18n) with next-intl and Italian translations

- Integrated `next-intl` for server-side and client-side i18n support.
- Added English (`en.json`) and Italian (`it.json`) localization files.
- Configured routing with locale-based subdirectories (`/[locale]/path`) using `next-intl`.
- Introduced type-safe i18n utilities and TypeScript definitions for translation keys.
- Updated middleware to handle locale detection and routing.
- Implemented dynamic translation loading to reduce bundle size.
- Enhanced developer experience with auto-complete and compile-time validation for i18n keys.
This commit is contained in:
Felipe Cardoso
2025-11-17 20:27:09 +01:00
parent b7c1191335
commit fe6a98c379
11 changed files with 873 additions and 13 deletions

165
frontend/messages/en.json Normal file
View File

@@ -0,0 +1,165 @@
{
"common": {
"loading": "Loading...",
"error": "Error",
"success": "Success",
"cancel": "Cancel",
"save": "Save",
"delete": "Delete",
"edit": "Edit",
"close": "Close",
"confirm": "Confirm",
"back": "Back",
"next": "Next",
"submit": "Submit",
"search": "Search",
"filter": "Filter",
"clear": "Clear",
"required": "Required",
"optional": "Optional",
"yes": "Yes",
"no": "No"
},
"navigation": {
"home": "Home",
"dashboard": "Dashboard",
"settings": "Settings",
"profile": "Profile",
"logout": "Logout",
"login": "Login",
"register": "Register",
"demos": "Demos",
"design": "Design System"
},
"auth": {
"login": {
"title": "Sign in to your account",
"subtitle": "Enter your email below to sign in to your account",
"emailLabel": "Email",
"emailPlaceholder": "name@example.com",
"passwordLabel": "Password",
"passwordPlaceholder": "Enter your password",
"rememberMe": "Remember me",
"forgotPassword": "Forgot password?",
"loginButton": "Sign In",
"noAccount": "Don't have an account?",
"registerLink": "Sign up",
"success": "Successfully logged in",
"error": "Invalid email or password"
},
"register": {
"title": "Create an account",
"subtitle": "Enter your information to create an account",
"firstNameLabel": "First Name",
"firstNamePlaceholder": "John",
"lastNameLabel": "Last Name",
"lastNamePlaceholder": "Doe",
"emailLabel": "Email",
"emailPlaceholder": "name@example.com",
"passwordLabel": "Password",
"passwordPlaceholder": "Create a strong password",
"confirmPasswordLabel": "Confirm Password",
"confirmPasswordPlaceholder": "Re-enter your password",
"phoneLabel": "Phone Number",
"phonePlaceholder": "+1 (555) 000-0000",
"registerButton": "Create Account",
"hasAccount": "Already have an account?",
"loginLink": "Sign in",
"success": "Account created successfully",
"error": "Failed to create account"
},
"passwordReset": {
"title": "Reset your password",
"subtitle": "Enter your email address and we'll send you a reset link",
"emailLabel": "Email",
"emailPlaceholder": "name@example.com",
"sendButton": "Send Reset Link",
"backToLogin": "Back to login",
"success": "Password reset link sent to your email",
"error": "Failed to send reset link"
},
"passwordChange": {
"title": "Change Password",
"currentPasswordLabel": "Current Password",
"newPasswordLabel": "New Password",
"confirmPasswordLabel": "Confirm New Password",
"changeButton": "Change Password",
"success": "Password changed successfully",
"error": "Failed to change password"
}
},
"settings": {
"title": "Settings",
"profile": {
"title": "Profile",
"subtitle": "Manage your profile information",
"firstNameLabel": "First Name",
"lastNameLabel": "Last Name",
"emailLabel": "Email",
"phoneLabel": "Phone Number",
"updateButton": "Update Profile",
"success": "Profile updated successfully",
"error": "Failed to update profile"
},
"password": {
"title": "Password",
"subtitle": "Change your account password",
"currentPasswordLabel": "Current Password",
"newPasswordLabel": "New Password",
"confirmPasswordLabel": "Confirm New Password",
"updateButton": "Update Password",
"success": "Password updated successfully",
"error": "Failed to update password"
},
"sessions": {
"title": "Sessions",
"subtitle": "Manage your active sessions",
"currentSession": "Current Session",
"activeSession": "Active",
"lastActive": "Last active",
"device": "Device",
"location": "Location",
"revokeButton": "Revoke",
"revokeAll": "Revoke All Other Sessions",
"success": "Session revoked successfully",
"error": "Failed to revoke session"
},
"preferences": {
"title": "Preferences",
"subtitle": "Customize your experience",
"language": "Language",
"languageDescription": "Select your preferred language",
"theme": "Theme",
"themeDescription": "Choose your color scheme",
"themeLight": "Light",
"themeDark": "Dark",
"themeSystem": "System"
}
},
"errors": {
"notFound": "Page not found",
"notFoundDescription": "The page you're looking for doesn't exist.",
"unauthorized": "Unauthorized",
"unauthorizedDescription": "You don't have permission to access this page.",
"serverError": "Server error",
"serverErrorDescription": "Something went wrong on our end.",
"networkError": "Network error",
"networkErrorDescription": "Please check your internet connection.",
"validation": {
"required": "This field is required",
"email": "Please enter a valid email address",
"minLength": "Must be at least {min} characters",
"maxLength": "Must be at most {max} characters",
"passwordMismatch": "Passwords do not match",
"passwordWeak": "Password is too weak"
}
},
"validation": {
"required": "This field is required",
"email": "Invalid email address",
"minLength": "Minimum {count} characters required",
"maxLength": "Maximum {count} characters allowed",
"pattern": "Invalid format",
"passwordMismatch": "Passwords do not match"
}
}

165
frontend/messages/it.json Normal file
View File

@@ -0,0 +1,165 @@
{
"common": {
"loading": "Caricamento...",
"error": "Errore",
"success": "Successo",
"cancel": "Annulla",
"save": "Salva",
"delete": "Elimina",
"edit": "Modifica",
"close": "Chiudi",
"confirm": "Conferma",
"back": "Indietro",
"next": "Avanti",
"submit": "Invia",
"search": "Cerca",
"filter": "Filtra",
"clear": "Cancella",
"required": "Obbligatorio",
"optional": "Facoltativo",
"yes": "Sì",
"no": "No"
},
"navigation": {
"home": "Home",
"dashboard": "Dashboard",
"settings": "Impostazioni",
"profile": "Profilo",
"logout": "Disconnetti",
"login": "Accedi",
"register": "Registrati",
"demos": "Demo",
"design": "Design System"
},
"auth": {
"login": {
"title": "Accedi al tuo account",
"subtitle": "Inserisci la tua email per accedere al tuo account",
"emailLabel": "Email",
"emailPlaceholder": "nome@esempio.com",
"passwordLabel": "Password",
"passwordPlaceholder": "Inserisci la tua password",
"rememberMe": "Ricordami",
"forgotPassword": "Password dimenticata?",
"loginButton": "Accedi",
"noAccount": "Non hai un account?",
"registerLink": "Registrati",
"success": "Accesso effettuato con successo",
"error": "Email o password non validi"
},
"register": {
"title": "Crea un account",
"subtitle": "Inserisci le tue informazioni per creare un account",
"firstNameLabel": "Nome",
"firstNamePlaceholder": "Mario",
"lastNameLabel": "Cognome",
"lastNamePlaceholder": "Rossi",
"emailLabel": "Email",
"emailPlaceholder": "nome@esempio.com",
"passwordLabel": "Password",
"passwordPlaceholder": "Crea una password sicura",
"confirmPasswordLabel": "Conferma Password",
"confirmPasswordPlaceholder": "Reinserisci la tua password",
"phoneLabel": "Numero di Telefono",
"phonePlaceholder": "+39 123 456 7890",
"registerButton": "Crea Account",
"hasAccount": "Hai già un account?",
"loginLink": "Accedi",
"success": "Account creato con successo",
"error": "Impossibile creare l'account"
},
"passwordReset": {
"title": "Reimposta la tua password",
"subtitle": "Inserisci il tuo indirizzo email e ti invieremo un link per reimpostare la password",
"emailLabel": "Email",
"emailPlaceholder": "nome@esempio.com",
"sendButton": "Invia Link di Reset",
"backToLogin": "Torna al login",
"success": "Link di reset password inviato alla tua email",
"error": "Impossibile inviare il link di reset"
},
"passwordChange": {
"title": "Cambia Password",
"currentPasswordLabel": "Password Attuale",
"newPasswordLabel": "Nuova Password",
"confirmPasswordLabel": "Conferma Nuova Password",
"changeButton": "Cambia Password",
"success": "Password cambiata con successo",
"error": "Impossibile cambiare la password"
}
},
"settings": {
"title": "Impostazioni",
"profile": {
"title": "Profilo",
"subtitle": "Gestisci le informazioni del tuo profilo",
"firstNameLabel": "Nome",
"lastNameLabel": "Cognome",
"emailLabel": "Email",
"phoneLabel": "Numero di Telefono",
"updateButton": "Aggiorna Profilo",
"success": "Profilo aggiornato con successo",
"error": "Impossibile aggiornare il profilo"
},
"password": {
"title": "Password",
"subtitle": "Cambia la password del tuo account",
"currentPasswordLabel": "Password Attuale",
"newPasswordLabel": "Nuova Password",
"confirmPasswordLabel": "Conferma Nuova Password",
"updateButton": "Aggiorna Password",
"success": "Password aggiornata con successo",
"error": "Impossibile aggiornare la password"
},
"sessions": {
"title": "Sessioni",
"subtitle": "Gestisci le tue sessioni attive",
"currentSession": "Sessione Corrente",
"activeSession": "Attiva",
"lastActive": "Ultima attività",
"device": "Dispositivo",
"location": "Posizione",
"revokeButton": "Revoca",
"revokeAll": "Revoca Tutte le Altre Sessioni",
"success": "Sessione revocata con successo",
"error": "Impossibile revocare la sessione"
},
"preferences": {
"title": "Preferenze",
"subtitle": "Personalizza la tua esperienza",
"language": "Lingua",
"languageDescription": "Seleziona la tua lingua preferita",
"theme": "Tema",
"themeDescription": "Scegli la tua combinazione di colori",
"themeLight": "Chiaro",
"themeDark": "Scuro",
"themeSystem": "Sistema"
}
},
"errors": {
"notFound": "Pagina non trovata",
"notFoundDescription": "La pagina che stai cercando non esiste.",
"unauthorized": "Non autorizzato",
"unauthorizedDescription": "Non hai i permessi per accedere a questa pagina.",
"serverError": "Errore del server",
"serverErrorDescription": "Qualcosa è andato storto dal nostro lato.",
"networkError": "Errore di rete",
"networkErrorDescription": "Controlla la tua connessione internet.",
"validation": {
"required": "Questo campo è obbligatorio",
"email": "Inserisci un indirizzo email valido",
"minLength": "Deve essere di almeno {min} caratteri",
"maxLength": "Deve essere al massimo {max} caratteri",
"passwordMismatch": "Le password non corrispondono",
"passwordWeak": "La password è troppo debole"
}
},
"validation": {
"required": "Questo campo è obbligatorio",
"email": "Indirizzo email non valido",
"minLength": "Minimo {count} caratteri richiesti",
"maxLength": "Massimo {count} caratteri consentiti",
"pattern": "Formato non valido",
"passwordMismatch": "Le password non corrispondono"
}
}