Colisión de Caché NGINX en WordPress Multilingüe
Cómo RG Digital desarrolló su propia arquitectura multilingüe para WordPress y rastreó un comportamiento inesperado en producción hasta la interacción entre el estado de la aplicación y la caché del servidor.
Una aplicación técnicamente correcta puede fallar incluso antes de que WordPress ejecute una sola línea de su lógica.
Eso fue exactamente lo que descubrimos mientras validábamos la arquitectura bilingüe de RG Digital.
En lugar de adoptar un plugin multilingüe de propósito general, diseñamos nuestra propia arquitectura de idioma y desarrollamos RG Language Bridge, un plugin personalizado para WordPress responsable de la asignación de idioma, relaciones editoriales, generación de hreflang, idioma de schema, routing y comportamiento determinístico del selector de idioma.
La aplicación se comportaba correctamente. El plugin leía correctamente las preferencias de idioma. Las páginas de destino se resolvían como esperábamos. Los códigos de estado HTTP generados eran los correctos.
Aun así, un visitante que había seleccionado explícitamente Español podía terminar siendo redirigido a la versión en Inglés del sitio.
El problema no estaba en la arquitectura de idioma.
El problema existía una capa antes.
Por Qué Desarrollamos Nuestra Propia Capa Multilingüe
WordPress ya cuenta con soluciones multilingües maduras como WPML y Polylang. Son plataformas capaces de resolver necesidades amplias de traducción y publicación multilingüe para miles de escenarios diferentes.
Nuestro requerimiento era más específico y, sobre todo, más arquitectónico.
No necesitábamos una plataforma de gestión de traducciones que definiera cómo debía comportarse el sitio. Necesitábamos una capa de aplicación pequeña que implementara un contrato que pudiéramos definir, inspeccionar, probar y controlar directamente.
La arquitectura requería URLs independientes por idioma, relaciones editoriales explícitas entre páginas equivalentes, salida hreflang predecible, routing controlado y un sistema determinístico de fallback.
Arquitectura Explícita
El comportamiento del idioma sigue un contrato de aplicación diseñado específicamente para el sitio, en lugar de depender del modelo interno de una plataforma multilingüe de propósito general.
Solo lo que Necesitamos
El sistema administra idioma, pairing editorial, hreflang, schema language, switching y routing sin introducir una capa adicional de gestión de traducciones.
Comportamiento Predecible
Cada redirect, fallback y relación existe dentro de nuestro propio código y puede auditarse contra un contrato arquitectónico claramente definido.
No necesitábamos otra capa de traducción. Necesitábamos una arquitectura de idioma.
Esa decisión nos llevó al desarrollo de RG Language Bridge.
Un Plugin Pequeño con un Contrato Explícito
RG Language Bridge no traduce páginas automáticamente.
Inglés y Español permanecen como experiencias editoriales independientes. El plugin crea y hace cumplir las relaciones necesarias para que ambas funcionen como un solo sistema multilingüe coherente.
Cada responsabilidad se mantiene deliberadamente pequeña.
Rank Math permanece a cargo de canonical URLs, sitemap y de la capa SEO general. RG Language Bridge únicamente controla las responsabilidades multilingües que pertenecen a su alcance arquitectónico.
Simetría Estructural No Significa Equivalencia Editorial
Una de las reglas más importantes dentro de RG Language Bridge es que dos páginas no se emparejan únicamente porque ocupen una posición similar dentro de las estructuras en Inglés y Español.
Un pairing existe solamente cuando dos páginas representan el mismo contenido editorial para audiencias en idiomas diferentes.
El segundo ejemplo puede ser estructuralmente simétrico, pero el contenido no es equivalente.
En ese caso, las páginas permanecen intencionalmente sin pairing y RG Language Bridge no genera una relación hreflang artificial entre ellas.
Una arquitectura multilingüe debe representar relaciones de contenido que realmente existen, no relaciones que simplemente resultan convenientes dentro de un árbol de URLs.
El Selector Resuelve la Intención en Lugar de Adivinar URLs
El selector de idioma no sustituye mecánicamente /en/ por /es/, ni asume que necesariamente debe existir una URL equivalente.
Sigue una secuencia de resolución determinística.
Esto permite preservar la intención del visitante sin fabricar relaciones entre contenidos que no son realmente equivalentes.
Por ejemplo, una página de Casos de Estudio sin pairing puede resolver su destino mediante su Home emparejado y llevar al visitante al punto de entrada correcto del otro idioma.
Una URL con Múltiples Estados Válidos de Aplicación
Las experiencias en Inglés y Español viven en rutas independientes:
La URL raíz tiene una responsabilidad diferente.
No representa una página de contenido. Funciona como punto de entrada y router de la arquitectura multilingüe.
Ruta Predeterminada
Un visitante sin una preferencia almacenada recibe el Home en Inglés como destino predeterminado.
Inglés Explícito
Un visitante que seleccionó Inglés mantiene esa preferencia mediante un redirect temporal.
Español Explícito
Un visitante que seleccionó Español es dirigido directamente a la experiencia en Español.
Durante las pruebas de aplicación, ese contrato se comportó exactamente como había sido diseñado.
Entonces producción se comportó de manera diferente.
El Primer Sospechoso Fue Nuestro Propio Código
Durante la validación en producción, un visitante con una preferencia explícita por Español podía recibir el redirect permanente hacia Inglés desde la URL raíz.
Debido a que el componente de routing había sido desarrollado por nosotros, la primera pregunta era evidente:
¿Existía un defecto dentro de RG Language Bridge?
Antes de responsabilizar al entorno de hosting o introducir cambios adicionales en infraestructura, auditamos nuestra propia capa de aplicación.
Revisamos la lógica de redirects, manejo de cookies, validación de idioma y comportamiento del router contra el contrato arquitectónico.
Después pasamos de la revisión estática del código al aislamiento del comportamiento en runtime.
Una Solicitud Única Cambió la Investigación
Repetimos la solicitud utilizando un query string único que no podía existir previamente como la misma solicitud dentro de la caché del servidor.
Esta vez, la respuesta coincidió exactamente con lo que exigía el contrato de la aplicación.
La misma prueba con una preferencia explícita por Inglés también se comportó correctamente.
RG Language Bridge estaba leyendo correctamente la cookie y produciendo la decisión de routing esperada.
Algo más estaba devolviendo la respuesta incorrecta antes de que esa lógica de aplicación tuviera oportunidad de ejecutarse.
Cuando la Caché Consideró Equivalentes Dos Solicitudes Diferentes
Identificamos la caché de servidor NGINX como la siguiente variable y reproducimos el comportamiento mediante una secuencia controlada.
Primero limpiamos completamente la caché.
La segunda solicitud generó legítimamente la respuesta predeterminada 301 → /en/.
NGINX almacenó esa respuesta en caché.
Cuando llegó una nueva solicitud con una preferencia explícita por Español, la caché devolvió el redirect previamente almacenado sin considerar el estado de aplicación representado por la cookie de idioma.
WordPress nunca tuvo oportunidad de evaluar esa preferencia.
Más PHP No Podía Corregir una Solicitud que Nunca Llegaba a PHP
Las ramas correspondientes a preferencias explícitas ya estaban enviando headers restrictivos de caché.
Esos headers eran correctos.
Pero solamente existían después de que WordPress ejecutaba la lógica del router.
Una vez que NGINX ya tenía almacenada una representación de la URL raíz, podía responder a la siguiente solicitud antes de que PHP, WordPress o RG Language Bridge se ejecutaran.
En la solicitud que fallaba, la ejecución efectivamente se detenía en el segundo nodo.
Incluso enviar explícitamente desde el cliente headers como:
no modificó la respuesta almacenada.
El código de aplicación no puede corregir una decisión tomada antes de que la aplicación se ejecute.
Eliminar una Variable y Repetir Exactamente la Misma Prueba
Para confirmar el diagnóstico, desactivamos la caché NGINX y repetimos exactamente la misma secuencia.
Nada más cambió.
La misma instalación de WordPress.
La misma versión de RG Language Bridge.
El mismo contrato de routing.
Las mismas cookies.
Las mismas URLs.
La única variable eliminada fue la caché NGINX.
Eso aisló la falla en la capa de infraestructura.
Cada Componente Era Correcto de Forma Aislada
Aquí es donde el debugging deja de ser un problema de componentes y se convierte en un problema de arquitectura.
RG Language Bridge evaluaba correctamente la preferencia de idioma.
WordPress ejecutaba correctamente la lógica de aplicación.
NGINX almacenaba correctamente respuestas repetidas según su política de caché.
La falla apareció porque la caché consideraba equivalentes dos solicitudes que la aplicación, deliberadamente, trataba como estados diferentes.
Una caché no puede reutilizar de forma segura una respuesta cuando la aplicación depende de un estado que esa caché no está considerando.
Aplicar Caché Según la Responsabilidad de Cada Ruta
Desde una perspectiva arquitectónica, la solución ideal no era eliminar la caché de forma general.
El router de idioma y las URLs de contenido tienen responsabilidades diferentes y, en un entorno con suficiente granularidad de configuración, pueden utilizar políticas de caché distintas.
Bypass de Caché Cuando Existe la Cookie de Idioma
Cuando la URL raíz recibe una solicitud que contiene rg_lang_pref, la caché NGINX puede omitirse para permitir que RG Language Bridge evalúe la preferencia explícita del visitante.
No Almacenar en Caché el Router Raíz
Si no están disponibles reglas de bypass basadas en cookies, una alternativa es excluir únicamente la URL raíz de la caché del servidor mientras las URLs de contenido en Inglés y Español permanecen cacheables.
Esta era la arquitectura preferida: permitir que el contenido siguiera beneficiándose de la caché mientras el router conservaba acceso al estado necesario para tomar su decisión.
La implementación final, sin embargo, tenía que adaptarse a las capacidades reales del entorno de hosting.
Adaptar la Solución a las Restricciones del Entorno
Nuestra solución preferida consistía en omitir la caché NGINX únicamente cuando el router raíz necesitara evaluar una solicitud con la cookie rg_lang_pref.
El entorno de hosting no permitía aplicar ese nivel de granularidad directamente en la configuración compartida de NGINX para rgdigital.mx sin afectar la configuración utilizada por los demás dominios de la cuenta.
La solución disponible en producción fue, por lo tanto, más amplia.
Mediante la configuración .htaccess específica de RG Digital se añadieron encabezados HTTP que indican que las respuestas del sitio no deben almacenarse ni reutilizarse desde la caché del servidor.
De esta forma, el cambio quedó encapsulado dentro del dominio rgdigital.mx. NGINX continúa formando parte de la infraestructura y los demás dominios de la cuenta conservan su configuración de caché.
El tradeoff es explícito: las páginas HTML de RG Digital dejaron de beneficiarse de la caché de servidor NGINX.
Bajo las restricciones actuales del hosting, priorizamos la corrección del routing y una experiencia multilingüe consistente sobre conservar una optimización de caché que no podía distinguir de forma segura entre los diferentes estados de la aplicación.
La lógica de aplicación no necesitó cambiar. La política de caché alrededor de la aplicación sí.
Verificando la Resolución
Después del cambio de infraestructura, repetimos exactamente la misma secuencia de solicitudes que anteriormente reproducía la colisión.
También verificamos directamente las respuestas de las rutas principales de contenido en Inglés y Español.
Esto confirmó tanto la resolución de la colisión como el alcance real del tradeoff: el HTML del sitio dejó de utilizar la caché NGINX bajo la configuración actual.
La falla previamente reproducible desapareció sin modificar RG Language Bridge, su contrato de routing ni la arquitectura multilingüe del contenido.
Si en el futuro la infraestructura permite reglas más granulares, esta arquitectura puede evolucionar hacia un bypass selectivo del router, manteniendo cacheables las páginas de contenido.
La prueba final cerró la investigación: la aplicación era correcta y la solución de producción pertenecía al límite entre el estado de la aplicación y la política de caché de la infraestructura.
Un Sistema Digital No Termina en el CMS
El síntoma original parecía un problema de WordPress.
Después parecía un problema de redirects.
Después parecía un problema de cookies.
Auditamos nuestra propia capa de aplicación antes de asignar la responsabilidad a otro componente del sistema.
La falla real existía en la interacción entre la aplicación y la infraestructura encargada de servirla.
Software Engineering nos dio control sobre la aplicación.
Technical QA nos permitió validar esa aplicación contra su contrato.
El análisis de infraestructura reveló por qué una aplicación correcta estaba produciendo una experiencia incorrecta en producción.
Arquitectura Digital significa comprender no solamente cómo funciona cada componente, sino cómo se comportan esos componentes cuando interactúan.
¿El problema realmente está donde usted cree?
Conflictos de caché, redirects, discrepancias en analytics, aplicaciones desconectadas y problemas de infraestructura suelen parecer incidentes técnicos aislados. Con frecuencia, son síntomas de cómo está diseñada la arquitectura digital que los conecta.
Solicite una Auditoría de Arquitectura Digital →
