Embeddable Widgets
Booking widget#
Embed a full booking flow on any page. The widget handles date and time picking and the booking form.
<div id="booking-widget"></div>
<script src="https://cdn.goodinbound.com/widgets/booking.js"></script>
<script>
GoodInbound.booking({
projectSlug: "acme",
eventTypeSlug: "consultation",
container: "#booking-widget",
theme: {
primaryColor: "#1B4332"
}
});
</script>
| Property | Type | Required | Description |
|---|---|---|---|
projectSlug |
string | Yes | Your project's URL slug |
eventTypeSlug |
string | Yes | The event type to book |
container |
string | HTMLElement | Yes | CSS selector or DOM element |
theme.primaryColor |
string | No | Override brand color |
hidden |
Record<string, string | string[]> | No | Prefill hidden (or visible) fields by field id. Wins over host-page query params. |
ui |
{ hideBanner?, hideBranding?, hideTitle?, hideIntro?, hideAvatar? } |
No | Hide booking chrome for this embed. hideBranding works on every plan. URL hide_* flags also work. |
Form widget#
Embed a form on your site. The widget renders each page in sequence and handles validation, submission, and the completion state.
<div id="form-widget"></div>
<script src="https://cdn.goodinbound.com/widgets/form.js"></script>
<script>
GoodInbound.form({
projectSlug: "acme",
formSlug: "contact",
container: "#form-widget",
theme: {
primaryColor: "#1B4332"
}
});
</script>
| Property | Type | Required | Description |
|---|---|---|---|
projectSlug |
string | Yes | Your project's URL slug |
formSlug |
string | Yes | The form's URL slug |
container |
string | HTMLElement | Yes | CSS selector or DOM element |
theme.primaryColor |
string | No | Override brand color |
hidden |
Record<string, string | string[]> | No | Prefill hidden (or visible) fields by field id. Wins over host-page query params. |
ui |
{ hideBanner?, hideBranding?, hideTitle?, hideIntro?, hideMedia? } |
No | Hide form chrome for this embed. hideBranding works on every plan. |
Theme#
Both widgets accept a theme object to match your brand: colors, border radius, and fonts.
GoodInbound.booking({
projectSlug: "acme",
eventTypeSlug: "consultation",
container: "#booking-widget",
theme: {
primaryColor: "#1B4332",
borderRadius: "12px",
fontFamily: "Inter, sans-serif"
}
});
Both widgets are zero-dependency bundles under 6KB gzipped.
Prefill and hidden fields#
Hidden fields stay off the public screen but still accept values. Keys are field ids, not labels. Query values win over a field's default, and the widget's hidden option wins over the host page query string.
Share link
https://goodinbound.com/acme/contact?utm_source=newsletter&plan=pro
Embed with JS values
GoodInbound.form({
projectSlug: "acme",
formSlug: "contact",
container: "#form-widget",
hidden: {
user_id: "usr_123",
plan: "pro"
}
});
Both widgets forward the host page query string into the iframe, so ?plan=pro on your site fills a plan field. The exceptions are embed, theme, and the keys the widget uses itself: gi_source, gi_journey, gi_page, gi_ref, gi_fbp, and gi_fbc. Booking links also accept reserved name, email, and notes when those ids are free. File fields cannot be prefilled.
Hide page chrome#
Form and event settings can hide the banner, title, intro, section image, avatar, and GoodInbound branding. A share link or embed can hide more with query flags, but a flag cannot unhide something the resource already hid. Hiding branding works on every plan.
Share link
https://goodinbound.com/acme/contact?hide_banner=1&hide_title=1
Widget
GoodInbound.form({
projectSlug: "acme",
formSlug: "contact",
container: "#form-widget",
ui: { hideBanner: true, hideTitle: true }
});
Flags are hide_banner, hide_branding, hide_title, hide_intro, hide_avatar, and hide_media. Custom CSS can target [data-gi-banner], [data-gi-title], [data-gi-intro], [data-gi-avatar], [data-gi-media], and [data-gi-branding].