---
title: "BookingPro — Framer component · Best of Framer"
description: "$25.00 · Framer component · by MJ Jung · Forms. BookingPro sends a clean JSON payload to Formspree or any webhook, so it slots straight into the workflow you already have: - Zapier / Make / n8n…"
canonical: "https://framer.elliotli.dev/component/bookingpro"
---

[Home](/)/[Components](/components)/[Forms](/components/category/forms)/BookingPro

# BookingPro

Subscription-free Framer booking widget.

[View on Framer](https://framer.com/marketplace/components/bookingpro/?via=elliot-li)

![BookingPro preview image 1](https://framer.elliotli.dev/og/component/bookingpro/bd3d9f664ff7291f/1600x1200.jpg)

## Summary

BookingPro sends a clean JSON payload to Formspree or any webhook, so it slots straight into the workflow you already have: - Zapier / Make / n8n — Auto-send a confirmation email…

## Description

\# BookingPro

A Calendly-style booking widget for Framer. Visitors pick a date and time on your own site and submit their details — fully branded, on your own domain, with no monthly subscription. Drop it in, paste your Formspree ID, optionally connect a Google Sheet that holds your taken slots, and you're live.

\---

\## Why You'll Like It

\- Calendly-style booking without the monthly fee. A polished date+time picker that lives on your own domain, with your own brand. One-time purchase instead of a per-seat subscription.

\- Friendly booking horizon. Pick "1 month from today", "3 months", "1 year" — no need to think in raw days. Calendar math is correct (1 month = the same day next month, not 30 days).

\- Pick your week start. Monday (Europe / ISO, default), Sunday (US), or Saturday (Middle East). The grid and weekday labels rotate automatically.

\- Four booking modes built in. Single appointment, multi-time block, hotel-style date range (check-in / check-out), or multiple independent dates. One component, all the use cases.

\- Three ways to know what's already taken. Edit the booked list right in Framer, or sync from a Google Sheet, or pull from any JSON URL.

\- Already-booked slots are visually clear. Taken slots are grayed out and show your custom message — no double bookings.

\- Truly customizable form. You decide which fields to ask: name, email, phone, project description, anything.

\- Sends straight to Formspree (or any webhook). The chosen date(s) and time(s) are added to the payload automatically.

\- Designer-first. Four ready-made presets (Modern, Minimal, Soft, Dark), every color editable, every label rewriteable. Korean / Japanese / Spanish weekday and month names just need a quick paste.

\- No code, no plugins, no CMS. No CMS dependency — booking data comes from your panel or a URL you choose.

\---

\## Install Into Your Framer Project

After purchase you'll receive a \`.txt\` file containing the component URL. To bring it into Framer:

1\. Open the \`.txt\` file and copy the URL (Ctrl + C / Cmd + C).

2\. Go to your Framer dashboard and open the project where you want to use it.

3\. Click into the canvas.

4\. Paste the URL directly onto the canvas (Ctrl + V / Cmd + V).

Framer will detect the link and place the component on your page. Drag it, resize it, and configure it from the right-side property panel.

\---

\## Four Booking Modes

Pick one in the Booking Mode dropdown at the top of the property panel.

\### Date + Single Time

Classic Calendly-style. User picks a date, then one time slot. Best for: 1-on-1 calls, consultations, demos, photo shoots.

\### Date + Multiple Times

User picks a date, then any number of time slots in that day. Optional Consecutive Only toggle requires the picked slots to be adjacent — perfect for "book a 2-hour studio block" or "book lunch + the meeting after".

\### Date Range (Check-in / Check-out)

Hotel-style. User picks a start date (check-in), then an end date (check-out). The whole range highlights, the form summary shows the night count. Best for: lodging, multi-day rentals, conference room reservations.

\### Multiple Dates

User picks any number of independent days. Best for: "select all the dates you're available", workshop signups with optional days, photo session day picker.

The booked list works for all modes. In date-only modes (range / multi-date), any taken date in your sheet blocks that whole day.

\---

\## Setup in 60 Seconds

1\. Drop the component on your canvas.

2\. Open the property panel on the right.

3\. Availability — set your working days, hours, and slot length (e.g. Mon–Fri, 9–18, 30-minute slots).

4\. Form Fields — add the questions you want to ask the visitor.

5\. Submission — pick Formspree, paste your form ID. Done.

Optional but powerful: set Existing Bookings → Source to Google Sheet and paste a published CSV URL so booked slots come straight from your spreadsheet.

\---

\## What You Can Customize

Every group below is a collapsible panel in the Framer property pane.

\- Style Preset — pick a look in one click (Modern / Minimal / Soft / Dark / Custom).

\- Availability — working days (1=Mon, 2=Tue…), hours, slot length, lunch break, holidays, timezone label.

\- Existing Bookings — pick how to sync taken slots: manual list, Google Sheet, or JSON URL.

\- Form Fields — add any number of fields with id, label, type, placeholder, and required flag.

\- Submission — Formspree ID, Webhook URL + Allowed Domains, email subject, the keys used for date/time in the payload.

\- Messages — every visible string. Translate to any language, change the booked-slot warning, the success message, the back/submit labels — anything.

\- Calendar Style — header, weekday labels, date colors, today ring, booked-slot dot color.

\- Slots Style — slot colors (default / hover / selected / booked), columns, padding, radius.

\- Form Style — input colors, label color, font sizes, spacing.

\- Buttons — primary and secondary button colors, radius, padding, weight.

\- Container — background, border, radius, summary pill, progress bar.

Most designers only touch a few of these. Pick a preset, edit your fields, ship.

\---

\## Three Ways to Track Booked Slots

You decide where the list of "already taken" times lives.

\### 1. Manual List

Type slots into the property panel. Best for solo founders or low-volume use.

\### 2. Google Sheet (CSV)

Step 1 — Create the sheet. Open a new Google Sheet and add two column headers in the first row: \`date\` and \`time\`. Then list each booked slot as one row:

| date | time |

|------|------|

| 2026-05-15 | 10:00 |

| 2026-05-15 | 14:00 |

| 2026-05-16 | 11:00 |

Format rules:

\- date in \`YYYY-MM-DD\` format (e.g. \`2026-05-15\`)

\- time in 24-hour \`HH:MM\` format (e.g. \`10:00\`, \`14:30\`)

\- One booking per row

Step 2 — Publish the sheet as CSV. In Google Sheets:

1\. File → Share → Publish to web

2\. Choose your sheet, format Comma-separated values (.csv), click Publish

3\. Copy the URL Google gives you

4\. Paste into the Sheet CSV URL field in the property panel

The component re-checks the sheet on load (and optionally every N seconds). Add or remove a row in the sheet and the website updates without redeploying. Beautiful for a small team where someone manages bookings in Sheets.

For date-only modes (Date Range / Multiple Dates): the \`time\` column is still required, but the value is ignored — you can put anything (e.g. \`00:00\`). One row per blocked day.

\### 3. Custom JSON URL

For anyone with a backend or automation. Point it at any URL that returns JSON like:

\`\`\`json

\[

{ "date": "2026-05-15", "time": "10:00" },

{ "date": "2026-05-15", "time": "14:00" }

\]

\`\`\`

or \`{ "bookings": \[...\] }\` or \`{ "data": \[...\] }\`. The component handles all three shapes.

\---

\## What the Booked Slot Behavior Looks Like

When a slot is already taken:

\- It appears grayed out in the time grid

\- The clickable behavior depends on Disable Booked Slots:

\- On (default): the slot can't be clicked at all

\- Off: clicking it shows your custom Booked Slot Message ("Sorry, this time is already taken — please pick another")

You write the message in any language you want, with any tone. The default is friendly: "This slot is already taken. Please pick another time."

\---

\## Where Your Data Goes

When the user submits, the component sends a JSON \`POST\` to your endpoint with all the fields they filled in plus the chosen date and time.

\### Formspree

Endpoint: \`[https://formspree.io/f/{your-form-id}\`](https://formspree.io/f/{your-form-id}`). You only paste the form ID (e.g. \`xnqklbpr\`) — not a full URL. The component builds the HTTPS endpoint for you.

\### Webhook (POST)

Any URL that accepts a JSON body — Zapier, Make, n8n, your own server, Notion via integrations, Airtable, Slack incoming webhooks. Two rules:

1\. HTTPS only. \`[http://\`](http://`) URLs are rejected.

2\. List the allowed domains. In the Submission group, fill Allowed Domains with a comma-separated list of the hosts you trust, e.g. \`[hooks.zapier.com](http://hooks.zapier.com), [hook.us1.make.com](http://hook.us1.make.com), [your-backend.com](http://your-backend.com)\`. The component refuses to POST anywhere else. Subdomains count (so \`[hook.us1.make.com](http://hook.us1.make.com)\` covers \`\*.[hook.us1.make.com](http://hook.us1.make.com)\` as well).

This keeps visitor data safe: if a webhook URL is ever changed by mistake (or by someone you didn't authorize), submissions won't silently leak to an unknown server.

\### Payload Shape

The exact keys depend on the Booking Mode you chose. Custom form field IDs always come through. Here are the extras the component adds automatically:

Date + Single Time (default)

\`\`\`json

{

"name": "Sarah Kim",

"email": "[sarah@example.com](mailto:sarah@example.com)",

"date": "2026-05-15",

"time": "14:00",

"\_subject": "New booking request"

}

\`\`\`

Date + Multiple Times

\`\`\`json

{

"name": "Sarah Kim",

"email": "[sarah@example.com](mailto:sarah@example.com)",

"date": "2026-05-15",

"time": "14:00",

"times": "14:00, 14:30, 15:00",

"\_subject": "..."

}

\`\`\`

Date Range (Check-in / Check-out)

\`\`\`json

{

"name": "Sarah Kim",

"email": "[sarah@example.com](mailto:sarah@example.com)",

"date": "2026-05-15",

"checkOut": "2026-05-18",

"nights": "3",

"dates": "2026-05-15, 2026-05-16, 2026-05-17, 2026-05-18",

"\_subject": "..."

}

\`\`\`

Multiple Dates

\`\`\`json

{

"name": "Sarah Kim",

"email": "[sarah@example.com](mailto:sarah@example.com)",

"date": "2026-05-15",

"dates": "2026-05-15, 2026-05-22, 2026-06-05",

"\_subject": "..."

}

\`\`\`

All key names (\`date\`, \`time\`, \`checkOut\`, \`nights\`, \`dates\`, \`times\`) are configurable in the Submission group, in case your tool expects different names.

If your endpoint replies with a non-2xx status, the component shows your Error Message with a Back button so the user can try again.

\---

\## Great For

\- 1-on-1 consultations and discovery calls

\- Coaching sessions and tutoring

\- Photo / video shoot booking

\- Studio / equipment rental

\- Salon / clinic appointments (with the holiday list filled in)

\- Hotels, B&Bs, and lodging with check-in / check-out (range mode)

\- Multi-day rentals and tour bookings

\- Workshop / class registration with optional days (multi-date mode)

\- Internal demos and sales calls

\- Real estate viewings

\- Anywhere you currently bounce between emails to schedule, or pay $10–30/month for a tool you barely use

\---

\## Power It Up With Your Favorite Tools

BookingPro sends a clean JSON payload to Formspree or any webhook, so it slots straight into the workflow you already have:

\- Zapier / Make / n8n — Auto-send a confirmation email to the visitor, push the booking into Google Sheets, create a Notion page, or message a Slack channel.

\- Google Calendar / Outlook — Add a Zapier step to create a calendar event the moment a booking lands.

\- Gmail / SendGrid / Resend — Trigger a branded confirmation email from your own address.

\- Stripe / PayPal — For paid bookings, wire the webhook to a payment link and unlock the calendar event after checkout.

\- Your own server — Point the webhook at any HTTPS endpoint that accepts a JSON \`POST\`. Total control.

Because the data comes through as a regular \`POST\`, every "what if I want X to happen automatically" question has an answer.

\---

\## A Few Tips

\- For consultations, set Slot Length to 30 or 60 and keep Working Days to weekdays only.

\- If you allow same-day bookings, set Min Days Ahead to 0. To require a day's notice, set it to 1.

\- Use Holidays for fixed off-days (e.g. \`2026-12-25, 2026-01-01\`).

\- Korean labels: paste \`1월, 2월, 3월, 4월, 5월, 6월, 7월, 8월, 9월, 10월, 11월, 12월\` into Month Labels and \`월, 화, 수, 목, 금, 토, 일\` into Weekday Labels.

\- For Google Sheet sync, keep your sheet really simple — just \`date\` and \`time\` columns. Anything else is ignored.

\- Test once with Submission → Send To = None to walk through the flow without sending anything.

\---

\## Need Help?

If a submission isn't arriving, check that:

\- The Formspree ID is just the ID (e.g. \`xnqklbpr\`), not the full URL.

\- Formspree has confirmed your sender email (they email you once after the first submission).

\- Your webhook (if using one) is HTTPS and the host is listed in Allowed Domains (comma-separated, e.g. \`[hooks.zapier.com](http://hooks.zapier.com), [hook.us1.make.com](http://hook.us1.make.com)\`).

\- Your webhook responds with a 2xx status.

If you see a red error banner on the Framer canvas:

\- That banner shows up only while you're designing — it's a heads-up that the Google Sheet / JSON URL didn't load. Visitors will never see it.

\- Click Retry to re-fetch without touching the property panel.

\- Common cause: the Sheet wasn't published as CSV, or the JSON URL returned a non-2xx status.

If booked slots aren't grayed out:

\- The Sheet URL must be the published CSV URL (ends with \`output=csv\`), not the regular sheet URL.

\- The column headers in your sheet should match what you typed in Date Column and Time Column (default \`date\` and \`time\`).

\- Dates should be in \`YYYY-MM-DD\` format. The component also accepts \`MM/DD/YYYY\` and \`YYYY/MM/DD\` but \`YYYY-MM-DD\` is safest.

Everything else works out of the box.

## Rank history [How rankings work →](/terms#rankings)

-   All · #3511

## Details

- **Author**: MJ Jung
- **Price**: $25.00
- **Published**: 2026-06-01
- **Updated**: 2026-06-01
- **Added**: 2026-05-25
- **Categories**: Forms

## More across types

-   [Wallble: Guest Book & Wall of Love](/plugin/wallble-guest-book-wall-of-love) — Wallble · Free — Guest book & Wall of Love

## More like this

-   [Stay Booking Pro](/component/stay-booking-pro) — Design Foundry · $10 — Stay Planner with Dynamic Pricing
-   [Postcode Checker](/component/postcode-checker) — Sean Weekes · $15 — Do we cover your area? (UK
-   [Property Calculators](/component/property-calculators) — Sean Weekes · $12 — UK Stamp Duty, mortgage and yield
-   [UTM Lead Capture](/component/utm-lead-capture) — Sean Weekes · $9 — See where every lead came from
