Internacionalización (i18n) en Kotlin: desde lo básico hasta técnicas avanzadas
La internacionalización (abreviada i18n — del inglés «internationalization», donde 18 es el número de letras entre la primera «i» y la última «n») es el proceso de diseñar software de manera que pueda adaptarse fácilmente a diferentes idiomas y estándares regionales sin realizar cambios en el código. Para Kotlin, como lenguaje multiplataforma moderno, el soporte de i18n es especialmente importante, ya que las aplicaciones construidas con él funcionan en Android, backend (JVM), web (Kotlin/JS) y plataformas nativas (Kotlin/Native).
En este artículo, veremos cómo organizar correctamente la internacionalización en proyectos Kotlin: desde enfoques básicos con archivos de recursos hasta soluciones avanzadas con bibliotecas auxiliares.
1. Enfoque básico: archivos de recursos (ResourceBundle)
La forma más simple y común es usar los mecanismos estándar de Java ResourceBundle y archivos de propiedades (.properties). Este método funciona muy bien para proyectos JVM (Android, Spring Boot, aplicaciones de consola).
Paso 1. Crear archivos de localización
Cree en los recursos del proyecto archivos como messages.properties (predeterminado) y messages_es.properties (para español):
# messages.properties (inglés, idioma predeterminado)greeting=Hello, {0}!farewell=Goodbye, {0}!app.title=My Application
# messages_es.properties (español)greeting=¡Hola, {0}!farewell=¡Adiós, {0}!app.title=Mi AplicaciónPaso 2. Cargar y usar en Kotlin
Cree un objeto auxiliar para trabajar con la localización:
import java.text.MessageFormatimport java.util.*
object I18n { private var bundle: ResourceBundle = ResourceBundle.getBundle("messages", Locale.getDefault())
fun setLocale(locale: Locale) { bundle = ResourceBundle.getBundle("messages", locale) }
fun get(key: String, vararg args: Any?): String { val pattern = bundle.getString(key) return MessageFormat.format(pattern, *args) }}
fun main() { // Usamos inglés por defecto println(I18n.get("greeting", "Alice")) // Hello, Alice!
// Cambiamos a español I18n.setLocale(Locale("es")) println(I18n.get("greeting", "Alicia")) // ¡Hola, Alicia!}2. Biblioteca kotlin-i18n (de JetBrains)
Para Kotlin Multiplatform existe la biblioteca oficial kotlin-i18n, que permite trabajar con traducciones en todas las plataformas de manera uniforme. Utiliza el formato Gettext PO (Portable Object), que es conveniente para traductores.
Instalación (Gradle)
repositories { mavenCentral()}dependencies { implementation("org.jetbrains.kotlinx:kotlin-i18n:0.1.0")}Ejemplo de uso
import org.jetbrains.kotlinx.i18n.*
fun main() { // Creamos un traductor cargando desde archivos PO val translator = Translator( bundleName = "messages", locale = Locale("es") )
// Usamos con sustitución de parámetros val message = translator.translate( "greeting", "Mundo" ) println(message) // ¡Hola, Mundo!}Ventajas: soporte de plurales (plural forms), contextos de traducción, funciona en todas las plataformas Kotlin.
3. Enfoque avanzado: biblioteca ok-i18n
Para proyectos que requieren flexibilidad e integración con contenedores DI (por ejemplo, Koin o Dagger), la biblioteca ok-i18n es ideal. Soporta formato JSON para traducciones, lo cual es conveniente al trabajar con API REST o archivos de configuración.
Ejemplo de archivo JSON de traducción (es.json)
{ "app": { "title": "Mi