> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt ## Resource: Build a Custom Booking Calendar Page ## Article: Build a Custom Booking Calendar Page ## Article Link: https://dev.wix.com/docs/develop-websites-sdk/code-your-site/extend-wix-business-solutions/replace-app-pages/build-a-custom-booking-calendar-page.md ## Article Content: # Tutorial: Build a Custom Booking Calendar Page This tutorial shows you how to replace a site's default [Wix Booking Calendar page](https://support.wix.com/en/article/wix-bookings-customizing-your-calendar-page) with your own customized version. This allows you to modify or extend the page's functionality to suit your precise business needs and create a unique booking experience for your customers. By the end of this tutorial, you'll have a custom booking calendar page that displays service information, shows available time slots, and seamlessly integrates with your site's booking flow.  Follow these steps to build a custom booking calendar page: 1. [Add a custom calendar page to your site](#step-1--add-a-custom-calendar-page-to-your-site) 2. [Design your custom calendar page](#step-2--design-your-custom-page) 3. [Add code to your custom page](#step-3--add-code-to-your-custom-page) > **Note:** The code in this tutorial uses the following module versions: > > - @wix/site-window (v1.0.0) > - @wix/bookings (v1.0.0) > - @wix/site-location (v1.0.0) > > Learn how to install npm packages [in the editor](https://dev.wix.com/docs/develop-websites/articles/coding-with-velo/packages/work-with-npm-packages-in-the-editor.md) or [using the CLI](https://dev.wix.com/docs/develop-websites/articles/coding-with-velo/packages/work-with-npm-packages-with-the-wix-cli.md). ## Before you begin It's important to note the following points before doing this tutorial: * You need to have Wix Bookings installed on your site with at least 1 service created. * This feature is currently not supported with [Multi-service bookings appointments](https://support.wix.com/en/article/wix-bookings-scheduling-multi-service-appointments). ## Step 1 | Add a custom calendar page to your site In this step, you'll replace the default Wix Bookings calendar page with a custom page that you can fully control and customize. At the end of this step, you'll have a blank custom page ready for design and coding. To create a custom calendar page: ::::tabs :::Wix-Studio 1. Click  and then **Start Coding** from the sidebar on the left side of the editor. 2. Click **Pages**  on the sidebar. 3. On the **Booking Calendar** (under **Bookings Pages**), click the **More Actions** icon . 4. Click **Replace with custom page**. 5. In the confirmation panel, click **Replace**.  ::: :::Wix-Editor 1. Enable the site's code editor. 2. Click **Pages**  on the left side of the editor. 3. Click **Bookings Pages**, and then on the **Booking Calendar** page, click the **More Actions** icon . 4. Click **Replace with custom page**. 5. In the confirmation panel, click **Replace**.  ::: :::: ## Step 2 | Design your custom page In this step, you'll design the layout and add the necessary elements to your custom booking calendar page. At the end of this step, you'll have a page with the elements needed to display service information, show available time slots, and allow site visitors to make selections. To design your custom page: 1. [Add elements to the page](https://support.wix.com/en/article/wix-editor-adding-and-deleting-elements) to create your business's customized design and functionality. Make sure to include these essential elements: * Text element to display information about the selected service. * Dropdown or selection element to provide site visitors with a way to view availability and select a slot. * Button element to navigate to the next step in the bookings flow. 2. Give your elements meaningful IDs that you'll use in your code: * `#serviceName` for the service name text. * `#dateDropdown` for the time slot selection dropdown. * `#nextButton` for the navigation button. ## Step 3 | Add code to your custom page In this step, you'll add code that connects your custom page to your booking service's data. We'll use the JavaScript SDK to retrieve information about the selected service, display service availability, and navigate to the next step in the booking flow. At the end of this step, you'll have access to the service information that was passed to your custom page. To retrieve and display service data with code: 1. Add the following import statements at the top of your page code: ```js import { window } from '@wix/site-window'; import { availabilityCalendar } from '@wix/bookings'; import { location } from '@wix/site-location'; ``` 2. Call the [Get App Page Data](https://dev.wix.com/docs/sdk/frontend-modules/window/get-app-page-data.md) method to get the [service object](https://dev.wix.com/docs/sdk/frontend-modules/window/app-page-data.md) associated with the page: ```js $w.onReady(async function () { const pageData = await window.getAppPageData(); const serviceId = pageData.service.id; const serviceName = pageData.service.name; }); ``` > **Note:** To receive a populated page data object using `getAppPageData()` when testing your code, do the following: > > * Create at least 1 Bookings service. > * Preview the Bookings Calendar page and then return to the editor. 3. Query the service availability. The following example queries the availability for the upcoming week in the site visitor's time zone. ```js const today = new Date(); const nextWeek = new Date(today.getTime() + 7 * 24 * 60 * 60 * 1000); let query = { filter: { serviceId: [serviceId], startDate: today, endDate: nextWeek, } } const selectedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const options = { timezone: selectedTimezone }; const availability = await availabilityCalendar.queryAvailability(query, options); const entries = availability.availabilityEntries; ``` 4. Populate your custom page's elements with the service information and availability. The code below displays the service name, and creates dropdown options for the service availability. ```js $w('#serviceName').text = serviceName; const slotOptions = []; entries.forEach((entry, index) => { const label = `${entry.slot.startDate}-${entry.slot.endDate}`; const value = `${index}`; slotOptions.push({ label, value }); }); $w('#dateDropdown').options = slotOptions; ```
__Tip:__ You can customize how the time slots are displayed by modifying the `label` format. For example, you might want to show just the time or format the date differently.5. Add an [event handler](https://dev.wix.com/docs/develop-websites/articles/coding-with-velo/frontend-code/about-event-handlers-in-wix.md) to the page's action button so that it navigates to the next page in the flow, which is typically the Booking Form. You can [create a link to a preloaded Booking Form](https://dev.wix.com/docs/sdk/.md frontend-modules/bookings/shareable-booking-form-links), specifying the appropriate query params based on the visitor's selections. ```js $w('#nextButton').onClick(() => { const selectedIndex = $w('#dateDropdown').selectedIndex; const selectedSlot = entries[selectedIndex].slot; let queryParams = `?bookings_serviceId=${serviceId}&bookings_resourceId=${selectedSlot.resource._id}&bookings_startDate=${encodeURIComponent(selectedSlot.startDate)}&bookings_endDate=${encodeURIComponent(selectedSlot.endDate)}&bookings_timezone=${selectedTimezone}`; const nextUrl = "/booking-form" + queryParams; location.to(nextUrl); }); ``` ## Complete example code Here's the complete code for your custom booking calendar page: ```js import { window } from '@wix/site-window'; import { availabilityCalendar } from '@wix/bookings'; import { location } from '@wix/site-location'; $w.onReady(async function () { // Get service data const pageData = await window.getAppPageData(); const serviceId = pageData.service.id; const serviceName = pageData.service.name; // Query availability const today = new Date(); const nextWeek = new Date(today.getTime() + 7 * 24 * 60 * 60 * 1000); let query = { filter: { serviceId: [serviceId], startDate: today, endDate: nextWeek, } } const selectedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const options = { timezone: selectedTimezone }; const availability = await availabilityCalendar.queryAvailability(query, options); const entries = availability.availabilityEntries; // Populate elements $w('#serviceName').text = serviceName; const slotOptions = []; entries.forEach((entry, index) => { const label = `${entry.slot.startDate}-${entry.slot.endDate}`; const value = `${index}`; slotOptions.push({ label, value }); }); $w('#dateDropdown').options = slotOptions; // Redirect to booking form $w('#nextButton').onClick(() => { const selectedIndex = $w('#dateDropdown').selectedIndex; const selectedSlot = entries[selectedIndex].slot; let queryParams = `?bookings_serviceId=${serviceId}&bookings_resourceId=${selectedSlot.resource._id}&bookings_startDate=${encodeURIComponent(selectedSlot.startDate)}&bookings_endDate=${encodeURIComponent(selectedSlot.endDate)}&bookings_timezone=${selectedTimezone}`; const nextUrl = "/booking-form" + queryParams; location.to(nextUrl); }); }); ``` You've now successfully created a custom booking calendar page that integrates seamlessly with your site's booking flow. Your custom page can now display service data, provide site visitors with an interface for selecting available time slots, and direct them to the next page in the booking process.