Switchfly Widgets Integration Guide (1.0.0)
Download OpenAPI specification:
Embeddable travel widgets for partner sites.
- Search Widget: Full-featured travel search (air, hotel, car, activities, bundles)
- Hotel Deals Widget: Showcase featured hotel deals with click-through to booking
Direct Script Embed (Search Widget)
Load the widget bundle and call createSearchWidget():
<div id="search-widget"></div>
<script src="https://your-cdn.com/dist/switchfly-widgets.iife.js"></script>
<script>
SwitchflyWidgets.createSearchWidget({
containerId: 'search-widget',
targetUrl: 'https://your-booking-site.com',
locale: 'en',
cobrand: 'partner123',
searchParam: '|city:7321',
prefillDestinationLabel: 'San Diego',
searchDateFormat: 'dd/mm/yy',
customTab1Label: 'Cruises',
customTab1Url: 'https://example.com/cruises',
customTab1Position: 'last',
branding: {
tokens: {
accentColor: '#0a66c2'
}
}
});
</script>
Iframe Embed (Search Widget)
<iframe
src="https://your-cdn.com/widgets/search/?locale=en&searchParam=%7Ccity:7321&prefillDestinationLabel=San%20Diego&cobrand=partner123&searchDateFormat=dd/mm/yy&customTab1Label=Cruises&customTab1Url=https://example.com/cruises&customTab1Position=last&accentColor=%230a66c2"
width="100%"
height="600"
frameborder="0">
</iframe>
Direct Script Embed (Hotel Deals Widget)
<div id="hotel-deals"></div>
<script src="https://your-cdn.com/dist/switchfly-widgets.iife.js"></script>
<script>
SwitchflyWidgets.createHotelDealsWidget({
containerId: 'hotel-deals',
targetUrl: 'https://your-booking-site.com',
locale: 'en',
maxItems: 6,
showPrices: true,
title: 'Featured Hotels',
branding: {
tokens: {
accentColor: '#dc2626'
}
}
});
</script>
Iframe Embed (Hotel Deals Widget)
<iframe
src="https://your-cdn.com/widgets/hotelDeals/?locale=en&maxItems=6&accentColor=%23dc2626"
width="100%"
height="600"
frameborder="0">
</iframe>
postMessage API
Widgets send events to parent windows via postMessage:
window.addEventListener('message', (event) => {
switch (event.data.type) {
case 'SWF_WIDGET_HEIGHT':
// Resize iframe to match widget height
iframe.style.height = event.data.height + 'px';
break;
case 'SWF_WIDGET_NAVIGATE':
// Widget is navigating to booking platform
console.log('Navigating to:', event.data.url);
break;
}
});
Note: Parent → widget configuration messages are not currently supported. Configure via URL parameters or script config only.
URL Parameter Notes
- Colors must be URL-encoded (
#0a66c2→%230a66c2) cobrandparameter becomesnav=<value>in the final booking search URL- Only include parameters you want to override (all are optional)
- Destination prefill with numeric city IDs:
- Use
searchParam=|city:7321(URL-encoded:%7Ccity:7321) for the canonical token - Also provide
prefillDestinationLabel=San%20Diegofor display - Typeahead API cannot resolve numeric city IDs, so the label is required
- Airport codes (e.g.,
|airport:LAS) don't need a label—they resolve via typeahead
- Use
- Custom tabs:
- Supports up to 2 custom tabs with external URLs
- Custom tab URL is required for tab to render; label defaults to "Link" if omitted
- Position options:
first,last, orafter:<product>(e.g.,after:air) - Custom tabs open in new tab with
noopener,noreferrer - Custom tabs never become the active product tab
- Search date format:
- Use
searchDateFormatto control how dates are formatted in the Core deep-link URL (date1/date2 params) - Options:
mm/dd/yy(default),dd/mm/yy,yy/mm/dd,yyyy/mm/dd - This ONLY affects the URL format sent to the booking platform
- Does NOT change datepicker UI, on-screen date display, or locale-based formatting
- Use
API Configuration (apiPathPrefix)
The apiPathPrefix config option controls how widgets construct API URLs for location autocomplete and data fetching.
Production deployments (recommended):
- Omit
apiPathPrefixor set to empty string"" - Widgets will use root-relative URLs like
/apps/api/locations/ - API calls go to the same origin as the hosting page
Local development:
- Set
apiPathPrefix: "/core" - Enables Vite dev proxy to forward API calls to QA environment
- Example:
http://localhost:5173/core/apps/api/locations/→https://qaone.uat.switchfly.com/apps/api/locations/
When to set apiPathPrefix:
- Never set it in production embed code
- Only set it when testing locally with
npm run dev - The builder UI defaults to
"/core"for development convenience
Switchfly widgets support two integration methods:
- Iframe embed (recommended): simplest integration and maximum isolation from host page styles/scripts.
- Direct script embed (IIFE): renders inline on the host page for tighter visual integration.
Both methods are supported out of the gate. Hosting of the widget IIFE and the API proxy approach will be documented once finalized.
The notes below call out CMS-specific considerations. Unless stated otherwise, iframe embed is the recommended approach.
HubSpot
- Recommended: Iframe embed in a Custom HTML module
- Supported: Direct script embed (subject to HubSpot script/CSP restrictions)
- Allowlist the widget host domain (for example,
your-cdn.com) in Content Security Policy (CSP) if needed - Listen for
SWF_WIDGET_HEIGHTto resize iframe dynamically - URL-encode all color parameters (
#→%23)
Wix
- Recommended: Iframe embed via HTML Embed or Custom Element
- Supported: Direct script embed
- For iframe: Set an explicit height (for example, 600px) or use an auto-height script
- Ensure the iframe
srcdomain (or script source domain) is allowlisted - URL-encode all color parameters (
#→%23)
Webflow
- Recommended: Iframe embed via Custom Code component
- Supported: Direct script embed
- For iframe: Set an explicit height or add a resize listener via postMessage
- URL-encode all color parameters (
#→%23)
Squarespace
- Recommended: Iframe embed using a Code Block
- Supported: Direct script embed
- For iframe: Set an explicit height (Squarespace does not support dynamic iframe resizing)
- Ensure the iframe
srcdomain (or script source domain) is allowlisted - URL-encode all color parameters (
#→%23)
WordPress
- Recommended: Iframe embed using Custom HTML block
- Supported: Direct script embed
- For script embeds, some themes or security plugins may block inline scripts
- For iframe: Set an explicit height or handle resizing via postMessage
- URL-encode all color parameters (
#→%23)
Shopify
- Recommended: Iframe embed using Custom HTML section or Liquid template
- Supported: Direct script embed
- Script embeds may require adding the widget domain to Shopify’s allowed script sources
- For iframe: Set an explicit height or implement postMessage-based resizing
- URL-encode all color parameters (
#→%23)
Search Widget HTML (iframe entrypoint)
Serves the search widget HTML page for iframe embedding.
All parameters are optional and override widget defaults.
Example with branding:
/widgets/search/?locale=fr&cobrand=partner123&accentColor=%230a66c2&bgColorWidget=%23ffffff
Example with destination prefill (numeric city ID):
/widgets/search/?searchParam=%7Ccity:7321&prefillDestinationLabel=San%20Diego
Example with custom tabs:
/widgets/search/?customTab1Label=Cruises&customTab1Url=https://example.com/cruises&customTab1Position=last
query Parameters
| locale | string Example: locale=en Widget locale (e.g., en, es, fr, ja) |
| searchParam | string Example: searchParam=%7Cairport:LAS Pre-fill destination search token (format: "|airport:CODE" or "|city:ID"). Examples:
For numeric city IDs, also provide |
| prefillDestinationLabel | string Example: prefillDestinationLabel=San Diego Optional display label for pre-filled destination. Required when using numeric city ID tokens (e.g., "|city:7321") because the Locations typeahead API cannot resolve numeric IDs. The widget will display this label in the destination input while sending the canonical token to Core Shopping on submit. Not needed for airport codes (e.g., "|airport:LAS") as those resolve via typeahead API. |
| cobrand | string Example: cobrand=partner123 Cobrand identifier (becomes nav= in booking URL) |
| searchDateFormat | string Default: "mm/dd/yy" Enum: "mm/dd/yy" "dd/mm/yy" "yy/mm/dd" "yyyy/mm/dd" Example: searchDateFormat=dd/mm/yy Date format for Core deep-link URL (date1/date2 query params). This only affects the format of dates sent to the booking platform—it does NOT change the datepicker UI or any on-screen date display. Options: mm/dd/yy, dd/mm/yy, yy/mm/dd, yyyy/mm/dd |
| customTab1Label | string Example: customTab1Label=Cruises Label for first custom tab (e.g., "Cruises") |
| customTab1Url | string Example: customTab1Url=https://example.com/cruises URL for first custom tab. Required for tab to render. Opens in new tab when clicked with noopener and noreferrer. |
| customTab1Position | string Default: "last" Enum: "first" "last" "after:bundle" "after:air" "after:hotel" "after:car" "after:activity" Example: customTab1Position=last Position for first custom tab in tab row. Options: "first", "last", "after:bundle", "after:air", "after:hotel", "after:car", "after:activity" |
| customTab2Label | string Example: customTab2Label=Deals Label for second custom tab |
| customTab2Url | string Example: customTab2Url=https://example.com/deals URL for second custom tab. Required for tab to render. Opens in new tab when clicked with noopener and noreferrer. |
| customTab2Position | string Default: "last" Enum: "first" "last" "after:bundle" "after:air" "after:hotel" "after:car" "after:activity" Example: customTab2Position=after:air Position for second custom tab in tab row. Options: "first", "last", "after:bundle", "after:air", "after:hotel", "after:car", "after:activity" |
| discountCode | string Example: discountCode=SUMMER2026 Discount code for promotional pricing.
Passed through to booking URL as |
| currency | string^[A-Z]{3}$ Example: currency=USD Currency code for price display (3-letter ISO 4217 code, e.g., USD, EUR, GBP).
Passed through to booking URL as |
| languageId | integer Example: languageId=3 Numeric language identifier for booking platform.
Passed through to booking URL as |
| utmSource | string Example: utmSource=newsletter UTM source parameter for campaign tracking.
Passed through to booking URL as |
| utmMedium | string Example: utmMedium=email UTM medium parameter for campaign tracking.
Passed through to booking URL as |
| utmCampaign | string Example: utmCampaign=summer_sale_2026 UTM campaign parameter for campaign tracking.
Passed through to booking URL as |
| utmContent | string Example: utmContent=hero_banner UTM content parameter for A/B testing and content differentiation.
Passed through to booking URL as |
| trackId | integer Example: trackId=1234 The agent ID of the referring agent.
Passed through to booking URL as |
| bgColorWidget | string Example: bgColorWidget=%23ffffff Background color (URL-encoded) |
| highlightColor | string Example: highlightColor=%23eef2ff Highlight color for focus/hover states (URL-encoded) |
| accentColor | string Example: accentColor=%230a66c2 Primary accent color (URL-encoded) |
| accentColorHover | string Example: accentColorHover=%23004182 Accent hover color (URL-encoded) |
| accentColorActive | string Example: accentColorActive=%23003366 Accent active/pressed color (URL-encoded) |
Responses
Widget CDN (placeholder - replace with your actual CDN)
QA environment (example)
Hotel Deals Widget HTML (iframe entrypoint)
Serves the hotel deals widget HTML page for iframe embedding.
All parameters are optional and override widget defaults.
Example with branding:
/widgets/hotelDeals/?locale=en&maxItems=6&accentColor=%23dc2626
query Parameters
| locale | string Example: locale=en Widget locale (e.g., en, es, fr, ja) |
| maxItems | integer [ 1 .. 12 ] Example: maxItems=6 Maximum number of hotels to display (1-12) |
| showPrices | boolean Example: showPrices=true Display hotel prices in tiles |
| currency | string^[A-Z]{3}$ Example: currency=USD Currency code for price display (3-letter ISO 4217 code, e.g., USD, EUR, GBP).
Passed through to booking URL as |
| title | string Example: title=Featured Hotels Widget title heading |
| cobrand | string Example: cobrand=partner123 Cobrand identifier (becomes nav= in booking URL) |
| searchParam | string Example: searchParam=%7Cairport:LAS Pre-fill destination search token (format: "|airport:CODE" or "|city:ID"). Examples:
For numeric city IDs, also provide |
| bgColorWidget | string Example: bgColorWidget=%23ffffff Background color (URL-encoded) |
| highlightColor | string Example: highlightColor=%23eef2ff Highlight color for focus/hover states (URL-encoded) |
| accentColor | string Example: accentColor=%230a66c2 Primary accent color (URL-encoded) |
| accentColorHover | string Example: accentColorHover=%23004182 Accent hover color (URL-encoded) |
| accentColorActive | string Example: accentColorActive=%23003366 Accent active/pressed color (URL-encoded) |
Responses
Widget CDN (placeholder - replace with your actual CDN)
QA environment (example)
