
Última actualización
Los Lagos Hotel es un hotel familiar de El Calafate, el pueblo patagónico que la mayoría de los viajeros usa como base para visitar el glaciar Perito Moreno. Cuando empezó este trabajo, el hotel estaba migrando de Minihotel, un sistema de gestión más antiguo, a Cloudbeds. Esa migración es la que hizo posible todo lo demás: en cuanto las habitaciones, las tarifas y las reservas pasaron a vivir en un sistema con una API de verdad, el hotel pudo por fin vender directo desde su propia web y controlar sus propios precios.
Así que construí dos aplicaciones web. Una es el sitio bilingüe donde reservan los huéspedes; la otra es la herramienta interna con la que el hotel fija sus precios. No se parecen en nada, y no deben parecerse. Una es el escaparate y la otra la trastienda. Lo que comparten es el backend, y las dos hablan con la misma cuenta de Cloudbeds.
El problema de dinero no era complicado. Una parte importante de las reservas del hotel llegaba a través de Booking.com y plataformas similares, y cada una de ellas lleva una comisión. El hotel ya tenía una web, así que en principio esos huéspedes podrían haber reservado directamente. Pero el sitio no parecía un lugar donde uno entregaría su tarjeta, y tampoco era fácil de usar. Las dos cosas costaban conversiones, y las comisiones se seguían pagando.
Vender directo suena sencillo hasta que miras lo que el hotel tiene que resolver en Argentina. Cloudbeds cobra en pesos argentinos, pero el hotel y las personas de revenue que le fijan los precios trabajan en dólares, porque el peso se mueve lo suficiente como para que un precio fijado en pesos quede desfasado en una semana. Y los huéspedes que residen fuera de Argentina están exentos del 21% de IVA sobre el alojamiento, así que la misma habitación tiene legítimamente dos precios según dónde viva quien reserva.
Las dos cosas terminaban en el mostrador de recepción, resueltas caso por caso. Así que el encargo se reducía a tres cosas: captar reservas en la web del propio hotel, hacer que esa web mereciera la confianza de dar una tarjeta, y mostrar a cada huésped el precio que realmente le corresponde sin que nadie tenga que hacer las cuentas a mano.
El sitio para huéspedes está hecho con Next.js y TypeScript, pregenerado de forma estática en cada idioma. La herramienta interna es una SPA de React construida con Vite. Supabase es el backend compartido: Postgres, seguridad a nivel de fila y Edge Functions. Ambas aplicaciones terminan escribiendo en la API de Cloudbeds.


El sitio público es bilingüe. El español conserva las URLs sin prefijo, preservando las rutas que ya usa la web actual del hotel, y el inglés vive bajo /en. Quien llega por primera vez no tiene que buscarlo: el sitio lee el idioma que pide su navegador, lo enruta en consecuencia y recuerda la elección en una cookie durante un año, con un selector en la cabecera para quien prefiera el otro. Todas las páginas se pregeneran en ambos idiomas para que los rastreadores reciban HTML real y no una estructura vacía. Más allá de las habitaciones y del hotel en sí, la mayor parte del contenido está para responder a lo que la gente pregunta de verdad antes de comprometerse con un viaje a la Patagonia: a qué distancia está el centro, cómo llegar desde el aeropuerto, qué hacer una vez allí.
Dos detalles que disfruté especialmente. Las secciones se separan con transiciones curvas en SVG en lugar de la típica línea recta. Y la página de ubicación incluye un mapa interactivo de OpenStreetMap con marcadores propios para el hotel y para los restaurantes, atracciones y bancos de alrededor, junto con los tiempos a pie y en coche hasta el centro, la terminal de autobuses, el aeropuerto y el glaciar. Las valoraciones de TripAdvisor, Google y Booking se reúnen en una sola franja para que el huésped no tenga que ir a buscarlas.

La página de inicio: la portada, los motivos para reservar directo y el buscador de disponibilidad
La página de reservas incrusta el Immersive Experience de Cloudbeds, un componente web de terceros que renderiza su propio checkout dentro del sitio. Es prácticamente una caja negra, así que todo lo que el hotel necesitaba por encima lo añade un único observador que vigila el DOM del componente y vuelve a aplicar los ajustes cada vez que se redibuja. Lo que aporta esa capa:
El error más instructivo salió precisamente de ese observador. Manipular el propio contador de cantidad de Cloudbeds hacía que el componente se redibujara, lo que volvía a disparar el observador, que volvía a manipular el contador. Un solo clic generaba más de 600.000 mutaciones del DOM y bloqueaba la pestaña. La solución fue una protección de reentrada alrededor de la pasada de ajustes, y ahora todo código que toque el DOM de Cloudbeds tiene que ejecutarse dentro de ella.

El motor de reservas, con el selector de residencia y el de tipo de cama
Algunos sistemas de gestión hotelera incluyen herramientas de revenue que harían parte de esto. El problema es la dependencia: la lógica de precios acaba viviendo dentro del producto de otro, y salir de ahí más adelante sale caro. Para este cliente pesaba más la flexibilidad, así que la lógica de precios vive en una aplicación aparte, propia, que habla con Cloudbeds a través de su API en lugar de residir dentro de él.
La segunda aplicación es donde el hotel fija sus precios. Es exclusivamente interna. No hay registro público y las cuentas las crea un administrador. Los dos roles, revenue y personal del hotel, se aplican mediante seguridad a nivel de fila en Postgres y se vuelven a comprobar dentro de cada función privilegiada, en lugar de simplemente ocultarse del menú.
No automatizar ese último paso es precisamente la idea. Una moneda como el peso argentino puede moverse de forma brusca y con poco aviso, así que un sistema que reajustara todas las habitaciones en cuanto se moviera una fuente sería un riesgo más que una comodidad: una lectura errónea o puramente pasajera se propagaría directamente a los precios en producción, y el hotel se enteraría vendiendo habitaciones demasiado baratas. Por eso observar una cotización nunca mueve un precio por sí sola. Registra la tasa, recalcula cuáles serían los nuevos precios y abre una tarea. Los precios solo se mueven cuando una persona confirma que la tasa está realmente aplicada en Cloudbeds. Cloudbeds tiene su propia conversión automática, que se actualiza dos veces al día desde una fuente internacional, pero para este hotel ni la frecuencia alcanza ni la referencia es la correcta: lo que factura es la cotización oficial del Banco Nación, no una tasa media internacional.
El punto débil de un paso de confirmación humano es que alguien tiene que enterarse. Por eso las mismas Edge Functions que abren una tarea FX la envían también a un grupo de Telegram, mediante un bot que escribí para el hotel: la tasa anterior, la nueva, si viene de la fuente automática o de una carga manual, y un botón que lleva directamente a la página de tareas de la herramienta de operaciones. Vuelve a publicar cuando alguien aplica la tasa, indicando quién lo hizo, y si la cotización vuelve a su valor anterior antes de que nadie actúe publica una cancelación para que nadie haga trabajo de más. La notificación es deliberadamente de mejor esfuerzo y nunca puede lanzar un error. La tarea FX ya está registrada cuando se intenta enviar el mensaje, así que un token ausente o una caída de Telegram no pueden romper el registro de tasas.

Panel: último tipo de cambio, tareas pendientes y ocupación
Argentina tiene su propio régimen de protección de datos, la Ley 25.326, supervisado por la AAIP, y los sitios se construyeron conforme a él en lugar de adaptarlos después. La web para huéspedes incluye una política de privacidad y una política de cookies redactadas según esa ley, con los derechos de Habeas Data que concede y cómo ejercerlos, y el flujo de reserva solo recoge lo que una reserva realmente necesita.
El consentimiento se aplica en el código, no solo se describe en una página. En la web para huéspedes existe exactamente una categoría no esencial, la analítica, y nada relacionado con ella se carga hasta que la persona ha dado su consentimiento de forma explícita. Tres elementos nunca se bloquean: la preferencia de idioma, el propio motor de reservas y el registro de la elección. Eso es lo que cumple la regla de consentimiento previo de la Ley 25.326, y el RGPD y la ePrivacy para los huéspedes europeos, que son muchos.
Detrás de esa barrera está PostHog para analítica de producto y grabación de sesiones, junto a Google Analytics, de modo que el hotel puede ver cómo se mueve la gente por el sitio y dónde abandona una reserva en lugar de suponerlo. La herramienta interna tiene su propia documentación: un aviso de privacidad para el personal, un registro de actividades de tratamiento y una política de retención realmente implementada, con una tarea programada que purga el registro de actividad a los 24 meses y los registros de peticiones a Cloudbeds a los 90 días.
Las dos mitades tienen requisitos realmente distintos. El sitio para huéspedes es público y tiene que ser indexable, así que se pregenera en cada idioma. La herramienta de operaciones no tiene ninguna superficie de SEO y nunca necesita renderizado en servidor, así que es una SPA sencilla que habla directamente con Supabase. Más pequeña, más barata y más fácil de razonar.
El backend es la mitad compartida. Todo lo sensible se ejecuta dentro de Postgres o de una Edge Function: el token de Cloudbeds, la clave de servicio, la escritura de tipos de cambio. Ninguno de los dos navegadores llega a tener nunca una credencial de Cloudbeds.
La herramienta de operaciones está en producción y el hotel fija sus precios con ella: actualizar tarifas es ahora escribir un número una vez, revisarlo, publicarlo y verificarlo contra Cloudbeds, en lugar de una pasada manual por cada tipo de habitación y cada fecha. En agosto de 2026 el sitio para huéspedes está terminado y a la espera del cambio desde la web actual del hotel; a partir de ese momento las reservas directas llegarán a él y cada huésped verá el precio que le corresponde.
Buena parte del trabajo no fue código. Como recepción es quien realmente cobra a los huéspedes, el proyecto también dejó guías en español para cobrar mediante enlace de pago: cómo comprobar la residencia declarada por el huésped, confirmar que el tipo de cambio sigue vigente y cuadrar el importe con Cloudbeds antes de cobrar nada.
Dos aplicaciones para un hotel pequeño: un escaparate que tiene que sobrevivir a Google y una trastienda que tiene que sobrevivir a un tipo de cambio en movimiento.
Gracias por leer,
Julio Macías González