Skip to main content

Widget / JS Online Booking Component for any Website

Bookla provides a widget for online booking that can be embedded into any website or application. This component allows you to offer a seamless booking experience without the need for extensive coding or integration work.

The widget is fully customizable — you can control colors, spacing, typography, localization, behavior, and form fields, all without touching CSS directly. Use the visual styler below to configure your widget interactively, then export the generated code.


Setup

Add the widget container and script to your page:

<div id="bookla-booking-widget" class="bookla-widget"></div>
<script src="https://bookla.pages.dev/booking-widget-standalone-v1.6.2.global.js"></script>

Then initialize the widget:

const container = document.getElementById('bookla-booking-widget');

BookingWidgetStandalone.initBookingWidget(container, {
apiKey: 'your-api-key', // Required
region: 'US', // Required: "US" or "EU"
companyId: 'your-company-id', // Required
serviceId: 'your-service-id', // Optional: pre-select a service
// ...configuration options
});

The initialization script handles DOMContentLoaded automatically in the exported code. Only the properties you want to override need to be specified; everything else falls back to sensible defaults.

Required Parameters

ParameterTypeDescription
apiKeyStringYour Bookla API key
region"US" | "EU"API region endpoint
companyIdStringYour Bookla company ID

Optional Top-Level Parameters

ParameterTypeDescription
serviceIdStringPre-select a specific service by ID

Theme Configuration

The theme object controls the visual appearance of the widget. It is divided into three sections: colors, spacing, and typography.

Colors

General Colors

These apply globally across the widget.

ParameterTypeDescription
colors.backgroundColor or GradientMain background color of the widget container
colors.textHex colorPrimary text color
colors.secondaryTextHex colorSecondary/muted text color
colors.errorHex colorColor for error states and validation messages
colors.successHex colorColor for success states
colors.borderBorder stringDefault border styling (e.g. "1px solid #cccccc")

Button Colors

Buttons support three states: normal, hover, and disabled. Each state accepts the same set of properties. There are three button variants: primary (button), secondary (secondaryButton), and icon (iconButton).

The path pattern is colors.<buttonType>.<state>.<property>.

PropertyTypeDescription
backgroundColor or GradientButton background
textHex colorButton text (or icon) color
borderBorder stringButton border

Example:

theme: {
colors: {
button: {
normal: { background: '#1a73e8', text: '#ffffff', border: '1px solid #1a73e8' },
hover: { background: '#1557b0', text: '#ffffff', border: '1px solid #1557b0' },
disabled: { background: '#e0e0e0', text: '#9e9e9e', border: '1px solid #e0e0e0' },
},
secondaryButton: {
normal: { background: '#ffffff', text: '#1a73e8', border: '1px solid #1a73e8' },
// hover, disabled...
},
iconButton: {
normal: { background: 'transparent', text: '#333333', border: 'none' },
// hover, disabled...
},
}
}

Item Colors

Items represent selectable elements like services, time slots, and date cells. They support four states: normal, selected, hover, and disabled.

Path pattern: colors.item.<state>.<property>

PropertyTypeDescription
backgroundColor or GradientItem background
textHex colorItem primary text
secondaryTextHex colorItem secondary text
borderBorder stringItem border

List Colors

List containers wrap groups of items. They support normal and selected states.

Path pattern: colors.list.<state>.<property>

PropertyTypeDescription
backgroundHex colorList container background
textHex colorList text color
secondaryTextHex colorList secondary text
borderBorder stringList border

Form Colors

Form inputs support normal and error states.

Path pattern: colors.form.<state>.<property>

PropertyTypeDescription
backgroundHex colorInput background
textHex colorInput text color
borderBorder stringInput border

Summary Colors

The summary section displays the booking overview before confirmation.

Path pattern: colors.summary.<property>

PropertyTypeDescription
backgroundHex colorSummary section background
textHex colorSummary text color
secondaryTextHex colorSummary secondary text
borderBorder stringSummary border

Spacing

Spacing values control padding, border radius, and gaps throughout the widget. Most values are numbers representing pixels.

General Spacing

ParameterTypeDefaultDescription
spacing.paddingNumber or PaddingWidget container padding. A single number applies uniformly; a string like "16px 12px 16px 12px" sets top/right/bottom/left individually
spacing.borderRadiusNumber8Corner radius for the main container
spacing.gridGapNumberGap between grid items (e.g. time slots)
spacing.rowGapNumberGap between rows
spacing.sectionGapNumberGap between major sections

Text Spacing

ParameterTypeDescription
spacing.text.gapNumberGap between text elements
spacing.text.labelGapNumberGap between a label and its input

Element-Specific Spacing

Each of the following elements has padding (Number or Padding string) and borderRadius (Number) properties:

ElementPath prefixDescription
Buttonspacing.buttonPrimary and secondary buttons
Icon Buttonspacing.iconButtonIcon-only buttons
Itemspacing.itemSelectable items (services, times, etc.)
Listspacing.listList containers
Formspacing.formForm input fields
Summaryspacing.summaryBooking summary section

Example:

theme: {
spacing: {
padding: 20,
borderRadius: 12,
gridGap: 8,
sectionGap: 24,
button: { padding: '12px 24px', borderRadius: 8 },
item: { padding: 16, borderRadius: 6 },
form: { padding: '10px 14px', borderRadius: 6 },
}
}

Typography

ParameterTypeDefaultDescription
typography.fontFamilyStringCSS font family for all text (e.g. "Inter, sans-serif")
typography.fontSize.baseNumber16Base font size in pixels
typography.fontSize.largeNumber18Large font size in pixels
typography.fontWeight.normalNumber400Normal font weight (100–900)
typography.fontWeight.mediumNumber500Medium font weight (100–900)
typography.lineHeight.titleNumber1.4Line height multiplier for titles
typography.lineHeight.textNumber1.6Line height multiplier for body text

Gradient Support

Any color property that accepts a "Color or Gradient" type can be configured as a gradient via the _gradients key on the theme. The Styler app provides a visual gradient editor for these.

// GradientValue structure
{
type: 'solid' | 'linear' | 'radial',
colors: ['#ff0000', '#0000ff'], // Array of hex colors
angle: 135, // For linear gradients (0–360)
position: 'center', // For radial gradients
}

Gradient-capable properties include background, all button state backgrounds, and all item state backgrounds.


Localization Configuration

The localization object lets you customize every text string in the widget. This is useful both for translating the widget into different languages and for tailoring the copy to your brand voice.

General

ParameterTypeDescription
localeStringLocale code (e.g. "en", "es", "fr", "de")

Time Selection

ParameterTypeDescription
times.selectTimeTitleStringTitle shown on the time selection step
times.noAvailableTimesStringMessage when no times are available
times.loadingTextStringLoading indicator text
times.continueButtonStringContinue button label
times.loginUrlString or nullURL for the login link (null to hide)

Resource Selection

ParameterTypeDescription
resource.selectResourceTitleStringTitle for the resource picker
resource.anyResourceOptionStringLabel for the "any resource" option

Guest Form

ParameterTypeDescription
guestForm.firstNameFieldLabelStringFirst name field label
guestForm.firstNameFieldErrorStringFirst name validation error
guestForm.lastNameFieldLabelStringLast name field label
guestForm.lastNameFieldErrorStringLast name validation error
guestForm.emailFieldLabelStringEmail field label
guestForm.emailFieldErrorStringEmail required error
guestForm.emailFieldInvalidErrorStringEmail format error

Result Screens

Success Screen:

ParameterTypeDescription
successScreen.titleStringTitle after successful booking
successScreen.descriptionStringDescription text
successScreen.bookAgainString"Book again" button text

Pending Screen:

ParameterTypeDescription
pendingScreen.titleStringTitle when booking is pending approval
pendingScreen.descriptionStringDescription text
pendingScreen.bookAgainString"Book again" button text

Error Screen:

ParameterTypeDescription
errorScreen.titleStringTitle on error
errorScreen.descriptionStringDescription text
errorScreen.reloadStringReload/retry button text

Buttons

ParameterTypeDescription
bookButtonStringPrimary "Book" button label
loginButtonStringLogin button label
backButtonStringBack navigation button label
loadingTextStringGeneric loading text

Service Selection

ParameterTypeDescription
serviceSelection.titleStringService list title
serviceSelection.descriptionStringService list subtitle

Group and Duration Selection

ParameterTypeDescription
group.selectTitleStringTitle for group/category selection
duration.selectTitleStringTitle for duration selection

Tickets

ParameterTypeDescription
tickets.selectTicketsTitleStringTitle for ticket selection
tickets.selectTicketsDescriptionStringDescription for ticket selection
tickets.noTicketsAvailableStringEmpty state message
tickets.continueButtonStringContinue button label
tickets.ticketsSummaryTitleStringSummary title for selected tickets

Days (Check-in/Check-out)

ParameterTypeDescription
days.checkInStringCheck-in label
days.checkOutStringCheck-out label
days.nightStringSingular form of "night"
days.nightsStringPlural form of "nights"

Terms and Conditions

ParameterTypeDescription
terms.acceptTextStringCheckbox label text
terms.urlsArrayArray of { text: string, url: string } objects linking to legal documents

Form

ParameterTypeDescription
form.isRequiredTextStringText for required field indicators
form.selectOptionStringDefault placeholder for select inputs

Coupon/Code

ParameterTypeDescription
code.fieldLabelStringCode input label
code.fieldErrorStringCode field error message
code.notFoundErrorStringError when code is not found

Add-ons

ParameterTypeDescription
addons.titleStringAdd-ons section title
addons.requiredString"Required" badge text
addons.selectOptionStringDefault dropdown option text
addons.totalLabelStringTotal price label

Subscriptions (Subscription Widget)

ParameterTypeDescription
subscriptions.titleStringSubscription list title
subscriptions.subtitleStringList subtitle
subscriptions.summaryTitleStringSummary title
subscriptions.buyTextStringPurchase button text
subscriptions.noSubscriptionsStringEmpty state message
subscriptions.visitsStringVisits limit text

Gift Cards (Gift Card Widget)

ParameterTypeDescription
giftCards.titleStringGift card list title
giftCards.subtitleStringList subtitle
giftCards.summaryTitleStringSummary title
giftCards.buyTextStringPurchase button text
giftCards.noGiftCardsStringEmpty state message
giftCards.validityTextStringValidity period label
giftCards.taxIncludedTextString"Tax included" indicator
giftCards.taxExcludedTextString"Tax excluded" indicator

Booking Configuration

All booking configuration parameters are passed at the top level of the configuration object (not nested under a config key).

General Options

ParameterTypeDefaultDescription
transitionType"slide" | "fade" | "flip" | "stack""slide"Page transition animation between steps
showServiceSelectorBooleanfalseShow the service selection screen as the first step
hideResourcePickerBooleanfalseHide the resource picker (staff, room, etc.). Set to true to skip resource selection
guestEnabledBooleanAllow guest booking without authentication
termsEnabledBooleanShow terms and conditions checkbox
addonsEnabledBooleanEnable the add-ons selection step
preselectedDateDatePre-select a specific date when the widget loads

Pricing

ParameterTypeDescription
showPriceBooleanDisplay prices in the UI
showComparedPriceBooleanShow original price alongside discounted price
showDecimalPlacesBooleanShow decimal places in price display

Days (Multi-day Bookings)

ParameterTypeDefaultDescription
minNightsNumber1Minimum number of nights for a booking
maxNightsNumber365Maximum number of nights for a booking

Coupon/Code

ParameterTypeDescription
code.enabledBooleanShow the coupon/code input field
code.requiredBooleanMake the code field mandatory

Service Overrides

You can override titles and behavior for individual services via the servicesConfig object:

servicesConfig: {
services: [
{
serviceId: 'service-abc-123', // Required: Bookla service ID
title: 'Premium Massage', // Override display title
description: 'A luxurious 60-min session', // Override description
hideResourcePicker: true, // Hide resource picker for this service
selectResourceTitle: 'Choose your therapist',
anyResourceOption: 'No preference',
}
]
}

Ticket Overrides

ticketsConfig: {
tickets: [
{
ticketId: 'ticket-xyz-789', // Required: Bookla ticket ID
title: 'VIP Entry', // Override display title
}
]
}

Subscription Overrides

subscriptionsConfig: {
subscriptions: [
{
subscriptionId: 'sub-001',
title: 'Monthly Unlimited',
description: 'Unlimited access for 30 days',
}
]
}

Gift Card Overrides

giftCardsConfig: {
giftCards: [
{
giftCardId: 'gc-001',
title: 'Birthday Gift Card',
description: 'The perfect gift for someone special',
}
]
}

Custom Form Fields

You can add custom fields to the booking form to collect additional information from customers.

Each custom field supports the following properties:

PropertyTypeRequiredDescription
type"text" | "number" | "textarea" | "phone" | "url" | "select" | "multiselect"YesInput type
labelTextStringYesLabel displayed above the field
requiredBooleanYesWhether the field is mandatory
errorTextStringIf requiredError message shown on validation failure
inputWidth"auto / span 1" | "auto / span 2"NoColumn span — span 1 for half-width, span 2 for full-width
optionsStringFor select/multiselectComma-separated or newline-separated list of options

Example:

customFormFields: [
{
type: 'text',
labelText: 'Company Name',
required: false,
inputWidth: 'auto / span 2',
},
{
type: 'phone',
labelText: 'Phone Number',
required: true,
errorText: 'Please enter your phone number',
inputWidth: 'auto / span 1',
},
{
type: 'select',
labelText: 'How did you hear about us?',
required: false,
inputWidth: 'auto / span 2',
options: 'Google,Social Media,Friend,Other',
},
{
type: 'textarea',
labelText: 'Special Requests',
required: false,
inputWidth: 'auto / span 2',
},
]

Complete Example

Here is a full configuration bringing together all sections. The HTML setup:

<div id="bookla-booking-widget" class="bookla-widget"></div>
<script src="https://bookla.pages.dev/booking-widget-standalone-v1.6.2.global.js"></script>

The initialization script:

const container = document.getElementById('bookla-booking-widget');

BookingWidgetStandalone.initBookingWidget(container, {
// Required
apiKey: 'your-api-key',
region: 'US',
companyId: 'your-company-id',

// Optional: pre-select a service
serviceId: 'your-service-id',

// Booking behavior
transitionType: 'fade',
showServiceSelector: true,
hideResourcePicker: false,
guestEnabled: true,
termsEnabled: true,
addonsEnabled: false,

// Theme
theme: {
colors: {
background: '#ffffff',
text: '#1a1a1a',
secondaryText: '#6b7280',
error: '#dc2626',
success: '#16a34a',
border: '1px solid #e5e7eb',
button: {
normal: { background: '#2563eb', text: '#ffffff', border: 'none' },
hover: { background: '#1d4ed8', text: '#ffffff', border: 'none' },
disabled: { background: '#d1d5db', text: '#9ca3af', border: 'none' },
},
item: {
normal: { background: '#f9fafb', text: '#1a1a1a', secondaryText: '#6b7280', border: '1px solid #e5e7eb' },
selected: { background: '#eff6ff', text: '#1e40af', secondaryText: '#3b82f6', border: '1px solid #2563eb' },
hover: { background: '#f3f4f6', text: '#1a1a1a', secondaryText: '#6b7280', border: '1px solid #d1d5db' },
disabled: { background: '#f9fafb', text: '#d1d5db', secondaryText: '#d1d5db', border: '1px solid #f3f4f6' },
},
},
spacing: {
padding: 24,
borderRadius: 12,
gridGap: 8,
sectionGap: 20,
button: { padding: '12px 24px', borderRadius: 8 },
item: { padding: 14, borderRadius: 8 },
},
typography: {
fontFamily: 'Inter, system-ui, sans-serif',
fontSize: { base: 15, large: 18 },
fontWeight: { normal: 400, medium: 600 },
lineHeight: { title: 1.3, text: 1.5 },
},
},

// Localization
localization: {
locale: 'en',
times: {
selectTimeTitle: 'Pick a time',
noAvailableTimes: 'No availability for this date',
continueButton: 'Continue',
},
bookButton: 'Confirm Booking',
backButton: 'Back',
successScreen: {
title: "You're all set!",
description: 'Your booking has been confirmed. Check your email for details.',
bookAgain: 'Make another booking',
},
terms: {
urls: [{ text: 'terms and conditions', url: '/terms' }],
},
},

// Custom form fields
customFormFields: [],

// Service & ticket overrides
servicesConfig: { services: [] },
ticketsConfig: { tickets: [] },
});