---
title: "Hotel Talavera: a bilingual site that AI can read · Polargate"
description: "A 4-star city hotel in Castilla-La Mancha had a website that search engines received as an empty container. Polargate rebuilt it as 16 pre-rendered bilingual URLs…"
url: https://polargate.ai/work/hotel-talavera
locale: en
publisher: POLARGATE S.L.
---
Hotels and hospitality

# A bilingual hotel website that crawlers and AI assistants can read

A 4-star city hotel in Castilla-La Mancha had a website that search engines received as an empty container. Polargate rebuilt it as 16 pre-rendered bilingual URLs and now runs it on a monthly Care retainer with a recurring audit loop.
[Visit the live site](https://www.hoteltalavera.com)

hoteltalavera.com

In short
Polargate rebuilt the website of a 4-star city hotel in Spain: what search engines used to receive as an empty single-page app is now 16 pre-rendered URLs in Spanish and English, with hreflang, a schema.org graph, FAQ content readable without JavaScript, llms.txt for AI assistants and a content security policy in enforce mode. A monthly Care retainer and a repeating audit loop keep it correct.
16
indexable URLs, Spanish and English

48
audit findings confirmed, none refuted

27
published FAQs with FAQPage schema

20
automated tests guarding SEO coherence

0
console errors with the security policy in enforce mode

## The problem

The hotel's website was a single page rendered in the browser. Search engines and AI assistants received an almost empty HTML container, every subroute answered 404, and the language tags pointed back at themselves, so the English version had no separate existence. There were no security headers. The contact form wrote into a database table that any anonymous visitor could read, and it delivered nothing to reception. Room types, prices, venues and opening hours only existed after JavaScript ran, which meant they existed for nobody who was not a browser.

## What we built

Polargate rebuilt the site on Vite, React and TypeScript with vite-react-ssg, so every route ships real HTML. The content became 16 indexable URLs, seven in Spanish and seven in English plus a FAQ page in each language, each with its own title, description, canonical and hreflang with return tags. One TypeScript file holds the hotel data and feeds the visible page, the schema.org graph and the llms.txt files. The contact form moved to a Supabase Edge Function with server-side validation and rate limiting, and mail leaves through Resend on a dedicated sending subdomain.

## The outcome

Twenty URLs answer 200 in production, the content security policy runs in enforce mode with no console errors, and both room types with their prices are readable in the served HTML. A 55-agent adversarial audit produced 48 findings, all confirmed and all fixed, among them a robots.txt group inheritance bug and English pages served with a Spanish language tag. Twenty automated tests now guard Spanish and English parity, unique metadata, and structured data against visible text. Traffic and booking effects are not measured yet, so Polargate does not claim them.

Stack

- Vite
- React
- TypeScript
- Tailwind CSS
- shadcn/ui
- React Router
- Vercel
- Supabase
- PostgreSQL
- Deno
- Resend
- GA4
- Search Console
- Google Maps
- Vitest
- GitHub
[hoteltalavera.com](https://www.hoteltalavera.com)

## What we found

An external audit and a code review on the same day reached the same verdict. The site was one page rendered in the browser, so a crawler received a container and nothing else. The English version had no URLs of its own, subroutes returned 404 and no security headers were sent. The contact form wrote into a Supabase table that any anonymous visitor could read, a personal data exposure we closed the same day.

- Content in the served HTML: empty
- Indexable URLs: one
- Security headers: none
- Contact form: stored the message, delivered nothing

## What we built

We kept the design and rebuilt the delivery. The site runs on Vite, React 18 and TypeScript with Tailwind and shadcn/ui, pre-rendered at build time by vite-react-ssg and deployed on Vercel. The route carries the language: Spanish at the root, English under /en/, each page pre-rendered in its own language with its own title, description, canonical and hreflang, including return tags and x-default.
A single file, src/lib/schema.ts, holds the hotel's facts. From it we generate the visible page, the JSON-LD graph (Hotel, Organization, WebSite, HotelRoom, EventVenue, FAQPage, BreadcrumbList and a ReserveAction pointing at the hotel's Paraty Tech booking engine) and the llms.txt and llms-full.txt files. Twenty-seven real questions from reception are published in six groups using native details elements, so an assistant reads them without executing JavaScript.
The contact form is a Deno Edge Function on Supabase: honeypot, timing check, server-side validation, rate limiting by hashed IP address, insert through the service role with no grants for the anonymous role, and delivery through Resend from a dedicated sending subdomain, which leaves the hotel's Microsoft 365 mail untouched. Analytics run on GA4 with Consent Mode v2 denied by default, and the map only loads after consent.

## How it runs now

The site sits on a monthly Care retainer, and that retainer includes an audit loop rather than patches alone. In August 2026 we ran a multi-agent audit across six areas, with a second agent trying to refute every finding before we accepted it: 48 findings, 48 confirmed, none refuted, 16 of them real bugs in production.

- Only one of the two room types reached the pre-rendered HTML
- English pages were served with lang="es"
- The hero image stayed hidden until hydration, behind a 4.5 second curtain
- A group inheritance bug in robots.txt
- Hotel coordinates about 430 metres off Everything was fixed and verified live from outside the client's network. The content security policy moved from report-only to enforce with zero console errors, 66 orphan files and 33 unused dependencies were deleted, and 20 vitest tests now fail the build if Spanish and English drift apart, if two pages share a title, or if the structured data stops matching what a visitor reads.

[Build →](https://polargate.ai/services/build) · [Grow →](https://polargate.ai/services/grow) · [Care →](https://polargate.ai/services/care) · [Hotels and hospitality →](https://polargate.ai/for/hotels)

FAQ

## Questions about this project

How long does a rebuild like this take? The work ran in phases inside a monthly retainer rather than as one launch. The first version, with the booking engine integration, the brand and the analytics setup, was delivered as a fixed-price project. The move to 16 pre-rendered bilingual URLs went live in July 2026 and the AI visibility work closed in August 2026. A comparable rebuild starts with a paid Discovery Sprint, which fixes scope and sequence before anyone writes code.
Can you do this with our existing booking engine? Yes. This hotel books through Paraty Tech and we kept it. Polargate treats the booking engine as a fixed point: the site links to it, and the structured data carries a ReserveAction pointing at the same URL, so an assistant reading the page knows where reservations happen. The same approach works with a PMS, a channel manager or a chain engine. We build around what you already pay for instead of replacing it.
Will this get our hotel into ChatGPT and Google's AI answers? It makes the hotel readable and quotable, which is the part anyone can control. We serve real HTML for every route, put the facts in visible text, keep a schema.org graph that mirrors that text, allow the search and answer crawlers in robots.txt and publish llms.txt. Nobody, Polargate included, can guarantee a citation or a ranking, so we report what is verifiable: what a crawler receives and whether it is correct.
What does the monthly Care retainer actually cover? Maintenance, the Google services (Business Profile, Search Console, Analytics), content and SEO work, and an audit loop. Every few months we re-audit the live site across security, SEO, accessibility, performance and content, and a second pass tries to refute each finding before we fix anything. In August 2026 that produced 48 confirmed findings and 16 real bugs. Twenty automated tests run on every build so the same regressions cannot return quietly.

## Related work

Global Dynamic Security Group

### Brand and bilingual site for Global Dynamic Security Group

Brand identity, a 15-page identity manual and a bilingual Spanish and English corporate site for Global Dynamic Security Group (GDS), a security services group in the Dominican Republic, delivered as one fixed-price project.
2026 Read the case

[Brand and bilingual site for Global Dynamic Security Group](https://polargate.ai/work/security-group-brand-and-site)

Hotel Marien

### A resort website that Google, social scrapers and AI assistants can actually read

Polargate turned the bilingual website of a 349-room Caribbean resort into a fully static, hardened site with structured data for AI search, and keeps it under a monthly care retainer with an automated audit on the first day of every month.
2026 Read the case

[A resort website that Google, social scrapers and AI assistants can actually read](https://polargate.ai/work/hotel-marien)

Santo Domingo Bay

### A Caribbean resort site rebuilt as static HTML, with an AI concierge behind it

Polargate rebuilt the bilingual website of a Caribbean convention resort and casino on Vite, React and its own Supabase project, prerendered the 38 Spanish and English routes to static HTML, and connected the hotel to Estevano, whose AI concierge handles real guest requests in six languages.
2026 Read the case

[A Caribbean resort site rebuilt as static HTML, with an AI concierge behind it](https://polargate.ai/work/santo-domingo-bay)

INITIATE

## Start the engine

Tell us what you are building in a few short questions. A senior engineer answers in writing within 48 business hours, with a first take on scope, timeline and price.
[Start your project](https://polargate.ai/start) · [Talk to us](https://polargate.ai/start#static-brief-heading)
