Recipes
Ready-to-copy BookingJs examples for common requirements – complete patterns that combine multiple BookingJs concepts and are testable in the browser.
This page collects complete, copyable examples that combine multiple BookingJs concepts. You can try out and modify the linked live examples directly in the browser.
Customizing fonts globally and per component
Sets a new default font for the entire widget and custom fonts for buttons and links (PRO).
<div id="bookingjs" style="margin: 32px"></div>
<script type="module">
import * as timum from 'https://cdn.timum.de/bookingjs/1/booking.js';
timum.init(
{ ref: 'booking-widget-demo-resource@timum' },
{
typography: {
// Default font for the entire widget
fontFamily: '"Ysabeau Office", Roboto, Helvetica, Arial',
// Font sources, loaded via <link rel="stylesheet">
fontSource: [
'https://fonts.googleapis.com/css2?family=Tangerine:wght@400;700&family=Ysabeau+Office:ital,wght@0,1..1000;1,1..1000&display=swap',
],
},
components: {
// Override font for buttons only
MuiButton: {
styleOverrides: {
root: { fontFamily: '"Tangerine", Roboto, Helvetica, Arial' },
},
},
// Override font for links only
MuiLink: {
styleOverrides: {
root: { fontFamily: '"Tangerine", Roboto, Helvetica, Arial' },
},
},
},
},
);
</script>
Booking only for invited customers
Shows BookingJs only when the visitor arrives via a personal invitation link with ref and invitee. Identification is handled via pData against your CRM platform (e.g. onOffice).
<div id="bookingjs" style="margin: 32px"></div>
<script type="module">
import * as timum from 'https://cdn.timum.de/bookingjs/1/booking.js';
// Hide widget container
const hideBookingJs = () => {
const el = document.getElementById('bookingjs');
if (el) el.style.display = 'none';
};
// Read parameters from the URL
const url = new URL(window.location.href);
const ref = url.searchParams.get('ref');
const inviteeId = url.searchParams.get('invitee');
// Without invitation parameters: do not initialize
if (!ref || !inviteeId) {
hideBookingJs();
} else {
timum.init({
ref: ref,
// Pass customer ID for verification via pData
pData: {
platform: 'onoffice',
personId: inviteeId,
},
callbacks: {
// Hide if no bookable appointments are found
fetchingBookablesSucceeded: (bookables) => {
const hasBookables = bookables && Object.values(bookables).length > 0;
if (!hasBookables) hideBookingJs();
},
fetchingBookablesFailed: () => hideBookingJs(),
},
});
}
</script>
Hiding the widget when no appointments are available
Hides the container when the appointment query comes back empty or fails – for example, to show your own message instead.
<div id="bookingjs" style="margin: 32px"></div>
<script type="module">
import * as timum from 'https://cdn.timum.de/bookingjs/1/booking.js';
// Hide widget container
const hideBookingJs = () => {
const el = document.getElementById('bookingjs');
if (el) el.style.display = 'none';
};
timum.init({
ref: 'ihre-ressourcen-referenz',
callbacks: {
// Query successful, but no appointments
fetchingBookablesSucceeded: (bookables) => {
const hasBookables = bookables && Object.values(bookables).length > 0;
if (!hasBookables) hideBookingJs();
},
// Query failed (e.g. server error)
fetchingBookablesFailed: () => hideBookingJs(),
},
});
</script>
Multi-Resource Mode for the CondensedView
Shows overlapping appointments from multiple resources color-coded side by side – ideal when the appointment matters more than the specific resource. With only one resource or no overlaps, the mode automatically falls back to the standard display.
import { TimumBooking } from '@timum/booking';
<TimumBooking
appConfig={{
ref: ['resource-1@provider', 'resource-2@provider'],
calendarFrontend: 'condensedView', // or detailsCondensedView
calendarFrontendOptions: {
condensedView: {
multiResourceMode: true, // Enable multi-resource display
},
},
}}
/>;
Custom required field with validation and translation
Removes the mobile and message fields, adds a required "Gender" field as a select field, and translates the label and validation message (PRO).
<div id="bookingjs" style="margin: 32px"></div>
<script type="module">
import * as timum from 'https://cdn.timum.de/bookingjs/1/booking.js';
timum.init({
ref: 'booking-widget-demo-resource@timum',
fields: {
// Explicitly set fields to undefined to remove them
message: undefined,
mobile: undefined,
// Select field with required validation
gender: {
index: 3,
title: 'fields.gender.title',
type: 'select',
validation: timum.yup.string().required('validation.gender_field_required'),
options: [
{ key: 'm', title: 'fields.gender.male' },
{ key: 'w', title: 'fields.gender.female' },
{ key: 'd', title: 'fields.gender.other' },
],
},
},
// Necessary to send custom field values as the message
sendCustomValuesInMessage: true,
localization: {
de: {
validation: { gender_field_required: 'Bitte wählen.' },
fields: {
gender: { title: 'Geschlecht', male: 'Männlich', female: 'Weiblich', other: 'Divers' },
},
},
en: {
validation: { gender_field_required: 'Please select an option.' },
fields: {
gender: { title: 'Gender', male: 'Male', female: 'Female', other: 'Others' },
},
},
},
callbacks: {
// Process the entered value further in the callback
createBookingStarted: ({ data }) => {
console.log(data.gender);
},
},
});
</script>
