Self-Service Booking on a Salesforce Experience Cloud Site
Put the calendar on a public or member-only site and let customers, candidates, students, or staff book their own dates. The records land in your org immediately, and nothing is stored anywhere else.
The usual way to add self-service booking to Salesforce is to bolt on an external scheduling service, then spend the next three months syncing it and explaining it to your security reviewer. MultiDatePick is a Lightning Web Component, so it drops into Experience Builder like any other component and writes to the objects you already own.
Five things people self-book
Appointments
Customers pick a date and time from the slots you make available, filtered by whichever resource they are booking with.
Their own availability
Candidates, contractors, and volunteers click the days they can work, and you get one record per date.
Shared spaces
Members book rooms, desks, courts, or equipment against live capacity, without a Salesforce license each.
Sessions and cohorts
Students or attendees enroll in dated sessions, with the slot closing once it reaches capacity.
What changes
| Self-service scenario | The usual approach | With MultiDatePick |
|---|---|---|
| Let a customer book a slot | External scheduler, synced back on a delay | Native component writing to your object on save |
| Security review | A second vendor, a second data processor | No external host, nothing leaves the org |
| Show only genuinely free slots | Depends on how fresh the sync is | Reads your live records at page load |
| Everyone books the same parent record | Custom development | Static Record Id property, set in the builder |
| Cost as usage grows | Per booking, or per seat, forever | Site visitors are not licensed users |
Guest users, honestly
Public guest access works, and there are two Salesforce platform rules to plan around rather than fight. Guests can read and create records but never edit or delete them, which is a Salesforce licensing limit that applies to every app on the platform, not something this one imposes. Plan guest-facing pages as create-only. And guest-created records need a default owner set on the site, or the insert fails. Both are one-time setup steps, and both are covered in the user guide.
The configuration, in full
Experience Cloud placement is the same component with one extra property, because a public page has no record context to inherit.
| staticRecordId | the property that makes this work. App Pages, Home Pages and Experience Sites have no automatic recordId, so you name the parent record everyone books against |
| relatedObjectApiName | Booking__c |
| relationshipFieldApiName | the lookup back to that parent |
| dateFieldApiName | Booking_Date__c |
| resourceObjectApiName | whatever visitors choose between: an advisor, a room, a piece of equipment |
| capacityField | so a session with twenty seats closes at twenty rather than at one |
| businessHoursStartField businessHoursEndField | on the resource, so you publish only the hours you actually offer |
| conflictBehavior | block — on a public page a clash must never save |
| enableEditMode | false for guests. Guest users cannot edit or delete records anyway, so leaving it on promises something the platform will not deliver |
| preloadExistingDates | true with preloadMode = readonly if you want visitors to see what is already taken without touching it |
recordId, or use parentRecordIdField to resolve the parent from a lookup on the running user's record.| Default record owner | Experience Workspaces → Administration → Preferences → Record Ownership. Guests cannot own records, so without this every insert fails with a transfer error |
| Guest sharing rule | guests need read access to the resource and parent records they reference, or the insert is rejected on the cross-reference |
Choose the view for the audience, not the org
A public site and an internal page usually want different layouts of the same data, and because the view is a property on the component rather than an org-wide setting you can give them exactly that from one install.
On a guest-facing page, calendar or week is what a visitor needs: pick a day, pick a time, submit. Keep availableViews short here. A switcher offering five layouts to a member of the public is noise, and two of them are read only.
For a status or "my bookings" page, agenda is the better answer. It is read only by construction, reads well on a phone, and with agendaFields you control exactly which fields a guest sees on each row.
Self-service booking, without a second vendor
Coming to the Salesforce AppExchange in 2026. Tell us where to send the launch note.
100% Salesforce native. Your data and your configuration never leave your org.