Hotel Booking Free owns locale resolution and the public language-navigation contract. WPML and Polylang are optional provider adapters; neither is a hard dependency of Free, Pro or Aurelia. The theme consumes a stable facade instead of calling a vendor API.
Two related contracts
The language provider resolves a locale for frontend, admin, REST, cron, email and PDF contexts. The navigation contract exposes available languages, the current language and a safe switch URL. Its public type is LanguageNavigationInterface. A theme can call:
$languages = hotel_booking()->languages();
$current = $languages->current();
$items = $languages->available();
$url = $languages->url('vi');
Each normalized item has code, locale, translated and native labels, direction, url, current and switchable. Provider order is preserved. A native WordPress site with one language reports a safe single_language state.
Boundaries and safety
Free owns detection, normalization, switch URLs and cache-safe state. Aurelia owns markup, placement, responsive behavior and accessibility. Pro delegates to the Free contract and does not fork it. Themes must not call WPML, Polylang, repositories, license services or internal HB... classes.
Sensitive confirmation, payment, customer, review, password-reset, nonce and token routes are locked and expose no switch URL. Booking locale is an immutable snapshot; switching the site later must not rewrite historical communication.
Next: configure WPML or Polylang.