1. Why This Particular Page Deserves the Attention
On a hotel website, there is one page that consistently pulls more high-intent traffic than any other: the room detail page, or the apartment detail page. It's where a visitor lands once they've already decided they might stay at this property and are now comparing concrete options β the view, the square footage, the bed configuration, whether there's a balcony or a kitchenette. It's also, almost systematically, the page an AI system will try to cite when a traveller asks "which sea-view room is cheapest at this hotel" or "does this property have a two-bedroom apartment."
And it is, across most of the sites we audit, the single worst-structured category of page from a technical standpoint. Not because it's visually neglected β the photography is often excellent β but because there are so many of these pages, they're typically bulk-generated or duplicated from a template, and nobody goes back to fix the underlying data structure once the content is in place. A forty-room hotel spread across eight room types, with a French and an English version of each page, quickly adds up to over seventy individual pages that need to stay structurally consistent. That's exactly the kind of volume where structural errors go unnoticed.
Our internal room and apartment management plugin has existed for several years and already powers every hotel website we build and manage. Over the past few months, we rebuilt it substantially across three specific areas, with a recent launch β BΓ’rma Courchevel Hotel & Spa β serving as a real-world proving ground. Here's what changed, and why each change matters more than it might look.
2. A Room and an Apartment Are Not the Same Thing β and Our Plugin Treated Them as If They Were
The first change is structural, and in hindsight it should have come sooner: we introduced a unit_type taxonomy that explicitly distinguishes a room from an apartment, rather than treating the apartment as a variant or subtype of a room.
The distinction looks almost trivial from a display standpoint β both render the same way in a results grid, with a photo, a price, and a booking button. It stops looking trivial the moment you look at it from a schema standpoint. A standard hotel room describes correctly with a fairly simple Room schema: a bed type, a square footage, an occupancy count. A two-bedroom apartment with a separate living room is a structurally different object. It needs to communicate a bedroom count, potentially a separate count of sleeping spaces in the living area (a sofa bed, for instance), and a spatial layout that a single "bed type" field simply cannot express correctly.
Treating both as the same data entity, with the same required fields and the same optional fields, forces the apartment into a mould built for the room β or, in the other direction, weighs down every room page with fields that never apply to it. Neither approach produces clean schema. The unit_type taxonomy fixes this at the root: every page knows, from the moment it's created, whether it's a room or an apartment, and the plugin adjusts the fields it exposes β and, downstream, the schema structure it generates β accordingly.
3. The WPML Bug Most Teams Never Find
The second piece of work involves the controlled vocabularies attached to each page: room amenities, bathroom features, room views, bed types. We built these out as full taxonomies rather than free-text fields, specifically so they could be translated properly through WPML instead of being re-typed, with all the inconsistency that implies, in every language.
This is the work that surfaced a real WPML bug, subtle enough to be worth documenting here, because it illustrates exactly the kind of unglamorous work a genuinely multilingual hotel website requires. WPML ships with a configuration file, wpml-config.xml, that is authoritative over translation settings for custom post types and taxonomies. The problem: if that XML file disagrees with the WPML admin interface β or with the database itself β the XML file wins, silently, with no warning surfaced anywhere in the admin.
In practice, that meant toggling a setting in the WPML admin β switching a "room view" taxonomy from "do not translate" to "translate" β was not enough. The interface accepted the change and displayed it as active, yet WPML kept behaving according to the old setting defined in the XML file, because that file remained, behind the scenes, the actual source of truth. Clearing the cache changed nothing either β this isn't a caching problem, it's a priority-order problem between two configuration sources that are, on paper, supposed to stay in sync.
The fix took two steps: rewriting the plugin's wpml-config.xml directly so it correctly declared each taxonomy as translatable, then deactivating and reactivating the plugin entirely β not just clearing a cache, not just re-saving permalinks. It's that full deactivate/reactivate cycle that forces WPML to re-read the configuration file and reconcile its internal settings with what it declares. Without that cycle, the inconsistency persists indefinitely, invisible in the admin, visible only in the site's actual behaviour: amenities that keep displaying in French on the English version of a page, for instance.
This isn't some exotic quirk unique to our plugin. It's a class of bug that any team building custom taxonomies on top of a WPML site will run into sooner or later. We're documenting it here precisely because it's the kind of thing that can go unnoticed for months β the site looks multilingual, the structure is there, but part of the vocabulary stays stuck in one language and nobody understands why until someone opens that particular XML file.
4. Clean English URLs, Without Breaking Anything
The third piece of work is the most visible to an actual visitor, even though it remains largely a matter of internal plumbing: we added new English URLs for room and apartment pages β /room/{slug}/ and /apartment/{slug}/ β alongside the existing French URLs, /chambre/{slug}/ and /appartement/{slug}/.
Before this change, English-language pages inherited the same path segments as the French version β an English page would sit at something like /chambre/deluxe-sea-view/ rather than at something genuinely English. That wasn't broken in the strict sense β WPML correctly handled the language of the displayed content β but it wasn't clean either. An English-speaking visitor landing on a URL that begins with a French word gets a mismatched signal. A search engine or AI crawler trying to determine a page's canonical language from the URL itself, alongside hreflang and the html lang tag, gets a more ambiguous signal than it should.
The plugin now automatically detects each page's language and generates the matching URL base β English for English content, French for French content β with no manual per-page configuration required. And because we didn't want to break a single existing link β not the ones shared by visitors, not the ones already indexed by Google, not the ones an AI system may already have memorised from a previous crawl β old English URLs that used the French path segments now 301-redirect automatically to their canonical English equivalent. An external link pointing at the old URL still works; it simply lands, after a clean redirect, at the correct address.
This redirect detail matters more than it looks, specifically for AI visibility. An AI system that encounters two different URLs for what appears to be the same content, with no clear signal indicating which one is canonical, will either cite one at random or hesitate to cite either. A clean 301 redirect removes that ambiguity: there is now exactly one valid address per language, and that's the one every system β human or machine β should remember.
5. Why the Data Layer Determines Everything That Comes After
None of the above is visible in the admin interface at first glance, and none of it directly changes how a room page looks to a visitor. That's precisely the point. This plugin doesn't produce visible content; it produces the structured data layer that makes clean schema possible downstream, through our other plugin, recently rebranded Mixit7 AI Ready, which generates Room and Offer schema from that same underlying data.
But a Room schema can only be correct if the underlying data already is. You cannot generate schema that cleanly distinguishes a room from an apartment if the data model itself doesn't make that distinction. You cannot produce reliable schema in both languages of a site if the amenity, view, and bed-type vocabularies aren't reliably translated β if they silently fall back to English because of a misaligned WPML configuration file. And you cannot give a search engine or an AI system an unambiguous signal about which version of a page is canonical if two competing URLs exist for the same content in the same language.
That's why we put the time into a layer most visitors will never directly see. Room and apartment pages are simultaneously the most-viewed and the most technically fragile pages on a site, precisely because there are so many of them and they're rarely revisited individually once created. Fixing the structure once, at the source, inside the plugin itself, avoids having to fix the same error dozens of times across dozens of individual pages.
6. What This Actually Changes for the Sites We Manage
This plugin, with these three changes, now powers every room and apartment page across the hotel websites we build and manage β not just new launches like BΓ’rma Courchevel, but also, progressively, existing sites where we're migrating the old structure over to the new taxonomy. It isn't a plugin we sell separately; it's a piece of our internal infrastructure, in the same way as our FAQ plugin or our structured-data plugin, Mixit7 AI Ready.
But all three converge on the same conviction we've made a few times on this blog already: how accurately a search engine or an AI system can describe a hotel property depends almost entirely on a data layer the visitor never sees. A site can have the best room photography on the market; if the underlying data conflates a room with an apartment, doesn't reliably translate its amenities, or exposes two competing URLs for the same page, neither Google nor ChatGPT will be able to correctly describe what the hotel actually offers.
Wondering if your room pages have clean Room/Offer schema in every language you serve? AIscore checks exactly that β schema consistency, hreflang structure, duplicate URLs β among its 91 signals. Free, no sign-up required.
Check the structure of your room pages
AIscore analyses your site in 30 seconds and flags schema, language, and URL inconsistencies across your room and apartment pages.
Scan your hotel now β