[Guía práctica completa] Multilingüización y localización en Laravel: archivos de traducción, cambio de idioma, diseño de URL, validación, fechas, moneda e interfaz multilingüe accesible
Qué aprenderás en este artículo
- Diseño básico para comenzar a admitir varios idiomas en Laravel
- Cómo usar el directorio
lang, traducciones en arrays PHP y traducciones JSON - Gestión de textos con
__(),@langytrans_choice() - Patrones de implementación para cambio de idioma, diseño de URL, middleware y almacenamiento en sesión
- Localización de mensajes de validación, nombres de atributos, fechas, horas, monedas y números
- Errores comunes en sitios multilingües: SEO, caché, pruebas y operación
- Interfaz accesible para cambio de idioma, soporte para lectores de pantalla, atributos
lang, dirección del texto y visualización clara de errores
Lectores objetivo
- Ingenieros Laravel de nivel principiante a intermedio que quieren ampliar una aplicación solo en japonés hacia inglés u otros idiomas
- Operadores de SaaS, comercio electrónico y medios que quieren atender a usuarios internacionales y multilingües
- Líderes técnicos que quieren estandarizar archivos de traducción, URL, caché y pruebas dentro de un equipo
- Diseñadores, redactores y especialistas en accesibilidad que quieren que el cambio de idioma y los textos multilingües sean claros para todos
Nivel de accesibilidad: ★★★★★
La multilingüización no consiste solo en traducir textos. Requiere un diseño que permita a los usuarios operar con confianza, incluyendo el atributo lang de la página, enlaces claros para cambiar de idioma, detección correcta del idioma por lectores de pantalla, formato de fechas y moneda, y mensajes de error naturales. Este artículo organiza el soporte multilingüe accesible desde las perspectivas de implementación e interfaz de usuario.
1. Introducción: la multilingüización no es “traducción”, sino “diseño de experiencia”
Cuando se empieza a implementar soporte multilingüe en Laravel, muchas personas primero piensan en reemplazar textos japoneses por textos en inglés. La traducción, por supuesto, es importante, pero no es suficiente. El soporte multilingüe afecta URL, formularios, validación, fechas, horas, monedas, correos electrónicos, SEO, caché y accesibilidad.
Por ejemplo, aunque el texto visible de una pantalla esté en inglés, los usuarios se confundirán si los mensajes de error siguen en japonés. Una fecha como 2026/05/13 puede interpretarse de manera diferente según el país o la región. La moneda, los separadores decimales y los separadores de miles también varían según la configuración regional. Además, los lectores de pantalla consultan el atributo lang de la página al leer el contenido en voz alta, por lo que una configuración incorrecta del idioma puede afectar la pronunciación y la comprensión.
En otras palabras, la multilingüización no es “reemplazar cadenas de texto”. Es “diseñar la entrega de información para que encaje con el idioma, la cultura y el entorno de uso del usuario”. Laravel ofrece funciones de localización, por lo que el enfoque más seguro es usar primero correctamente las funciones estándar y luego agregar reglas operativas según sea necesario.
2. Decide primero: idiomas admitidos y diseño de URL
Antes de comenzar la multilingüización, lo primero que debes decidir son los idiomas admitidos y el diseño de las URL. Si esto no está claro, el enrutamiento, el SEO, la caché y la generación de enlaces se volverán difíciles más adelante.
Hay tres patrones comunes de diseño de URL.
2.1 Incluir el idioma en la ruta
/ja/products
/en/products
/fr/products
Este es el enfoque más claro y funciona bien para SEO y para compartir enlaces. Como el idioma de la página es visible desde la URL, también funciona bien con la caché y los motores de búsqueda. En proyectos reales, suele ser la primera opción a considerar.
2.2 Separar por subdominio
ja.example.com
en.example.com
Esto es adecuado cuando quieres separar claramente marcas o regiones. Sin embargo, los certificados, cookies, sesiones, enrutamiento e infraestructura se vuelven un poco más complejos.
2.3 Cambiar solo con sesiones o cookies
/products
En este método, la URL permanece igual y el idioma mostrado cambia según el idioma guardado en la sesión o cookie. Es conveniente para pantallas administrativas pequeñas, pero es débil para SEO y enlaces compartidos. Si alguien ve una URL en inglés y se la envía a otra persona, el destinatario podría ver la página en japonés.
En la práctica, los sitios públicos y servicios donde el SEO importa son más fáciles de gestionar cuando el idioma está incluido en la URL, como /ja/... o /en/.... Para pantallas administrativas o productos SaaS con inicio de sesión, también es realista usar sesiones o configuraciones de usuario.
3. Configuración básica de Laravel: locale y fallback_locale
En Laravel, la configuración del idioma de la aplicación se gestiona en config/app.php.
'locale' => env('APP_LOCALE', 'ja'),
'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),
En .env, puedes configurarlo así.
APP_LOCALE=ja
APP_FALLBACK_LOCALE=en
locale es el idioma predeterminado, y fallback_locale es el idioma de respaldo que se usa cuando no se encuentra una traducción. Por ejemplo, si el idioma predeterminado es japonés pero faltan algunas traducciones, puedes usar inglés como respaldo.
Sin embargo, tener un idioma de respaldo no significa que esté bien dejar traducciones faltantes sin resolver. Si una parte de la pantalla está en japonés y otra en inglés, los usuarios pueden confundirse. Es más seguro preparar un mecanismo que facilite detectar traducciones faltantes durante el desarrollo y las pruebas.
4. Ubicación de los archivos de traducción: prepara el directorio lang
En aplicaciones Laravel recientes, es posible que el directorio lang no exista por defecto. En ese caso, puedes publicarlo con el siguiente comando.
php artisan lang:publish
Una estructura típica se ve así.
lang/
├─ ja/
│ ├─ messages.php
│ ├─ validation.php
│ └─ auth.php
├─ en/
│ ├─ messages.php
│ ├─ validation.php
│ └─ auth.php
└─ ja.json
Laravel admite tanto archivos de traducción en arrays PHP como archivos de traducción JSON. Ambos son útiles, pero separar sus casos de uso facilita el mantenimiento.
5. Cómo usar traducciones en arrays PHP y traducciones JSON
5.1 Traducciones en arrays PHP
lang/ja/messages.php
return [
'welcome' => 'ようこそ、:nameさん',
'profile_updated' => 'プロフィールを更新しました。',
'items_count' => ':count件の項目があります。',
];
Uso:
{{ __('messages.welcome', ['name' => $user->name]) }}
Las traducciones en arrays PHP son útiles porque permiten organizar el texto por categoría.
Por ejemplo, puedes separar la autenticación en auth.php, los formularios en forms.php y las pantallas administrativas en admin.php.
5.2 Traducciones JSON
lang/ja.json
{
"Welcome": "ようこそ",
"Save": "保存する",
"Cancel": "キャンセル"
}
Uso:
{{ __('Save') }}
Las traducciones JSON son adecuadas para textos comunes y breves.
Sin embargo, no son muy adecuadas para una gestión jerárquica o dependiente del contexto, por lo que en aplicaciones grandes suele ser más fácil mantener las traducciones en arrays PHP como enfoque principal.
5.3 Recomendación práctica
- Texto específico de pantallas y negocio: arrays PHP
- Botones comunes y etiquetas cortas: JSON
- Validación:
validation.php - Autenticación:
auth.php - Correos electrónicos:
mail.phpoemails.php
No hace falta dividir los archivos demasiado desde el principio, pero decidir como equipo dónde colocar cada texto ayuda a mantener organizados los archivos de traducción.
6. Conceptos básicos de traducción: __(), @lang y trans_choice()
La forma básica de obtener cadenas traducidas en Laravel es __().
<h1>{{ __('messages.welcome', ['name' => $user->name]) }}</h1>
En Blade, también puedes usar @lang.
@lang('messages.profile_updated')
Cuando el texto cambia según una cantidad, usa trans_choice().
echo trans_choice('messages.comments', $count, ['count' => $count]);
Archivo de traducción:
return [
'comments' => '{0} コメントはありません|{1} :count件のコメントがあります|[2,*] :count件のコメントがあります',
];
El japonés tiene menos cambios entre singular y plural que el inglés, pero al expandirse al inglés u otros idiomas, es más seguro gestionar las expresiones basadas en cantidades con trans_choice() desde el principio.
7. Implementar el cambio de idioma: determinar el idioma actual con middleware
Cuando el idioma está incluido en la URL, puedes usar rutas como /ja/products.
Primero, define los idiomas admitidos en un archivo de configuración.
// config/locales.php
return [
'supported' => ['ja', 'en'],
'default' => 'ja',
];
Crea un middleware.
php artisan make:middleware SetLocale
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
class SetLocale
{
public function handle(Request $request, Closure $next)
{
$locale = $request->route('locale');
if (! in_array($locale, config('locales.supported'), true)) {
abort(404);
}
App::setLocale($locale);
return $next($request);
}
}
Define las rutas así.
Route::prefix('{locale}')
->middleware(['set.locale'])
->group(function () {
Route::get('/products', [ProductController::class, 'index'])
->name('products.index');
});
Al generar enlaces, pasa el idioma actual.
<a href="{{ route('products.index', ['locale' => app()->getLocale()]) }}">
{{ __('messages.products') }}
</a>
Con este enfoque, el idioma queda claro desde la URL. Es fácil de compartir y comprensible para los motores de búsqueda, por lo que es especialmente práctico para sitios públicos.
8. Guardar el idioma en sesiones o configuraciones de usuario
Para pantallas administrativas con inicio de sesión o productos SaaS, puedes guardar una configuración de idioma para cada usuario.
Por ejemplo, agrega una columna locale a la tabla de usuarios.
Schema::table('users', function (Blueprint $table) {
$table->string('locale', 10)->default('ja');
});
Configúralo en un middleware después del inicio de sesión.
public function handle(Request $request, Closure $next)
{
if ($request->user()?->locale) {
App::setLocale($request->user()->locale);
}
return $next($request);
}
Formulario de cambio de idioma:
<form method="POST" action="{{ route('settings.locale.update') }}">
@csrf
@method('PATCH')
<label for="locale">{{ __('settings.language') }}</label>
<select id="locale" name="locale">
<option value="ja" @selected(app()->getLocale() === 'ja')>日本語</option>
<option value="en" @selected(app()->getLocale() === 'en')>English</option>
</select>
<button type="submit">{{ __('messages.save') }}</button>
</form>
Guardar el idioma como configuración del usuario facilita mostrar el mismo idioma incluso cuando el usuario cambia de dispositivo.
Por otro lado, en páginas públicas, el idioma no aparece en la URL, por lo que hay que tener cuidado con el SEO y los enlaces compartidos.
9. Interfaz de cambio de idioma: diseña para la accesibilidad desde el principio
Cambiar de idioma no es tan simple como colocar un icono de bandera. Las banderas representan países, no idiomas, y no siempre representan con precisión un idioma. Por ejemplo, el inglés no se usa solo en Estados Unidos, y el español se usa en muchos países.
Un enfoque recomendado es mostrar el nombre de cada idioma en ese mismo idioma.
<nav aria-label="{{ __('messages.language_switcher') }}">
<ul>
<li>
<a href="{{ route('home', ['locale' => 'ja']) }}" lang="ja" hreflang="ja">
日本語
</a>
</li>
<li>
<a href="{{ route('home', ['locale' => 'en']) }}" lang="en" hreflang="en">
English
</a>
</li>
</ul>
</nav>
Agregar aria-current al idioma actualmente seleccionado facilita la comprensión.
<a
href="{{ route('home', ['locale' => 'ja']) }}"
lang="ja"
hreflang="ja"
@if(app()->getLocale() === 'ja') aria-current="true" @endif
>
日本語
</a>
Para la interfaz de cambio de idioma, ten en cuenta lo siguiente.
- No dependas solo de banderas
- Muestra los nombres de los idiomas como texto
- Indica claramente el idioma actualmente seleccionado
- Asegúrate de que pueda operarse solo con teclado
- Después del cambio, devuelve el foco a la parte superior de la página o a un encabezado si es necesario
La multilingüización debe comunicar correctamente no solo a las personas que entienden el idioma, sino también a quienes usan tecnologías de asistencia.
10. Atributo HTML lang: afecta directamente la calidad de los lectores de pantalla
Una parte del soporte multilingüe que se olvida fácilmente es el atributo HTML lang.
Refleja el idioma actual en el archivo de layout.
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<title>{{ $title ?? config('app.name') }}</title>
</head>
<body>
{{ $slot ?? '' }}
</body>
</html>
Si toda la página está en japonés, usa lang="ja". Si está en inglés, usa lang="en".
Si aparece otro idioma dentro de la página, agrega lang a esa parte específica.
<p>
サービス名は <span lang="en">Accessible Laravel</span> です。
</p>
Los lectores de pantalla pueden cambiar la pronunciación según el atributo lang.
Por lo tanto, si lang es incorrecto, el inglés puede leerse con pronunciación japonesa, o el japonés puede sonar de forma poco natural.
Es difícil notarlo visualmente, pero es muy importante para la accesibilidad.
11. Mensajes de validación multilingües
Los mensajes de validación son especialmente importantes en la localización de formularios.
Laravel usa lang/{locale}/validation.php para gestionar los mensajes.
Ejemplo:
return [
'required' => ':attribute は必須です。',
'email' => ':attribute はメールアドレスの形式で入力してください。',
'max' => [
'string' => ':attribute は :max 文字以内で入力してください。',
],
'attributes' => [
'name' => 'お名前',
'email' => 'メールアドレス',
'password' => 'パスワード',
],
];
También puedes usar attributes() en un FormRequest.
public function attributes(): array
{
return [
'name' => __('forms.name'),
'email' => __('forms.email'),
];
}
Sin embargo, si las llamadas de traducción se vuelven demasiado complejas aquí, la legibilidad se resiente, por lo que es mejor decidir una política de equipo.
En general, los campos comunes son más fáciles de gestionar en la sección attributes de validation.php, mientras que los campos específicos de una pantalla pueden agregarse en el FormRequest.
12. Visualización de errores: mantén una estructura clara después de traducir
Al multilingüizar una aplicación, la longitud del texto cambia según el idioma. Una frase corta en inglés puede volverse larga en alemán o francés. Incluso al traducir del japonés al inglés, pueden cambiar el ancho de los botones y el número de líneas de los mensajes de error.
Usa una estructura estándar como esta para mostrar errores.
@if ($errors->any())
<div id="error-summary" role="alert" tabindex="-1" class="border p-3 mb-4">
<h2>{{ __('forms.error_summary_title') }}</h2>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
Campo de entrada:
<label for="email">{{ __('forms.email') }}</label>
<input
id="email"
name="email"
type="email"
value="{{ old('email') }}"
aria-invalid="{{ $errors->has('email') ? 'true' : 'false' }}"
aria-describedby="{{ $errors->has('email') ? 'email-error' : 'email-help' }}"
>
<p id="email-help">{{ __('forms.email_help') }}</p>
@error('email')
<p id="email-error">{{ $message }}</p>
@enderror
Diseña los espacios y los saltos de línea para que la estructura no se rompa aunque el texto traducido sea más largo.
Para interfaces multilingües, es más seguro evitar botones y etiquetas de ancho fijo que asumen una sola línea.
13. Fechas, horas y zonas horarias: considera no solo el idioma, sino también la región
Las fechas y horas también son importantes en la multilingüización.
Laravel suele usar Carbon, pero si los formatos de visualización son cadenas fijas, se vuelve difícil admitir diferencias regionales.
Mal ejemplo:
{{ $post->published_at->format('Y/m/d H:i') }}
Este formato es fácil de leer en Japón, pero puede no sentirse natural en regiones de habla inglesa.
En la práctica, crear un formateador de visualización ayuda a mantener todo organizado.
class DateFormatter
{
public function date($value): string
{
return match (app()->getLocale()) {
'ja' => $value->format('Y年n月j日'),
'en' => $value->format('F j, Y'),
default => $value->toDateString(),
};
}
}
Blade:
{{ app(DateFormatter::class)->date($post->published_at) }}
Al manejar horas, las zonas horarias también son importantes.
Si cada usuario tiene un timezone, convierte la hora al mostrarla.
$post->published_at
->timezone($user->timezone ?? config('app.timezone'))
->format('Y-m-d H:i');
Desde una perspectiva de accesibilidad, también es importante evitar fechas ambiguas.
Por ejemplo, en lugar de decir solo “mañana” o “la próxima semana”, agregar una fecha específica cuando sea necesario reduce malentendidos.
14. Números, moneda y unidades: alinea el significado, no solo la apariencia
Los formatos de moneda y números también varían por región.
Para yenes japoneses, podrías mostrar ¥1,000; para dólares estadounidenses, $1,000.00. Los decimales y símbolos varían según la moneda.
Ejemplo simple:
class MoneyFormatter
{
public function format(int $amount, string $currency = 'JPY'): string
{
return match ($currency) {
'JPY' => '¥' . number_format($amount),
'USD' => '$' . number_format($amount / 100, 2),
default => number_format($amount),
};
}
}
Sin embargo, el soporte serio para varias monedas requiere decisiones de diseño, como almacenar los importes en la unidad mínima de la moneda, guardar códigos de moneda y estandarizar reglas de redondeo.
Aunque la visualización esté traducida, los importes de facturación y pago no deben ser ambiguos.
Lo mismo aplica a las unidades.
- km / millas
- kg / lb
- Celsius / Fahrenheit
Si las unidades requeridas difieren según la región objetivo, revisa no solo la capa de visualización, sino también el diseño de datos.
15. Correos electrónicos multilingües: decide claramente el idioma al momento del envío
A diferencia de las pantallas web, los correos electrónicos no pueden cambiar de idioma después de ser enviados.
Por lo tanto, debes decidir claramente qué idioma usar en el momento del envío.
El enfoque básico es usar el locale del usuario.
Mail::to($user->email)
->locale($user->locale)
->send(new WelcomeMail($user));
Usa traducciones también en la vista del Mailable.
<h1>{{ __('emails.welcome_title') }}</h1>
<p>{{ __('emails.welcome_body', ['name' => $user->name]) }}</p>
Para los correos electrónicos, presta especial atención a lo siguiente.
- Traduce también el asunto
- Prepara versiones HTML y de texto plano
- Haz que el texto de los enlaces sea específico
- Divide los textos largos en párrafos cortos
- No comuniques información solo mediante imágenes
Los entornos de correo electrónico varían mucho, por lo que una estructura simple y clara es aún más importante que en pantallas web.
16. Nombres de rutas y URL traducidas: decide hasta dónde traducir
En sitios multilingües, si se debe traducir la ruta de la URL también es una decisión importante.
Ejemplo sin rutas traducidas:
/ja/products
/en/products
Ejemplo con rutas traducidas:
/ja/shohin
/en/products
Las rutas URL traducidas pueden sentirse más naturales para los usuarios.
Por otro lado, el enrutamiento, la generación de enlaces, las redirecciones, el SEO y el mantenimiento se vuelven más complejos.
En la práctica, es más seguro comenzar con rutas comunes como /ja/products y luego considerar URL traducidas si la necesidad se vuelve fuerte.
En particular, para pantallas administrativas, traducir las URL suele ser innecesario.
También es natural usar políticas distintas para sitios públicos y pantallas administrativas.
17. SEO: organiza hreflang y URL canónicas
Al multilingüizar un sitio público, también es necesario diseñar el SEO.
Si existen páginas específicas por idioma, usa hreflang para mostrar la relación entre ellas.
<link rel="alternate" hreflang="ja" href="https://example.com/ja/products">
<link rel="alternate" hreflang="en" href="https://example.com/en/products">
<link rel="alternate" hreflang="x-default" href="https://example.com/">
Las URL canónicas también deben configurarse adecuadamente para cada idioma.
Si todas las páginas de distintos idiomas apuntan a la misma URL canónica, los motores de búsqueda pueden no gestionar correctamente las páginas separadas por idioma.
Los títulos de página, meta descripciones y contenido OGP también deben incluirse entre los objetivos de traducción.
Es sorprendentemente común que solo se traduzca el cuerpo del texto mientras la información meta permanece en japonés, así que inclúyelo en tu checklist.
18. Caché: separa las claves por idioma
La multilingüización y la caché funcionan bien juntas, pero si las claves de caché están mal diseñadas, los idiomas pueden mezclarse.
Por ejemplo, si la página principal en japonés queda en caché y se devuelve esa misma caché a usuarios en inglés, se convierte en un problema grave.
Incluye siempre el idioma en las claves de caché.
$key = 'home:' . app()->getLocale();
$posts = Cache::remember($key, 300, function () {
return Post::published()->latest()->take(10)->get();
});
Si también intervienen tenants o configuraciones de usuario, inclúyelos igualmente.
$key = sprintf(
'dashboard:%s:tenant:%d:user:%d',
app()->getLocale(),
tenant()->id,
auth()->id()
);
En la multilingüización, recuerda esta premisa: aunque la página parezca igual, cada idioma necesita una caché separada.
19. Operación de traducciones: revisa los archivos de traducción como “código”
Los archivos de traducción no son solo colecciones de texto.
Afectan directamente el significado de las pantallas, la comunicación de errores, las acciones de botones y la confianza del usuario.
Por lo tanto, los archivos de traducción deben revisarse como código.
Entre las reglas operativas a decidir están las siguientes.
- Estandarizar el estilo de redacción
- Decidir reglas para el texto de botones
- Incluir la causa y la siguiente acción en los mensajes de error
- Decidir reglas de nomenclatura para claves de traducción
- Limpiar regularmente claves no utilizadas
- Detectar traducciones faltantes en pruebas o CI
Por ejemplo, un texto de botón como “保存” puede ser más claro como “保存する” porque describe una acción.
En inglés también es importante usar textos específicos según el contexto, como Save, Update profile y Send invitation.
Más corto no siempre es mejor. Prioriza que los usuarios entiendan qué hace el botón.
20. Pruebas: evita traducciones faltantes e interfaces rotas
En la multilingüización, las pruebas de visualización por idioma son útiles además de las pruebas funcionales normales.
20.1 Prueba de visualización en japonés
public function test_homepage_is_displayed_in_japanese()
{
$response = $this->get('/ja/products');
$response->assertOk()
->assertSee('商品');
}
20.2 Prueba de visualización en inglés
public function test_homepage_is_displayed_in_english()
{
$response = $this->get('/en/products');
$response->assertOk()
->assertSee('Products');
}
20.3 Idiomas no admitidos devuelven 404
public function test_unsupported_locale_returns_404()
{
$this->get('/xx/products')
->assertNotFound();
}
20.4 Prueba de mensaje de validación
public function test_validation_message_is_localized()
{
$response = $this->post('/ja/contact', [
'email' => '',
]);
$response->assertSessionHasErrors('email');
}
Con pruebas de navegador como Dusk, también puedes comprobar si traducciones largas rompen botones y si el cambio de idioma funciona con teclado.
21. Errores comunes y cómo evitarlos
21.1 Traducir solo el texto de pantalla mientras la validación sigue en japonés
Esto hace que la experiencia del formulario sea poco natural.
Traduce también validation.php y los nombres de atributos.
21.2 No actualizar el atributo lang
Esto afecta la pronunciación de los lectores de pantalla.
Refleja app()->getLocale() en el layout.
21.3 No incluir el idioma en las claves de caché
Esto causa que páginas de distintos idiomas se mezclen.
Incluye siempre el locale en las claves de caché.
21.4 Representar el cambio de idioma solo con banderas
Los países y los idiomas no son lo mismo.
Muestra los nombres de los idiomas como texto.
21.5 La interfaz se rompe cuando el texto traducido se vuelve más largo
Diseña interfaces multilingües considerando longitud variable del texto, espaciado y saltos de línea.
21.6 Dejar el diseño de URL para más adelante
Cambiarlo después dificulta redirecciones y soporte SEO.
Decide pronto si usar URL como /ja/... o un enfoque basado en sesión.
22. Checklist para distribución
Diseño básico
- [ ] Los idiomas admitidos están decididos
- [ ] Se ha decidido si incluir el idioma en las URL o gestionarlo mediante configuraciones de usuario
- [ ]
localeyfallback_localeestán configurados
Archivos de traducción
- [ ] Los archivos de traducción se gestionan con
lang:publish - [ ] Se han decidido reglas para traducciones en arrays PHP y traducciones JSON
- [ ] Los mensajes de validación y nombres de atributos están traducidos
- [ ] Los asuntos y cuerpos de correo electrónico están incluidos en los objetivos de traducción
UI / Accesibilidad
- [ ]
<html lang="">refleja el idioma actual - [ ] El cambio de idioma no depende solo de banderas
- [ ] El idioma seleccionado se indica con
aria-currento similar - [ ] Los resúmenes de errores están asociados con los campos de entrada
- [ ] La interfaz no se rompe cuando el texto traducido se vuelve más largo
Fechas / Números
- [ ] Los formatos de fecha coinciden con el idioma o región
- [ ] Se consideran las zonas horarias
- [ ] Existen reglas para mostrar monedas y unidades
SEO / Caché
- [ ]
hreflangestá configurado en páginas públicas - [ ] Los meta títulos y descripciones están traducidos
- [ ] Las claves de caché incluyen el locale
Pruebas
- [ ] Existen pruebas de visualización para cada idioma admitido
- [ ] Los idiomas no admitidos devuelven 404
- [ ] Se revisan las traducciones de mensajes de validación
- [ ] La interfaz de cambio de idioma puede operarse con teclado
23. Conclusión
La multilingüización en Laravel puede comenzar traduciendo textos con __(). Sin embargo, en proyectos reales, debes considerar archivos de traducción, diseño de URL, validación, fechas, monedas, correos electrónicos, SEO, caché, pruebas y accesibilidad.
Primero, decide los idiomas admitidos y el diseño de URL, organiza los textos en el directorio lang y configura correctamente el locale con middleware. Luego amplía el soporte hacia validación, correos electrónicos, fechas y formato de números para crear una experiencia más natural para los usuarios.
La accesibilidad es especialmente importante: el atributo lang, el cambio de idioma basado en texto y los mensajes de error claros importan. La multilingüización no es solo soporte para usuarios extranjeros. También es una práctica de diseño para entregar información correctamente a usuarios diversos. Empieza pequeño y luego mejora gradualmente las traducciones y la interfaz.

