Embedding links on your website
Embedding scheduling links is an easy way to let people book time with you without navigating away from your website. This guide will teach you how to install our embed script and the various ways to trigger scheduling links to appear.
Installing the embed script
Copy and paste the following JavaScript code just before the closing </body>
tag:
<script>window.SavvyCal=window.SavvyCal||function(){(SavvyCal.q=SavvyCal.q||[]).push(arguments)};</script> <script async src="https://embed.savvycal.com/v1/embed.js"></script> <script> SavvyCal('init') </script>
We support 4 different modes for your SavvyCal embed:
- Display pop-up via hyperlink
- Display a floating pop-up button
- Open a pop-up via JavaScript
- Render an inline booking interface
Read on for details about how to do it!
1. Display pop-up via hyperlink
To open a scheduling link when someone clicks a hyperlink, add a data-savvycal-embed
attribute to the link.
<a data-savvycal-embed href="https://savvycal.com/derrick/chat">Schedule time with me</a>
We'll display the link from the href
in a lightbox.
If you'd like to prefill the user's email address or name, you can optionally set the data-email
and data-display-name
attributes respectively:
<a data-savvycal-embed data-email="derrick@savvycal.com" data-display-name="Derrick Reimer" href="https://savvycal.com/derrick/chat">Schedule time with me</a>
Here are all the data attributes you can use:
Attribute | Description |
data-email |
The email address to prefill. |
data-display-name |
The full name of the scheduler to prefill. |
data-phone |
The scheduler's phone number to prefill. The number should be provided as a numeric string, beginning with the country code (without parentheses, spaces, or dashes). For example, to prefill with the number (800) 555-0100, set the value 18005550100 . |
data-view |
The default view to use (either week or month ). |
data-theme |
The theme to use; either light , dark , or os (to match the viewer's operating system preferences). |
data-hide-avatar |
Whether the avatar should be hidden on sidebar (hidden if true , otherwise not hidden). |
data-hide-banner |
Whether the banner should be hidden on sidebar (hidden if true , otherwise not hidden). |
2. Display a floating pop-up button
To render a widget at the bottom of your site, enable it when initializing the script by setting enabled
to true
and populating the link
attribute.
<script> SavvyCal('init', { widget: { enabled: true, link: 'derrick/chat' } }) </script>
This will inject a floating button at the bottom your site:
The widget configuration accepts the following properties:
Property | Default Value | Description |
enabled |
false |
Determines whether the widget is visible. |
link |
— | The ID for a specific link (e.g. derrick/chat ) or index page (e.g. derrick ). Required. |
email |
— | The scheduler's email address to prefill. Optional. |
displayName |
— | The scheduler's first and last name to prefill. Optional. |
phone |
— | The scheduler's phone number to prefill. The number should be provided as a numeric string, beginning with the country code (without parentheses, spaces, or dashes). For example, to prefill with the number (800) 555-0100, set the value 18005550100 . |
icon |
"calendar" |
The icon to display on the button (either calendar or none ). |
prompt |
"Schedule a time" |
The button text. To omit the text, set this to false or an empty string ("" ). |
backgroundColor |
"#FFCA00" |
The background color for the button. |
textColor |
"#141E2F" |
The text color for the button. |
delay |
1000 |
The number of milliseconds to wait before the widget appears. |
position |
"bottom-right" |
The position for the floating button (either "bottom-right" or "bottom-left"). |
metadata |
{} |
A object containing custom metadata you'd like to attach to events (e.g. {"user_id": 123} ). Optional. |
questions |
{} |
A object containing custom question data to prefill. Keys should be the index of the question, starting at 0 for the first question, 1 for the second question, and so on. (e.g. if the first custom question was "Your Company Name", you would prefill that using the following data:{0: "Acme, Inc"} ). Optional. |
theme |
"light" |
The theme to use; either light , dark , or os (to match the viewer's operating system preferences). Optional. |
view |
— | The default view; either week or month (defaults to the pre-configured default view for the link). Optional. |
zIndex |
10000 |
The base z-index value to use for the widget popover. You shouldn't generally need to change this, unless your site uses extremely high z-indexes elsewhere. Optional. |
hideAvatar |
false |
Whether the avatar should be hidden on sidebar. Optional. |
hideBanner |
false |
Whether the banner should be hidden on sidebar. Optional. |
You can also update your widget configuration after the initial init
call like this:
<script> // For example, this will disable the widget SavvyCal('widget', { enabled: false }); // This will enable the widget and update the prompt SavvyCal('widget', { enabled: true, prompt: 'Book with me' }); </script>
3. Open a pop-up via JavaScript
You may use the open
call to open the embed any time after calling init
:
<script>window.SavvyCal=window.SavvyCal||function(){(SavvyCal.q=SavvyCal.q||[]).push(arguments)};</script> <script async src="https://embed.savvycal.com/v1/embed.js"></script> <script> SavvyCal('init'); SavvyCal('open', { link: 'derrick/chat' }); </script>
The open
command accepts the following options:
Property | Default Value | Description |
link |
— | The ID for a specific link (e.g. derrick/chat ) or index page (e.g. derrick ). Required. |
email |
— | The scheduler's email address to prefill. Optional. |
displayName |
— | The scheduler's first and last name to prefill. Optional. |
phone |
— | The scheduler's phone number to prefill. The number should be provided as a numeric string, beginning with the country code (without parentheses, spaces, or dashes). For example, to prefill with the number (800) 555-0100, set the value 18005550100 . |
metadata |
{} |
A object containing custom metadata you'd like to attach to events (e.g. {"user_id": 123} ). Optional. |
questions |
{} |
A object containing custom question data to prefill. Keys should be the index of the question, starting at 0 for the first question, 1 for the second question, and so on. (e.g. if the first custom question was "Your Company Name", you would prefill that using the following data:{0: "Acme, Inc"} ). Optional. |
theme |
"light" |
The theme to use; either light , dark , or os (to match the viewer's operating system preferences). Optional. |
view |
— | The default view; either week or month (defaults to the pre-configured default view for the link). Optional. |
hideAvatar |
false |
Whether the avatar should be hidden on sidebar. Optional. |
hideBanner |
false |
Whether the banner should be hidden on sidebar. Optional. |
4. Render an inline booking interface
This option allows you to place the SavvyCal scheduling interface directly inline with your other website content.
To render your link inline, make an inline
call after you call init
:
<div id="booking-page"> <!-- this is where we will inject the interface --> </div> <script>window.SavvyCal=window.SavvyCal||function(){(SavvyCal.q=SavvyCal.q||[]).push(arguments)};</script> <script async src="https://embed.savvycal.com/v1/embed.js"></script> <script> SavvyCal('init'); SavvyCal('inline', { link: 'derrick/chat', selector: '#booking-page' }); </script>
The inline
command accepts the following options:
Property | Default Value | Description |
link |
— | The ID for a specific link (e.g. derrick/chat ) or index page (e.g. derrick ). Required. |
selector |
— | The DOM selector for node where we should render the interface (e.g. #booking-page ). Required. |
email |
— | The scheduler's email address to prefill. Optional. |
displayName |
— | The scheduler's first and last name to prefill. Optional. |
phone |
— | The scheduler's phone number to prefill. The number should be provided as a numeric string, beginning with the country code (without parentheses, spaces, or dashes). For example, to prefill with the number (800) 555-0100, set the value 18005550100 . |
metadata |
{} |
A object containing custom metadata you'd like to attach to events (e.g. {"user_id": 123} ). Optional. |
questions |
{} |
A object containing custom question data to prefill. Keys should be the index of the question, starting at 0 for the first question, 1 for the second question, and so on. (e.g. if the first custom question was "Your Company Name", you would prefill that using the following data:{0: "Acme, Inc"} ). Optional. |
theme |
"light" |
The theme to use; either light , dark , or os (to match the viewer's operating system preferences). Optional. |
view |
— | The default view; either week or month (defaults to the pre-configured default view for the link). Optional. |
hideAvatar |
false |
Whether the avatar should be hidden on sidebar. Optional. |
hideBanner |
false |
Whether the banner should be hidden on sidebar. Optional. |
Listening for events
When someone schedules a time on an embedded booking, we dispatch an event on the window. You may listen for this event and perform actions (such as tracking the event in analytics or sending the data over to another provider):
<script> window.addEventListener("savvycal.scheduled", (ev) => { // The `detail` property contains the following data about the newly-scheduled event: // // id - the event ID // link - the link slug (e.g. "derrick/chat") // startAt - the start time of the event // endAt - the end time of the event // email - the scheduler's email address // displayName - the scheduler's display name // fields - custom question data // phoneNumber - the scheduler's phone number (if collected) // timeZone - the scheduler's time zone (e.g. "America/Chicago") // guests - additional guests invited to the event // url - the event URL const { id, link } = ev.detail; // Do something with the data, like record an analytics event... }) </script>
Using Custom Domains
If you have a custom domain, you should specify your custom domain in the embed code. This can be done simply by adding an origin
property to the init
call:
// Configuring a custom domain of "https://meet.yourdomain.com" SavvyCal('init', { origin: 'meet.yourdomain.com' }); // The other calls stay the same SavvyCal('inline', { link: 'derrick/chat', selector: '#booking-page' });
This also works with defining widgets at the same time, just be sure to put the origin property outside of the widget configuration:
SavvyCal('init', { origin: 'meet.yourdomain.com', widget: { enabled: true, link: 'derrick/chat' } })