A React library for integrating Tebuto appointment booking into your website.
- Features
- Installation
- Quick Start
- Widget Configuration
- Building Custom Booking UIs
- API Types
- License
- Drop-in Widget - Embed the Tebuto booking widget with a single component
- Custom Booking UIs - Build your own booking interface with powerful React hooks
- Full TypeScript Support - Complete type definitions for all APIs
- Theming - Customize colors, fonts, and styles to match your brand
- React 19 Compatible - Built for the latest React version
# npm
npm install @tebuto/react-booking-widget
# pnpm
pnpm add @tebuto/react-booking-widget
# yarn
yarn add @tebuto/react-booking-widgetRequirements: React 19.0.0 or higher
The simplest way to add Tebuto booking to your site:
import { TebutoBookingWidget } from "@tebuto/react-booking-widget";
function BookingPage() {
return <TebutoBookingWidget therapistUUID="your-therapist-uuid" />;
}Note: You can obtain the therapist UUID from the appointment settings. In the embedding section, click on the HTML button and use the value from the
data-therapist-uuidattribute.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
therapistUUID |
string |
Yes | - | Unique identifier for the therapist |
backgroundColor |
string |
No | transparent |
Background color (hex, rgb, etc.) |
border |
boolean |
No | true |
Show border around the widget |
categories |
number[] |
No | [] |
Filter appointments by category IDs |
includeSubusers |
boolean |
No | false |
Include subuser appointments |
showQuickFilters |
boolean |
No | false |
Show quick filter buttons for time slots |
inheritFont |
boolean |
No | false |
Use parent page font instead of widget font |
theme |
TebutoWidgetTheme |
No | - | Theme customization object |
noScriptText |
string |
No | Default message | Text shown when JavaScript is disabled |
Customize the widget appearance with the theme prop:
import { TebutoBookingWidget } from "@tebuto/react-booking-widget";
function BookingPage() {
return (
<TebutoBookingWidget
therapistUUID="your-uuid"
theme={{
primaryColor: "#10b981",
backgroundColor: "#0f0f10",
textPrimary: "#fafafa",
textSecondary: "#a1a1aa",
borderColor: "#2d2d30",
fontFamily: '"Inter", sans-serif',
inheritFont: false,
}}
/>
);
}| Theme Property | Type | Description |
|---|---|---|
primaryColor |
string |
Primary brand color for buttons, highlights |
backgroundColor |
string |
Main widget background |
textPrimary |
string |
Primary text color |
textSecondary |
string |
Secondary/muted text color |
borderColor |
string |
Border color |
fontFamily |
string |
Font family for the widget |
inheritFont |
boolean |
Inherit font from parent page |
For complete control over your booking interface, use the provided hooks to build a custom implementation.
Wrap your booking components with TebutoProvider to share configuration:
import { TebutoProvider } from "@tebuto/react-booking-widget";
function App() {
return (
<TebutoProvider
therapistUUID="your-uuid"
categories={[1, 2, 3]}
includeSubusers={false}
>
<YourCustomBookingUI />
</TebutoProvider>
);
}| Prop | Type | Required | Description |
|---|---|---|---|
therapistUUID |
string |
Yes | Therapist identifier |
apiBaseUrl |
string |
No | Custom API base URL |
categories |
number[] |
No | Category filter |
includeSubusers |
boolean |
No | Include subusers |
The useBookingFlow hook provides complete booking flow orchestration:
import { TebutoProvider, useBookingFlow } from "@tebuto/react-booking-widget";
function BookingUI() {
const {
step,
goToStep,
therapist,
slots,
selectedDate,
selectDate,
selectedDateSlots,
selectedSlot,
selectSlot,
selectedLocation,
setLocation,
submitBooking,
booking,
reset,
isLoading,
error,
} = useBookingFlow({
onBookingComplete: (booking) => console.log("Booked!", booking),
onError: (error) => console.error("Error:", error),
});
switch (step) {
case "loading":
return <LoadingSpinner />;
case "date-selection":
return (
<DatePicker
availableDates={slots.availableDates}
onSelect={selectDate}
/>
);
case "time-selection":
return <TimeSlotPicker slots={selectedDateSlots} onSelect={selectSlot} />;
case "booking-form":
return <BookingForm onSubmit={submitBooking} isLoading={isLoading} />;
case "confirmation":
return (
<Confirmation
booking={booking.booking}
onDownloadCalendar={booking.downloadCalendar}
onReset={reset}
/>
);
case "error":
return <ErrorDisplay error={error} onRetry={reset} />;
}
}
function App() {
return (
<TebutoProvider therapistUUID="your-uuid">
<BookingUI />
</TebutoProvider>
);
}For fine-grained control, use the individual hooks:
Fetch therapist information:
const { data, isLoading, error, refetch } = useTherapist();
// data: { name, firstName, lastName, address, showWatermark }Fetch and manage available time slots:
const {
slots, // All available slots
slotsByDate, // Slots grouped by date
availableDates, // Array of dates with availability
getSlotsForDate, // Get slots for a specific date
isLoading,
error,
refetch,
} = useAvailableSlots({ categories: [1, 2] });Claim (reserve) a time slot before booking:
const {
claim, // Claim a slot
unclaim, // Release claimed slot
claimData, // Claim response data
isLoading,
error,
} = useClaimSlot();
// Claim a slot
const response = await claim(selectedSlot);
// response: { isAvailable, requirePhoneNumber, requireAddress }Complete the booking:
const {
book, // Submit booking
booking, // Booking response
downloadCalendar, // Download ICS file
reset, // Reset state
isLoading,
error,
} = useBookAppointment();
// Book appointment
const result = await book({
slot: selectedSlot,
client: {
firstName: "Max",
lastName: "Mustermann",
email: "max@example.com",
phone: "+49123456789", // optional
notes: "First appointment", // optional
},
locationSelection: "onsite", // 'virtual' | 'onsite' | 'not-fixed'
});The library includes a full example implementation:
import { CustomBookingExample } from "@tebuto/react-booking-widget";
function BookingPage() {
return <CustomBookingExample therapistUUID="your-uuid" categories={[1, 2]} />;
}All types are exported for TypeScript users:
import type {
// Configuration
TebutoBookingWidgetConfiguration,
TebutoWidgetTheme,
// API Data
Therapist,
TimeSlot,
EnrichedTimeSlot,
ClaimResponse,
BookingRequest,
BookingResponse,
ClientInfo,
// Utilities
AppointmentLocation, // 'virtual' | 'onsite' | 'not-fixed'
Address,
SlotsByDate,
AsyncState,
} from "@tebuto/react-booking-widget";