Cal.com Embed: A Complete Setup Guide
Learn how to embed Cal.com booking calendars on your website. Step-by-step guide for HTML, React, and no-code platforms, plus styling, prefilled forms, and self-hosted setup.
- Cal.com embed adds booking calendars directly to your site without external redirects, reducing scheduling friction and improving conversion
- Choose inline for dedicated booking pages, floating button for secondary placement, or element-click for button-triggered flows
- HTML and React implementations take minutes; customize colors and themes through CSS variables to match your brand
- Self-hosted Cal.diy gives you data ownership and control; managed hosting handles operations for you
- Track bookings through onCreateBookingSuccess callbacks or webhooks for reliable analytics integration
Cal.com embed lets you add a booking calendar directly into your website, email, or application without forcing visitors to leave your site. Instead of sending people to a separate scheduling page, you can embed an inline calendar, a floating button, or a popup that triggers on click. This guide covers implementation, customization, and the practical differences between cloud and self-hosted setups.
What Is Cal.com Embed and Why It Matters
Embedding a booking widget cuts scheduling friction. When a visitor has to click a link, navigate to an external page, wait for it to load, and then select a time, you lose conversions. An embedded calendar lives on your site. The visitor sees availability without leaving.
Cal.com's embed feature solves three problems. First, it reduces form abandonment: people book more when they do not have to switch tabs. Second, it aligns the booking flow with your site's design and branding. Third, it simplifies your tech stack: one tool handles scheduling instead of embedding a competitor's calendar and managing two separate systems.
You will use embeds in three common scenarios. Sales teams embed calendars on their pricing page so prospects book calls without friction. Support teams embed booking calendars in help docs so customers schedule technical support. Creators and freelancers embed booking widgets on service pages to convert interest into booked meetings.
Cal.com offers two hosting models: cloud (cal.com) and self-hosted (cal.diy). If you run self-hosted Cal.com, your embed URLs will point to your own domain instead of cal.com's servers. This matters if you handle sensitive scheduling data or want full data ownership. We will dig into that at the end.
The Three Embed Types: When to Use Each
Cal.com offers three embed variants. Each serves a different use case.
Inline embeds render a full calendar widget directly in the page. The calendar stays visible and takes up space. Use inline embeds on a dedicated appointment booking page or as a permanent fixture on a service page. The entire booking flow happens on your site without any popups or redirects. This is best when booking is your page's primary purpose.
Floating popup buttons add a small button (typically in the corner) that opens a booking calendar in a popup when clicked. The button is not intrusive: it floats on top of your page and users can ignore it. This is ideal for websites where booking is secondary, like a SaaS product page or blog. Mobile users appreciate this approach because it does not consume screen space until they need it.
Element-click embeds trigger a popup when a visitor clicks a button, link, or element you control. You define the exact trigger: a "Book a Demo" button, a CTA link in your copy, or any HTML element. This gives you the most control over user experience. Conversion-focused pages often use this approach because the booking flow feels integrated with the primary call-to-action.
Deciding which to use: If your page is dedicated to scheduling, use inline. If booking is a secondary option, use the floating button. If you want to control when the booking flow starts, use element-click.
How to Generate Your Embed Code in Cal.com
Generating an embed is straightforward. Log into Cal.com, go to Event Types, and select the event you want to embed. Click the "Embed" button in the top-right corner of the event details. You now have access to Cal.com's embed builder.
The builder preview shows you three things: the embed type selector (inline, popup button, or element click), a live preview of the calendar, and customization options. You can change colors, select a theme (light or dark), adjust the layout, and toggle which fields appear in the booking form. The preview updates in real time, so you see exactly what your visitors will see.
Once you are happy with the preview, Cal.com generates code. You get two options: an HTML snippet or a React component. The HTML snippet is a self-contained script tag that you paste into any page. The React component is a JavaScript module that you import and place in your React app. Copy the one that matches your setup.
The generated code also includes a unique embed URL specific to your event and settings. This URL is what actually loads the calendar. If you self-host Cal.com, this URL will use your own domain instead of cal.com.
Implementing Embeds: HTML, React, and No-Code Platforms
HTML Implementation: The HTML snippet is the simplest path. It looks like this: <div id="booking-calendar"></div> followed by a script tag. You paste both into your page HTML, and the calendar loads. No build process. No dependencies. This works in static HTML, WordPress, Webflow, and any platform that lets you add custom code. The disadvantage is limited customization: you cannot easily access the calendar's internals from JavaScript or pass dynamic data without reloading the page.
React Implementation: If your site is a React app, use the Booker component. You import it, pass props for your event, and render it. This gives you programmatic control: you can listen for booking events, pass user data from your app into the form, and trigger the booking flow from your code. The React approach is more flexible for complex applications.
No-Code Platforms: Cal.com has extensions for Webflow and mentions compatibility with Squarespace, but your mileage varies. Some platforms embed external scripts more cleanly than others. If you use a drag-and-drop builder and cannot add custom code, contact Cal.com support to confirm compatibility before investing time.
Here is a minimal React example:
import { Booker } from '@calcom/embed-react';
export default function BookingPage() {
return (
<Booker
username="your-username"
eventSlug="your-event-slug"
isResponsive
/>
);
}
This renders the full booking experience. You can customize styling by passing a styles prop.
Styling and Customization with CSS Variables
Cal.com embeds accept CSS variables to match your brand. The main variables are: --cal-brand (primary color), --cal-text (text color), --cal-border (border color), and --cal-radius (corner radius). You can also toggle between light and dark themes.
If you are using HTML, set CSS variables on the container before loading the embed script. If you are using React, pass a styles object with your custom values.
Here is an example that changes the brand color to match your site:
<style>
:root {
--cal-brand: #0066cc;
--cal-text: #1a1a1a;
--cal-border: #e0e0e0;
--cal-radius: 8px;
}
</style>
For React, you would pass: styles={{ brandColor: '#0066cc' }}.
You can also add custom CSS classes to the embed and style specific elements. This is useful when you need very fine control over spacing, fonts, or button styles. The customClassNames prop lets you add your own class names to the component, and then you style them in your stylesheet.
Prefilling Booking Forms with User Data
Prefilling the booking form with known user data improves conversion. If you already know the visitor's name and email (because they logged in), you can pre-populate those fields so they do not have to type them again.
In React, use the defaultFormValues prop: <Booker defaultFormValues={{ name: 'John Doe', email: 'john@example.com' }} />. The form will populate these fields automatically.
In HTML, you can pass query parameters in the embed URL to achieve the same thing. For example: ?name=John+Doe&email=john@example.com. The exact parameters depend on your event's form fields. Check Cal.com's documentation for the full list of supported parameters.
This approach is powerful when integrated with your app's authentication. After a user logs in, read their profile data and pass it to the embed. They see their information already filled in, reducing friction. Zapier integrations can also pass data from your CRM or email tool into the booking form, automating lead capture.
Tracking Events and Analytics
You likely want to know when someone books a meeting. Cal.com provides two mechanisms for tracking.
First, the onCreateBookingSuccess callback fires after a booking is confirmed. In React, you can listen to this event and send data to your analytics tool: onCreateBookingSuccess={() => gtag('event', 'booking_created')}. This lets you track conversion rates, see which pages drive the most bookings, and attribute bookings to traffic sources.
Second, you can set up webhooks. When a booking is created, Cal.com sends a POST request to a URL you specify, containing all the booking details. You can use this to update your CRM, send confirmation emails, or trigger downstream workflows. This is more reliable than client-side tracking because webhooks execute server-side regardless of browser extensions or privacy tools that block analytics scripts.
For Google Analytics 4 integration, send an event when onCreateBookingSuccess fires. For Segment or other CDP tools, use the same callback to track the booking event in your data warehouse. Webhook-based tracking is better for accurate reporting because it does not depend on user's browser behavior.
Self-Hosted vs. Cloud: Embed Setup Differences
If you run Cal.com in the cloud (cal.com), embeds use Cal.com's domain and infrastructure. If you run self-hosted Cal.diy, embeds use your own domain.
The implementation is identical. You still generate an embed, still get the same customization options, still have the same features. The difference is the URL. Cloud embeds load from cal.com/[username]/[event]. Self-hosted embeds load from your-domain.com/[username]/[event].
Why this matters: If you are in a regulated industry (finance, healthcare) or handle sensitive scheduling data, self-hosting gives you data residency and control. You are not routing bookings through Cal.com's servers. If you want a fully branded experience without a third-party domain appearing anywhere in the booking flow, self-hosting removes that dependency.
Cal.diy, the open-source version of Cal.com, uses the MIT license. This means you have full access to the code, can modify it, and can run it on your own infrastructure. With 49.7K stars and 15.5K forks on GitHub, the project has significant community backing and ongoing maintenance.
For teams running self-hosted Cal.com, we recommend Opsily's managed Cal.com hosting. Instead of managing the infrastructure yourself--handling updates, backups, scaling, and security patches--Opsily runs Cal.com for you. You get the data ownership benefits of self-hosting without the operational overhead. Visit our Cal.com hosting page to learn how managed hosting works and what that looks like for your team.
Frequently Asked Questions
How can I embed a booking calendar on my website?
Log into Cal.com, navigate to your event, click "Embed," choose your embed type (inline, popup, or element-click), customize the appearance, and copy the generated code. For HTML sites, paste the snippet. For React sites, import and use the Booker component. For no-code platforms like Webflow, check Cal.com's platform-specific guides.
Is Calendly still free?
Calendly offers a free plan with one calendar and basic scheduling. Paid plans start at $12 per month for additional calendars and automation. Cal.com also offers a free plan and paid options starting at a similar price range, but the exact pricing depends on your hosting model and features.
Does Cal.com record meetings?
Cal.com does not record meetings by default. It schedules meetings and integrates with calendar providers like Google Calendar and Outlook. If you want recording, you can integrate Cal.com with Zoom or other conferencing tools that support recording, and then record the meeting through those platforms.
Which is better: Cal or Calendly?
It depends on your needs. Calendly is a simpler, consumer-friendly scheduling tool. Cal.com is more flexible and transparent: it is open-source, offers self-hosting, and has more customization options. If you need basic scheduling and do not care about data ownership or customization, Calendly works. If you want to own your data or need advanced features, Cal.com is stronger.
Is there a better option than Calendly?
Several alternatives exist: Cal.com, Acuity Scheduling, and Setmore all handle booking and scheduling. Cal.com stands out for being open-source and self-hostable. If transparency and data control matter to you, Cal.com is worth evaluating.
What are the downsides of Calendly?
Calendly is hosted on Calendly's servers, so you do not own your data. Customization is limited compared to open-source tools. The free plan is minimal (one calendar, basic features). If you need white-labeling, advanced automation, or self-hosting, Calendly will not meet those needs.
The Bottom Line
Cal.com embed eliminates the friction of sending visitors to a separate scheduling page. Choose inline if booking is your page's main purpose, floating button if it is secondary, and element-click if you want precise control over the trigger. Implementation takes minutes in HTML or React, and styling matches your brand through CSS variables.
The real differentiation comes with self-hosting. If you handle sensitive data, need full data ownership, or want to avoid third-party infrastructure, running Cal.com on your own servers gives you that control. Managed hosting removes the operational burden of running it yourself.
Start with a simple inline or popup embed on a test page, track conversions, and scale from there. Check out Opsily's managed Cal.com hosting to learn how to self-host Cal.com without the headache.