Mojibake: el hijo de puta que convierte “información” en “información”
Porque hay una tesis de marketing detrás: no solamente es un problema técnico; afecta percepción de marca y confianza.
El misterio del Mojibake: Cuando tu web habla en lenguas muertas
Todo funcionaba, el formulario enviaba, el correo llegaba, el diseño estaba bonito, analytics estaba puesto y conectado, el sitio no se había incendiado y entonces apareció esto:
Los datos enviados mediante este formulario sern utilizados para atender tu solicitud.
Perfecto. Otra vez.
Porque, al parecer hay bugs que aparecen una vez, los arreglas y se van. Y luego está el Mojibake, que en mi caso ya decidió convertirse en un personaje recurrente.
Primero pasó en el desarrollo web de grupo Antiova, después en AHÁ y cuando estaba preparando este sitio web, Marketing Chafa para producción apareció ese hermoso "sern" en el formulario de contacto.
Ya es personal.
¿Qué chingados es mojibake?
Mojibake es básicamente lo que ocurre cuando dos sistemas están viendo el mismo texto, pero no están de acuerdo sobre cómo interpretarlo.
Tú escribes: información y alguna parte de tu sistema decide interpretar esos bytes de otra manera. Entonces obtienes: información. O escribes: ¿Quieres hablar? y recibes: ¿Quieres hablar?
O, en el peor de los casos, aparece nuestro querido:
Ese rombito negro con signo de interrogación es básicamente la computadora diciéndote:
“No tengo ni puta idea de qué carácter iba aquí.”
Técnicamente, el problema está relacionado con la codificación de caracteres, humanamente, significa que una parte de tu sistema habla UTF-8 y otra está hablando algún dialecto ancestral que nadie invitó a la fiesta.
El carácter raro no es el problema. Esto fue algo que aprendí a golpes.
Cuando ves: "información", la tentación inmediata es buscar dónde dice información, cambiarlo por "información" y seguir con tu vida. Pero eso es como tener una tubería rota y resolver el problema secando el piso.
El mojibake casi siempre es un síntoma, la causa puede estar en prácticamente cualquier punto del recorrido:
- el archivo donde escribiste el texto;
- PHP;
- los headers HTTP;
- el HTML;
- PDO;
- MySQL;
- la configuración de la base de datos;
- el CMS;
- un formulario;
- el correo;
- o datos que ya estaban guardados incorrectamente desde antes.
Y aquí empieza lo divertido, porque todo puede parecer estar en UTF-8, el HTML dice UTF-8, el editor dice UTF-8, la base de datos supuestamente dice UTF-8, tú dices UTF-8, tu perro probablemente también dice UTF-8 y aun así aparece: José Muñoz
“Pues ponle UTF-8” Gracias, Stack Overflow. Ojalá fuera tan sencillo.
Una de las primeras cosas que cualquiera aprende cuando empieza a trabajar con HTML es esto:
<meta charset="UTF-8">
Y sí. Debe estar. Pero ese pequeño meta tag no tiene poderes sobrenaturales.
Si tu archivo está mal codificado, no lo arregla.
Si PHP envía headers incorrectos, no lo arregla.
Si PDO se conecta a MySQL utilizando otro charset, no lo arregla.
Si los datos ya están corruptos dentro de la base de datos, tampoco los arregla.
UTF-8 tiene que funcionar de extremo a extremo. Algo así:
ARCHIVO
↓
PHP
↓
PDO
↓
MYSQL
↓
PDO
↓
PHP
↓
HTTP
↓
HTML
↓
NAVEGADOR
Todos tienen que estar de acuerdo, porque basta con que uno de esos cabrones decida interpretar el texto de manera diferente para que: serán termine convertido en: serán
Y entonces aparece utf8mb4, porque claro, no podía simplemente llamarse UTF-8 y ya.
En MySQL existe una distinción importante entre utf8 y utf8mb4. Durante años, el charset llamado utf8 de MySQL no implementaba completamente todo lo que normalmente entendemos por UTF-8. utf8mb4 permite representar correctamente Unicode utilizando hasta cuatro bytes por carácter.
Traducción: Si estás desarrollando algo moderno y tienes control sobre la configuración, normalmente quieres utf8mb4. Especialmente si alguna vez pretendes guardar:
- idiomas distintos;
- caracteres especiales;
- símbolos;
- emojis;
- o cualquier cosa escrita por seres humanos fuera de un formulario diseñado en 2007.
Por eso una conexión PDO decente debería especificar algo como:
charset=utf8mb4
Pero aquí viene otro detalle importante. NO conviertas toda la base de datos a lo pendejo.
Esta es probablemente la parte donde más fácil puedes convertir un problema molesto en un problema realmente cabrón. Imagina que encontraste mojibake. Revisas MySQL. Ves algo que no te gusta. Y dices: "Ah, fácil. Convierto todo a utf8mb4." Detente. Porque una cosa es "cómo está declarada una columna" y otra muy distinta es "qué bytes contiene realmente".
Si los datos ya están correctamente almacenados y el problema únicamente ocurre al interpretarlos, hacer conversiones sin entender qué está pasando puede terminar corrompiendo información que estaba perfectamente sana.
Y así pasamos de: "serán" a: "serán" y, si tienes especial talento: "serán". Felicidades. Acabas de crear mojibake sobre mojibake. El equivalente digital de echarle cinta adhesiva a otra cinta adhesiva.
Por eso la regla debería ser: Primero encuentra dónde se rompe la cadena. Después corrige. No al revés.
La peor solución: JavaScript exorcista
En algún punto de tu carrera podrías encontrarte con algo así:
texto = texto.replace("á", "á");
texto = texto.replace("é", "é");
texto = texto.replace("ñ", "ñ");
Funciona. Técnicamente. Igual que poner una cubeta debajo de una gotera también funciona.
El problema es que no estás solucionando absolutamente nada. Solo estás esperando a que el contenido llegue roto al navegador para repararlo visualmente después.
Y eventualmente terminas con una maravillosa función llamada: fixMojibakeFinalAhoraSiDefinitivo.js con 37 reemplazos, tres excepciones y un MutationObserver recorriendo todo el DOM porque Dios nos abandonó.
Si el texto es: información
el servidor debería entregar: información
No: información para que JavaScript juegue a reconstruir cadáveres.
Cómo decidí blindar Marketing Chafa
Después de encontrar mojibake en varios proyectos entendí que seguir arreglando apariciones individuales era absurdo.
Así que para Marketing Chafa decidí tratarlo como un problema de infraestructura. La idea fue garantizar UTF-8 —y utf8mb4 donde corresponde— en toda la cadena:
Archivos
Todos los archivos de código y contenido deben estar guardados correctamente como UTF-8. Preferiblemente sin BOM.
HTML
Cada página debe declarar:
<meta charset="UTF-8">
HTTP
Las respuestas HTML tienen que indicar correctamente:
Content-Type: text/html; charset=UTF-8
PHP
Nada de conversiones arbitrarias utilizando funciones como utf8_encode() o utf8_decode() para “arreglar” strings que nadie comprobó primero.
PDO
La conexión a MySQL debe negociar explícitamente:
charset=utf8mb4
MySQL
Revisar charset y collation reales de la base de datos, tablas y columnas. Pero revisar primero. No correr ALTER TABLE como si estuvieras tratando de desactivar una bomba.
CMS
Crear contenido. Guardarlo. Editar. Volverlo a consultar. Mostrarlo en frontend. Y comprobar que siga siendo exactamente el mismo texto.
Formularios
Probar el recorrido completo:
Navegador
↓
Formulario
↓
PHP
↓
MySQL
↓
Dashboard
↓
Correo
Sin transformaciones mágicas en medio.
La prueba del crème brûlée
Tengo una nueva prueba favorita para cualquier CMS. La llamo: La prueba del crème brûlée.
Consiste en guardar algo deliberadamente incómodo:
José Muñoz pidió piña, jalapeño y crème brûlée. ¿Está bien? ¡Sí! — edición 2026™.
¿Por qué? Porque ahí tienes:
- é;
- ñ;
- á;
- caracteres franceses;
- signos de interrogación españoles;
- signos de exclamación;
- guión largo;
- números;
- símbolo de marca.
Lo guardas. Lo consultas. Lo editas. Lo vuelves a guardar. Lo imprimes en frontend.
Si después de recorrer todo el sistema sigue diciendo:
José Muñoz pidió piña, jalapeño y crème brûlée. ¿Está bien? ¡Sí! — edición 2026™.
Excelente.
Si dice:
José Muñoz pidió piña...
Bueno. Encontraste trabajo para la tarde.
“Pero es solo un carácter raro”
Aquí es donde este problema deja de ser únicamente técnico.
Porque tú sabes qué es un charset. El desarrollador sabe qué es UTF-8. El servidor sabe… bueno, aparentemente no siempre sabe.
Pero el usuario no tiene por qué saber nada de eso. El usuario simplemente entra a una página y ve:
Información de contacto
Y piensa: “Esta página está rota.”
Eso es todo. No piensa: “Seguramente existe una discrepancia entre la interpretación Windows-1252 de una secuencia originalmente codificada en UTF-8.”
No. Piensa: “Qué chafa.”
Y en una página de una empresa eso afecta algo mucho más importante que la belleza del código: la confianza.
Puedes tener:
- un branding increíble;
- fotografía espectacular;
- una interfaz bien diseñada;
- animaciones mamalonas;
- SEO;
- Analytics;
- automatizaciones;
- un CMS;
- una estrategia digital perfectamente pensada.
Pero aparece: Contáctanos para más información y de repente toda esa percepción de calidad se desploma un poquito.
Porque los detalles técnicos también comunican marca.
El software también tiene acabados
En diseño hablamos muchísimo sobre cuidar detalles. Kerning. Espaciados. Contraste. Jerarquía. Fotografía. Microinteracciones.
Pero cuando hacemos productos digitales parece que a veces olvidamos que también existen acabados técnicos.
Una página que devuelve errores. Un formulario que no funciona. Una imagen rota. Un botón muerto. Un información.
Todo comunica. Incluso las cosas que el usuario jamás debería notar. De hecho, el mejor resultado suele ser justamente ese: que nadie note nada.
Nadie va a entrar a tu web y decir:
“Qué increíble implementación de utf8mb4.”
Y está bien. El objetivo es que puedan escribir: ¿Me das información sobre diseño y fotografía? y que tu sistema responda: Sí.
No: SÃ.
Conclusión: , te estoy viendo
El mojibake probablemente no va a destruir una empresa. No va a tumbar tu servidor. No va a vaciar tu cuenta bancaria. Probablemente ni siquiera sea el bug técnicamente más grave de tu proyecto.
Pero es exactamente el tipo de error pequeño que convierte una experiencia que parecía profesional en algo que se siente descuidado.
Y después de encontrarlo en Antiova, AHÁ y ahora Marketing Chafa, aprendí dos cosas.
La primera: UTF-8 no se “pone”. Se garantiza en toda la cadena.
La segunda: si alguna vez vuelvo a ver un:
en producción… ya no será debugging.
Será venganza.