Skip to content

19 — Booking Engine Integration

PRD Document · Savoy Signature Hotels — Multi-Site Headless Platform
Version: 1.0 · Date: 2026-03-04
Related docs: 07_Modules_and_Templates.md (M03 — Booking Bar), 03_MultiSite_and_Domains.md


This document defines the integration between the Savoy Signature headless platform and the external booking systems — Navarino (Bookpoint calendar widget) and Synxis (SHR’s central reservation system). It covers the frontend widget embedding, configuration per hotel, URL redirect logic, and analytics tracking.


Synxis (SHR) Booking EngineNavarino Bookpoint WidgetBooking Bar (M03)Website VisitorSynxis (SHR) Booking EngineNavarino Bookpoint WidgetBooking Bar (M03)Website VisitorClicks "Book Now"Open calendar widget (inline/overlay)Selects dates, guests, promo codeValidates availability datesClicks "Check Availability"Redirect to Synxis with query paramsSynxis booking page (external domain)

[!IMPORTANT] The actual booking transaction (payment, reservation confirmation) happens entirely on the Synxis external domain. The Savoy website is responsible only for collecting dates, guest count, and optional promo code, then redirecting.


Navarino provides a JavaScript widget (Bookpoint) that renders a date-picker calendar. It is embedded into the Booking Bar module (M03) as a Client Component.

packages/modules/src/m03-booking-bar/BookingBar.client.tsx
'use client';
import Script from 'next/script';
import { useEffect, useRef } from 'react';
interface BookingBarProps {
navarinoHotelCode: string;
synxisHotelId: string;
synxisBaseUrl: string;
locale: string;
variant: 'inline' | 'overlay' | 'sticky';
}
export function BookingBarClient({
navarinoHotelCode,
synxisHotelId,
synxisBaseUrl,
locale,
variant
}: BookingBarProps) {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
// Initialize Navarino widget after script loads
if (window.Bookpoint && containerRef.current) {
window.Bookpoint.init({
container: containerRef.current,
hotelCode: navarinoHotelCode,
language: locale === 'pt' ? 'pt-PT' : 'en-GB',
onSubmit: (data) => {
// Redirect to Synxis with selected params
const params = new URLSearchParams({
hotel: synxisHotelId,
arrive: data.checkIn, // YYYY-MM-DD
depart: data.checkOut, // YYYY-MM-DD
adult: String(data.adults),
child: String(data.children || 0),
...(data.promoCode && { promo: data.promoCode }),
locale: locale,
});
// Track event before redirect
window.dataLayer?.push({
event: 'booking_bar_submit',
siteKey: 'savoy-palace',
hotelCode: navarinoHotelCode,
locale,
checkIn: data.checkIn,
checkOut: data.checkOut,
guests: data.adults,
});
window.location.href = `${synxisBaseUrl}?${params.toString()}`;
},
});
}
}, [navarinoHotelCode, synxisHotelId, synxisBaseUrl, locale]);
return (
<section className={`booking-bar booking-bar--${variant}`} data-module="bookingBar" data-module-id={moduleId}>
<Script
src="https://widget.navarino.co/bookpoint.js"
strategy="lazyOnload"
onReady={() => {
// Widget initialization handled by useEffect
}}
/>
<div ref={containerRef} className="booking-bar__widget" />
</section>
);
}
  • Loading: The Navarino script is loaded with strategy="lazyOnload" to avoid blocking the main thread and LCP.
  • Bundle impact: The external script is not counted in the site’s JS budget but is monitored via Lighthouse.
  • Fallback: If the widget fails to load, a simple HTML form with date inputs and a direct link to Synxis is displayed.

Each hotel has its own Navarino code and Synxis ID, configured in the siteRoot Document Type in Umbraco.

PropertyTypeExample
navarinoHotelCodeTextstringSVP
synxisHotelIdTextstring12345
synxisBaseUrlURLhttps://be.synxis.com/
bookingBarEnabledToggletrue
bookingBarVariantDropdown (inline / overlay / sticky)sticky
HotelNavarino CodeSynxis IDDefault Variant
Savoy PalaceSVPTBDsticky
Royal SavoyRSVTBDsticky
Savoy GardensTBDTBDinline
SaccharumTBDTBDsticky
NextTBDTBDinline
Calheta BeachTBDTBDinline
GalosolTBDTBDinline
Savoy Signature (Group)N/AN/AN/A (no booking on group site)

[!NOTE] Navarino and Synxis IDs to be confirmed by the Savoy Signature operations team during the STAGE integration phase.


The Synxis booking engine expects query parameters in a specific format:

https://be.synxis.com/?hotel={synxisHotelId}&arrive={YYYY-MM-DD}&depart={YYYY-MM-DD}&adult={N}&child={N}&promo={PROMO_CODE}&locale={LOCALE}
ParameterSourceRequired
hotelsiteRoot.synxisHotelId✅ Yes
arriveNavarino calendar selection✅ Yes
departNavarino calendar selection✅ Yes
adultGuest counter (default: 2)✅ Yes
childGuest counter (default: 0)❌ Optional
promoPromo code input field❌ Optional
localeCurrent page locale (pt / en)✅ Yes

The Booking Bar module (M03) supports three presentation modes:

VariantBehaviorTypical Placement
inlineRendered within the page content flowHomepage (below hero), Room listing pages
overlayFloats over the hero image, semi-transparent backgroundHomepage (over hero slider)
stickyFixed to the bottom of the viewport, slides up on scrollAll inner pages (contextual prompt to book)

Umbraco can define special offer pages with a pre-filled promo code:

// On specialOfferDetailPage
const promoCode = page.properties.promoCode; // e.g., 'SUMMER2026'
// The Booking Bar on this page auto-fills the promo code
<BookingBarClient
navarinoHotelCode={site.navarinoHotelCode}
synxisHotelId={site.synxisHotelId}
synxisBaseUrl={site.synxisBaseUrl}
locale={locale}
variant="inline"
defaultPromoCode={promoCode} // Pre-filled
/>

Marketing campaigns can pass promo codes via URL query string:

https://savoysignature.com/savoy-palace/pt?promo=SUMMER2026

The proxy.ts or page component extracts the promo param and passes it to the Booking Bar.


  • Navarino Bookpoint widget loads and initializes correctly on all 7 hotel sites (not group site).
  • Widget respects the page locale (pt-PT or en-GB).
  • Date selection redirects to Synxis with all required query parameters.
  • booking_bar_submit dataLayer event fires before redirect.
  • Promo code field pre-fills from CMS or URL query string.
  • sticky variant is visible on scroll and does not overlap content or navigation.
  • Fallback HTML form is shown if Navarino script fails to load.
  • Booking Bar is not rendered on the Savoy Signature group site.

Next document: 20_Roadmap_and_Phases.md