# Quickstart: Scheduler

Source: https://developer.nylas.com/docs/v3/getting-started/scheduler/

Nylas Scheduler gives your users embeddable scheduling pages that handle availability, booking, and calendar sync across Google, Microsoft, and Exchange -- without you building any of that logic.

This quickstart walks you through embedding the Scheduler components in a web app and creating your first scheduling page.

> **Info:** 
> **Want programmatic control instead?** You can also create and manage scheduling configurations entirely through the [Scheduler API](/docs/v3/scheduler/) without embedding UI components.

The complete code for this quickstart is on GitHub: [Web component (HTML)](https://github.com/nylas-samples/quickstart-scheduler-html) or [React](https://github.com/nylas-samples/quickstart-scheduler-react).

<img
  src="/docs/v3/getting-started/images/v3-scheduler-quickstart-app.png"
  alt="A sample web app that demonstrates a Scheduling Page and the Scheduler Editor"
  title="Sample quickstart app"
  style="width:70%;"
/>

## Before you begin

You need:

- **Node.js v18+** -- run `node -v` to check your version.
- **A Nylas application with a client ID** -- if you haven’t set one up yet, follow the [CLI setup](/docs/v3/getting-started/cli/) or [Dashboard setup](/docs/v3/getting-started/dashboard/). Your client ID is on the Dashboard Overview page.

## Bootstrap your app

Create a new local project. There are two paths: Web components (HTML) or React. Pick one and follow it through the rest of the guide.

```bash
mkdir nylas-scheduler/
cd nylas-scheduler/
touch index.html
touch scheduler-editor.html
```

```bash
npm create vite@latest nylas-scheduler
# -> When prompted, choose the "React" template
# -> When prompted, choose the "TypeScript" language
cd nylas-scheduler/
npm install react-router-dom # Needed for routing
npm install @nylas/react@latest # Install the Nylas React components
# Quick verify: you should now have a `public/`, `src/`, and `node_modules/` folder inside the `nylas-scheduler` folder.
```

## Register a callback URI

Register a callback URI so Nylas can redirect users after authentication. Since we're running locally, the URI uses `localhost`.

> **Warn:** 
> **You might need to use a different port number**. You should use the conventional port that your chosen language and framework uses.

1. In your Sandbox application, click **Hosted Authentication** in the left navigation, and click **Callback URIs**.
2. Click **Add a callback URI**, and enter your application's callback URI.
3. Select the **JavaScript** platform.
4. For **URL**, enter `http://localhost:<PORT>/scheduler-editor`.
5. For **Origin**, enter `http://localhost:<PORT>`.
6. Click **Add callback URI**.

<img
  src="/docs/v3/getting-started/images/v3-scheduler-add-javascript-callback-uri.png"
  alt="Hosted authentication screen showing the Callback URIs tab, and a freshly added entry for a localhost callback URI."
  style="width:50%;"
/>

The URL endpoints can be anything you want. However, they must match the callback URI and port in your application when you configure the Scheduler Editor Component.

## Add the Scheduler components

Include the Scheduler Editor and Scheduling components in your app. The files you need to update depend on your framework:

| Framework       | UI Component     | Files                   |
| --------------- | ---------------- | ----------------------- |
| HTML/Vanilla JS | Scheduler Editor | `scheduler-editor.html` |
|                 | Scheduling       | `index.html`            |
| React           | Scheduler Editor | `App.tsx`, `index.css`  |
|                 | Scheduling       | `App.tsx`, `App.css`    |

See the [Scheduler UI component reference](/docs/reference/ui/) for all available options and data properties.

> **Warn:** 
> Make sure to replace the `NYLAS_CLIENT_ID` with the value you copied from the Dashboard in the [Get your application credentials](#set-up-your-nylas-account) step.

```html [include_scripts-HTML (scheduler-editor.html)]

<!-- scheduler-editor.html -->

<!doctype html>
<html class="h-full bg-white" lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Nylas Scheduler Editor Component</title>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
      rel="stylesheet"
    />
    <script src="https://cdn.tailwindcss.com"></script>

    <style type="text/css">
      body {
        font-family: "Inter", sans-serif;
      }
    </style>
  </head>
  <body class="h-full">
    <div class="grid h-full place-items-center">
      <!-- Add the Nylas Scheduler Editor component -->
      <nylas-scheduler-editor />
    </div>

    <!-- Configure the Nylas Scheduler Editor component -->
    <script type="module">
      import { defineCustomElement } from "https://cdn.jsdelivr.net/npm/@nylas/web-elements@latest/dist/cdn/nylas-scheduler-editor/nylas-scheduler-editor.es.js";

      defineCustomElement();

      const schedulerEditor = document.querySelector("nylas-scheduler-editor");
      schedulerEditor.schedulerPreviewLink = `${window.location.origin}/?config_id={config.id}`;
      schedulerEditor.nylasSessionsConfig = {
        clientId: "<NYLAS_CLIENT_ID>", // Replace with your Nylas client ID from the previous section.
        redirectUri: `${window.location.origin}/scheduler-editor`,
        domain: "https://api.us.nylas.com/v3",
        hosted: true,
        accessType: "offline",
      };

      schedulerEditor.defaultSchedulerConfigState = {
        selectedConfiguration: {
          // Create a public Configuration that doesn't require a session.
          requires_session_auth: false,
          scheduler: {
            rescheduling_url: `${window.location.origin}/reschedule/:booking_ref`,
            cancellation_url: `${window.location.origin}/cancel/:booking_ref`,
          },
        },
      };
    </script>
  </body>
</html>


```

```html [include_scripts-HTML (index.html)]

<!-- index.html -->

<!doctype html>
<html class="h-full bg-white" lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Nylas Scheduling Component</title>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
      rel="stylesheet"
    />
    <script src="https://cdn.tailwindcss.com"></script>

    <style type="text/css">
      body {
        font-family: "Inter", sans-serif;
      }
    </style>
  </head>
  <body>
    <div class="grid gap-0 h-full place-items-center">
      <div class="grid gap-4">
        <!-- A button to view the Scheduler Editor -->
        <a
          href="scheduler-editor.html"
          class="w-fit border border-blue-500 hover:bg-blue-100 text-blue-500 font-bold py-2 px-4 rounded"
        >
          View Scheduler Editor
        </a>

        <!-- Add the Nylas Scheduling Component -->
        <nylas-scheduling></nylas-scheduling>
      </div>
    </div>

    <!-- Configure the Nylas Scheduling Component with a Configuration ID. -->
    <script type="module">
      import { defineCustomElement } from "https://cdn.jsdelivr.net/npm/@nylas/web-elements@latest/dist/cdn/nylas-scheduling/nylas-scheduling.es.js";

      defineCustomElement();

      const nylasScheduling = document.querySelector("nylas-scheduling");
      nylasScheduling.schedulerApiUrl = "https://api.us.nylas.com";

      // Get the Configuration ID from the URL (`?config_id=<NYLAS_SCHEDULER_CONFIGURATION_ID>`).
      const urlParams = new URLSearchParams(window.location.search);

      // If `config_id` doesn't exist, throw a `console.error`.
      if (!urlParams.has("config_id")) {
        console.error(
          "No Scheduler Configuration ID found in the URL. Please provide a Configuration ID.",
        );
      }

      // Set the Configuration ID.
      nylasScheduling.configurationId = urlParams.get("config_id");
    </script>
  </body>
</html>


```

```tsx [include_scripts-React (App.tsx)]

import { BrowserRouter, Route, Routes } from "react-router-dom";
import { NylasSchedulerEditor, NylasScheduling } from "@nylas/react";
import "./App.css";

function App() {
  // Get the configuration ID from the URL query string
  const urlParams = new URLSearchParams(window.location.search);
  const configId = urlParams.get("config_id") || "";

  return (


              <a href="/scheduler-editor" className="button">
                View Scheduler Editor
              </a>
              
            </div>
          }
        />

            </div>
          }
        />


  );
}
export default App;


```

```css [include_scripts-React (index.css)]

@import url("https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap");

html {
  height: 100%;
}

body {
  font-family: "Inter", sans-serif;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  height: 100%;
}


```

```css [include_scripts-React (App.css)]

#root {
  display: grid;
  place-items: center;
  height: 100%;
}

#root > div {
  display: grid;
  gap: 1rem;
}

.button {
  width: fit-content;
  padding-left: 1rem;
  padding-right: 1rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  font-weight: 700;
  color: rgb(59, 130, 246);
  text-decoration: inherit;
  border-width: 1px;
  border-radius: 0.25rem;
  border-color: rgb(59, 130, 246);
  border-style: solid;
}


```

## Start the dev server

Run a local server from your project root:

```bash
npx serve --listen <PORT>
```

```bash
npm run dev -- --port <PORT>
```

After you run the command, open your browser to `http://localhost:<PORT>/scheduler-editor` to see your Scheduler Editor.

## Create a scheduling page

Open `http://localhost:<PORT>/scheduler-editor` in your browser. Log in with your email provider, and the editor loads.

<img
  src="/docs/v3/getting-started/images/scheduler-editor-login.png"
  alt="A screenshot of the Scheduler Editor login page"
  title="Scheduler Editor Login Page"
  style="width:60%;"
/>

Click **Create new** to set up your first scheduling page.

<img
  src="/docs/v3/getting-started/images/scheduler-editor-list-configs.png"
  alt="A screenshot of the Scheduler Editor listing Scheduling Pages"
  title="Scheduling Pages in the Scheduler Editor"
  style="width:60%;"
/>

Enter a title, duration, and description. Set availability under **Availability** in the left nav, then click **Create**.

<img
  src="/docs/v3/getting-started/images/scheduler-editor-create-config.png"
  alt="A screenshot of the Scheduler Editor creating the Scheduling Page"
  title="Creating the Scheduling Page"
  style="width:60%;"
/>

The editor returns to the manager view showing all your scheduling pages.

<img
  src="/docs/v3/getting-started/images/scheduler-editor-preview-config.png"
  alt="A screenshot of the Scheduler Editor Preview"
  title="Scheduler Editor Preview"
  style="width:60%;"
/>

## Visit your scheduling page

Click **Preview** from the manager view, or visit `http://localhost:<PORT>/?config_id=<CONFIGURATION_ID>` directly. This is the page your users' invitees will see when booking time.

<img
  src="/docs/v3/getting-started/images/v3-scheduler-page.png"
  alt="A screen showing the Nylas scheduling component"
  title="Nylas scheduling component screen"
  style="width:60%;"
/>

## What's next

- **[Scheduler overview](/docs/v3/scheduler/)** -- availability rules, booking confirmations, and customization options
- **[Scheduler UI components](/docs/reference/ui/)** -- full reference for all component properties and events
- **[Scheduler & Notetaker integration](/docs/v3/scheduler/scheduler-notetaker-integration/)** -- automatically record meetings booked through Scheduler
- **[Authentication](/docs/v3/auth/)** -- set up OAuth so your users can connect their accounts
- **[Webhooks](/docs/v3/notifications/)** -- get notified when bookings are created or cancelled