Quick start
The most accurate snippet is the one on your booking link. These examples use placeholder paths on this origin.
- 01
Open Share on a booking link
In MicroCal, go to Booking links and choose Share, then Embed. That copy uses your real workspace and meeting slugs. - 02
Or start from the examples below
Replace your-workspace and your-meeting with your slugs. The origin is already correct. - 03
Publish
Guests book without leaving your page. Paid meetings open Stripe in the top window, then return to confirmation.
Snippets
Pick a stack and a widget type, then copy. Next.js works as a Server Component with next/script.
import Script from "next/script";
export function MicroCalEmbed() {
return (
<>
<div
className="microcal-inline-widget"
data-url="https://www.microcalendar.com.au/book/your-workspace/your-meeting/embed"
style={{ minWidth: 320, height: 700 }}
/>
<Script src="https://www.microcalendar.com.au/embed.js" strategy="afterInteractive" />
</>
);
}Paste into any App Router page. next/script loads embed.js once, even if you use this on more than one route. Snippets use www.microcalendar.com.au. Replace your-workspace and your-meeting, or copy from Share.
Load embed.js once in Next.js
If you already put Script in the root layout, you only need the widget markup on each page - next/script will not download embed.js twice.
import Script from "next/script";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
<Script src="https://www.microcalendar.com.au/embed.js" strategy="afterInteractive" />
</body>
</html>
);
}Page events
The iframe posts messages to the parent. Listen if you want to hide a banner, fire analytics, or continue a funnel after a booking.
resize- Content height changed. The widget uses this to avoid nested scrollbars.
view_changed- Guest moved between host, date, details, or confirmation.
scheduled- Booking confirmed. Payload includes guestEmail, startAt, and endAt.
window.addEventListener("message", (event) => {
if (event.data?.source === "microcal" && event.data.event === "scheduled") {
// Guest just booked. event.data.payload has guestEmail, startAt, endAt.
}
});