La Raya · app (2): idioma compartido y construir sobre una API que cambia bajo tus pies
Publicado el 13/06/2026
La app de La Raya tuvo que crecer con dos incomodidades simultáneas: es bilingüe por naturaleza (frontera España-Portugal, más inglés para visitantes) y se construía sobre un backend que aún cambiaba de forma. Esta entrada va de cómo domesticar ambas.
El idioma, de verdad y en todas partes
El backend sirve el contenido en el idioma que le pidas mediante una cabecera. La parte de la app era que ese idioma fuera global y coherente: que elegirlo en un sitio afectara a todas las pantallas, y que el contenido se actualizara al cambiarlo.
Lo resolví con un contexto de idioma (LangContext) que guarda la preferencia de forma persistente y la inyecta en cada petición (la cabecera X-Accept-Language). El truco que faltaba: al cambiar de idioma, invalidar la caché de React Query para forzar el refetch. Sin eso, cambiabas a portugués y seguías viendo lo cacheado en español hasta que algo expiraba. Un picker de idioma (es/pt/en) en el perfil cierra el círculo.
Un picker de localidad que no estorba
Otra pieza de UX: filtrar por localidad. La primera versión era un desplegable normal; acabó siendo un chip + modal con búsqueda, porque la lista de pueblos es larga y un selector plano es incómodo. Pequeño cambio, gran diferencia al usarlo con una mano en el autobús.
Construir sobre arena: adaptarse a una API viva
Esto fue lo más realista del proceso. Mientras yo montaba listados y detalles, el backend seguía evolucionando: cambiaban campos, aparecían filtros (ordenar por fecha ascendente/descendente), se añadían recintos. Hubo más de un commit del tipo "adaptar el frontend al API actual".
Lecciones de construir contra un objetivo móvil:
- Centraliza el cliente API (un único
lib/api.tscon axios, interceptores y los endpoints por dominio). Cuando el backend cambia, tocas un sitio, no veinte. - Tipa las respuestas (TypeScript). Si el tipo no incluye un campo, la app lo descarta en silencio — un clásico que muerde callado. Mantener los tipos al día con la API te ahorra bugs invisibles.
- Ordena igual que el backend. Hubo un baile con "próximos eventos": que la app pidiera
ordering=fecha_iniciopara que el más cercano saliera primero, en sintonía con lo que decidía el servidor. Cuando cliente y servidor discrepan en el orden, el usuario ve cosas raras.
La URL del API: hornearla en el build
Un detalle que parece tonto y no lo es: la app necesita saber a qué backend hablar, y eso cambia entre local y producción. La solución fue inyectar EXPO_PUBLIC_API_URL en tiempo de build (como argumento de construcción), de modo que cada binario sabe a dónde apunta sin configuración en runtime. (Esto volvería a darme guerra más adelante con los builds de release, pero esa es otra entrada.)
Lo que me llevo
- El idioma es estado global, trátalo como tal. Un contexto + invalidación de caché al cambiarlo evita el clásico "lo cambié pero sigue en el idioma anterior".
- Una API que cambia no es un problema si tu cliente está centralizado y tipado. Un único punto de contacto y tipos al día convierten un cambio de backend en un diff pequeño, no en una cacería.
- Sintoniza orden y filtros con el servidor. Las discrepancias cliente/servidor en ordenación son bugs de percepción difíciles de depurar.
- La configuración del entorno es parte del producto. Saber a qué API hablas (y hornearlo en el build) evita despliegues "que apuntan a localhost" en producción.
Con el idioma y la API domados, me metí en una función vistosa que luego reconsideré entera: la geolocalización para ordenar por cercanía. La próxima entrada cuenta por qué la añadí… y por qué acabé quitándola.