Skip to content
HotelSEO Lab
← The Lab
Technical SEO Advanced

JavaScript Rendering and Hydration: Why Google Sometimes Cannot See My Booking Widget

A founder's plain-English guide to why client-side rendering and hydration delays hide your hotel booking widget from crawlers, and the SSR and prerender fixes that put content back where Google can read it.

HotelSEO LabJune 1, 2025 9 min read

I lost a weekend once to a hotel homepage that looked perfect to everyone except Google. The owner showed me the site on his laptop, all the room descriptions, the amenities, the little “Best Rate Guarantee” badge, everything loading clean and fast. Then I pulled up the raw HTML the crawler actually sees, and it was a ghost town. A logo, a loading spinner, and a wall of empty divs. Every word that mattered showed up only after the browser ran a pile of JavaScript.

That gap, between what a person sees and what a crawler sees, is the single most underrated technical SEO problem on independent hotel sites in 2026. So let me walk you through what is actually happening under the hood, why your booking widget specifically tends to be invisible, and the handful of fixes that reliably put your content back where search engines and AI engines can read it.

The two-second version of how rendering works

When someone visits your site, their browser asks your server for the page. The server sends back HTML. That HTML is the raw material. If your room descriptions are written into that HTML, great, they exist the moment the page arrives.

But a lot of modern hotel sites, especially anything built on React, Vue, Next.js, or a fancy theme a developer “upgraded,” do something different. The server sends back a nearly empty HTML shell, plus a big bundle of JavaScript. The browser then runs that JavaScript, which fetches your content from somewhere and paints it onto the page. This is client-side rendering. The content is real, but it only comes alive after the visitor’s device does the work.

Hydration is the related concept that trips people up. Some frameworks send HTML that looks complete, then JavaScript “wakes it up” by attaching all the interactive behavior, click handlers, the booking calendar, the menu. During that hydration window the page can look finished but be functionally inert, and depending on how it is built, some content can swap, shift, or appear only once hydration finishes.

Here is the part that matters for you.

Googlebot does render JavaScript, but it does it in a second pass, on a queue, and on a budget. For a small independent hotel with a modest crawl allowance, content that depends on JS can get indexed late, indexed partially, or skipped. AI crawlers from ChatGPT and others are even less patient, and many do not run your JavaScript at all.

So “it works in my browser” and “Google can read it” are two completely different claims. Your browser is a powerful machine giving your one page its full attention. A crawler is rationing attention across billions of pages.

Why the booking widget is its own special case

Let me clear something up, because hoteliers panic about this for the wrong reason.

Your embedded booking engine, the SynXis, Cloudbeds, Mews, or WebRezPro widget that loads the calendar and live rates, is almost always loaded inside an iframe or a third-party script. Google generally does not index the live rates or availability inside it, and honestly, you do not want it to. Rates change hourly. Indexing them would be a mess. So the widget being a black box to crawlers is normal and fine.

The real problem is more subtle. It is when your descriptive content gets tangled up in the same JavaScript-heavy setup as the widget. I see this constantly:

When that happens, the crawler shows up, grabs the empty shell, and may move on before the second rendering pass ever fills it in. Now the page that is supposed to rank for your hotel’s name and your room types has, as far as the index is concerned, almost no text on it. That is how a beautiful site ends up invisible, and it is closely related to the reason your hotel can rank below the OTAs even for your own name. I wrote about that mess in detail in why your hotel ranks below OTAs for your name, and rendering is often the hidden culprit.

How to tell if this is happening to you

You do not need to be a developer to diagnose this. Three checks, ten minutes.

1. View the raw source. Right-click your room page and choose “View Page Source.” That is the raw HTML before any JavaScript runs. Use Ctrl+F to search for a sentence you know is on the page, like a line from your suite description. If you can find it in the source, good. If it is not there, your content depends on JS to appear.

2. Use Google Search Console. Pop your URL into the URL Inspection tool and look at the rendered HTML and the screenshot Google captured. If the rendered version is missing big chunks that you can see in a live browser, that is your answer.

3. The cheap-and-dirty test. Disable JavaScript in your browser (Chrome dev tools lets you do this), then reload the page. What you see with JS off is roughly the floor of what a crawler reliably gets on the first pass. If the page collapses into a spinner and empty boxes, you have a rendering problem.

Here is a quick way to think about which approach your site is using and what it means:

Rendering approachWhat the crawler gets on first requestSEO risk for hotels
Static HTMLFull content immediatelyLowest
Server-side rendering (SSR)Full content immediatelyLow
Prerender for botsFull cached HTML snapshotLow, if kept fresh
Client-side rendering (CSR)Empty shell, content via JSHigh
Hydration-dependent contentLooks full, key text may render lateMedium to high

If you land in those bottom two rows for the pages that are supposed to earn bookings, that is where the work is.

The fixes, from “tell your developer” to “rebuild”

You have options, and they range from a config change to a real project. I will give them to you roughly in order of effort.

1. Server-side rendering (SSR)

This is the gold standard. Your server builds the complete HTML for each page before sending it, so crawlers and humans both get a finished page in the first response. The JavaScript still loads to make things interactive, but it is enhancing a page that already has all its content, not creating it from scratch.

If you are on Next.js, Nuxt, Astro, or similar, SSR or static generation is usually a built-in option that your developer can switch on for the content pages. The phrase to hand your developer is: “I need the room descriptions, amenities, and page copy in the server-rendered HTML, not injected client-side after load.”

The goal is brutally simple. When a crawler asks for your room page, the very first response should already contain the words that describe that room. Everything else, the calendar, the animations, the live rates, is allowed to load later. The text cannot.

2. Static generation

If your content does not change minute to minute (and for most boutique hotels, room descriptions, the story of the property, the local guide, none of that changes daily), you can pre-build static HTML pages at deploy time. They are fast, cheap, crawl beautifully, and there is no rendering gamble at all. The dynamic stuff, live availability and rates, still comes from your booking engine widget layered on top. This is often the sweet spot for an independent property.

3. Prerendering for bots

If a full SSR rebuild is not in the cards, prerendering is the pragmatic middle path. A service or your own setup detects crawler traffic and serves them a fully rendered, cached HTML snapshot of the page, while regular visitors get the normal JS app. Done correctly this is not cloaking, because the content is the same, you are just delivering it in a crawler-friendly format. The catch is freshness: if you prerender, you have to make sure the snapshots regenerate when you update content, or you will serve Google a stale page.

4. Stop hiding text behind interactions

Even on a well-rendered site, I find content tucked inside tabs, accordions, “read more” toggles, and carousels that only inject their text into the page when clicked. Modern crawlers handle a lot of this better than they used to, but I still treat it as risk. If a paragraph matters for ranking, it should be in the DOM on load, not summoned by a click. Style it however you like visually, but keep the words present.

Where this ties into AEO, GEO, and getting picked by AI

Everything above gets more urgent when you think about AI search. The volume tells the story: people are searching for answer engine optimization (about 27,100 monthly US searches), generative engine optimization (around 5,400), and the category is growing fast. The AI crawlers feeding ChatGPT, Perplexity, and Google’s AI answers are, on the whole, less tolerant of JavaScript than Googlebot. Many fetch your raw HTML and call it a day.

So if your property’s description, your unique selling points, your neighborhood story, all of it lives behind client-side rendering, you are not just risking your Google ranking. You are making yourself unreadable to the engines that increasingly decide whether a traveler ever hears your name. I dug into exactly this failure mode in is your hotel invisible to ChatGPT, and rendering is a recurring villain there too.

This is also why I will not promise you a number-one ranking, from this fix or any other. What I can tell you is that getting your content into the initial HTML is one of the highest-leverage things you can do to maximize your odds of being seen, indexed, and quoted. It is a prerequisite, not a magic trick. You cannot rank or get cited for text the machine never read.

The payoff for an independent hotel

Let me connect this to the thing you actually care about: more direct bookings and a healthier OTA mix.

When your own site renders cleanly and ranks for your name and your room types, you reduce your dependence on the OTAs that take roughly 15 to 25 percent of every reservation. You do not get to fully escape the OTAs, and I would be lying if I told you that you could, they are a real and useful distribution channel. But every guest who finds you directly, on a site that crawlers and AI engines can actually read, is a guest you did not rent from Booking or Expedia. The math on that is worth understanding, and I broke it down in the book-direct math on OTA commission cost.

A fast, well-rendered site also makes your conversion work pay off, because traffic you cannot earn cannot convert. If you are layering on book-direct CRO or building out your Google Business Profile, a site that crawlers can read is the foundation the rest sits on.

So here is my honest take to close. Rendering problems are invisible until you go looking, which is exactly why they linger for years on otherwise gorgeous hotel sites. Spend the ten minutes on the three checks above. If your content is hiding behind JavaScript, you have found a quiet, fixable leak in your search visibility.

If you want me to run those checks for you and hand your developer a precise, prioritized fix list, that is exactly the kind of thing our hotel technical SEO work is built for. Book a call and I will tell you straight whether rendering is costing you bookings, or whether your problem is somewhere else entirely.

FAQ

Quick answers

Does Google really fail to read JavaScript on my hotel website?

Google can render JavaScript, but it does it on a delay and on a budget. For a small independent hotel with a modest crawl budget, content that only appears after the browser runs JS can get indexed late, partially, or not at all. The safest move is to serve the important text in the initial HTML.

Is my booking engine widget a problem for SEO?

Most embedded booking widgets load inside an iframe or a third-party script, and Google generally does not index the rates or availability inside them. That is fine. The problem is when your room descriptions, amenities, or page copy also depend on that same JS to appear. Keep your descriptive content in the page HTML and let the widget be the widget.

What is the difference between server-side rendering and prerendering?

Server-side rendering builds the full HTML on the server for every request, so crawlers and people get a complete page immediately. Prerendering generates static HTML snapshots ahead of time, or serves a cached rendered version to bots. Both put readable content in the first response. Which one fits depends on your stack and how often your content changes.

How do I know if hydration is hurting my rankings?

View the page source and use the URL Inspection tool in Google Search Console to see the rendered HTML. If your headings, room copy, and key text are missing from the raw source but appear in the live browser, JavaScript rendering is likely costing you visibility.

Keep reading

More from the Lab

Free intro call

Let's go find out why the OTAs are outranking you for your own name.

20 free minutes. We'll look at your hotel live, show you where you're invisible — on Google and in the AI answers — and tell you straight whether we can help.

No lock-in · No 12-month handcuffs · You talk to the strategist