Beyond APIs: Designing elegant, smart Web Components

11 min read

Everybody knows about APIs. They abstract complex functionality into a well-defined interface, providing essential backend infrastructure and powerful application functionality. 

However, at Nylas, we found one big challenge: when our customers build software, providing them with an API is only one part of the solution. Our customers build our APIs into their software, which also involves UI work.

Navigating the complexity of API integration with smart Web Components

Frontend development expands the scope of integration work, requiring more design and development resources, which can become a significant blocker to implementing the features folks really want. Roadmap time is scarce, and the difference between a sprint for a single engineer and a couple of sprints involving product designers and front-end developers is a big one.

At Nylas, a question emerged: How could we make it quicker and easier for our customers to profit from the value our APIs brought? This question inspired the first version of Nylas Scheduler, which launched in 2019. It was our first prepackaged, full-stack workflow that allowed you to create scheduling UIs quickly, powered by our flagship APIs out-of-the-box.

Lessons learned from building Scheduler v1

Building Scheduler broke new ground. There are many best practices for building easy-to-use APIs, but there aren’t many examples of successful frontend+backend solutions. However, we did get some things right. For example, we saw significant product adoption and growth improvements by streamlining the front-end build. While the first version had some flaws, its ease of use made it one of our fastest-growing products.

After thousands of integrations, exposed to millions of end-users, here were some of the themes that began emerging from Scheduler v1:

  1. Scheduler v1 had Nylas-hosted scheduling pages, and while iFraming certainly served its purpose at the time, it also showed how limiting and jarring it could be to have to cater to a separate web page.
  2. Booking flows were too rigid; this went hand-in-hand with the above points. How could customers use browser events, inject logic, or adapt their UIs intelligently?
  3. We could address many customer requests without needing backend changes by making small tweaks to our UI code. It became clear that giving customers access to the code would be a win for everyone, allowing them to handle styling changes directly and more efficiently. 
  4. Lastly, the stiffness of the components encouraged hacky, bootstrapped workarounds that confused support teams and created unexpected behaviors.

Initially built as a POC app on Nylas API v2, the original Nylas Scheduler evolved incrementally, much like a customer-built app, leading to significant architectural limitations. While the first version was easy to use, it lacked the flexibility for users to extend and customize the product to fit their specific needs. Developers don’t want to feel constrained, and abstraction shouldn’t come at the cost of hitting a wall when the out-of-the-box solution isn’t quite right.

Earlier this year, we introduced Nylas API v3. While rolling out API v3, we decided the time was ripe to reimagine the next generation of the Nylas Scheduler. Leveraging the improvements from API v3, we were able to rearchitect it from the ground up to address the major learnings from the first version.

Solving customizability with smart Web Components: 4 things we did differently in Scheduler v3

1. Web components for composability

iFrames are notorious for causing integration and styling problems due to their isolation from the parent page. They slow down load times, complicate communication between the parent and the child, and can create security vulnerabilities.

To address these issues, we moved from the old iFrame-based model to Web Components, which we built using Stencil.js. This made the Scheduler more modular, customizable, and independent of any specific frontend framework.

Web Components provide a standardized way to create reusable and encapsulated HTML elements that can be fully controlled with the browser’s native API.

Key benefits:

  • Encapsulation: Shadow DOM isolates styles and markup, preventing interference with the rest of the page.
  • Reusability: Component tags like <input-component> can be reused across different pages or applications.
  • Framework-agnostic: They work natively in browsers and can be used with or without frameworks like React or Vue.

For more information on Web Components and their history, check out this resource: MDN Web Components.

Benefits of building Web Components using Stencil.js

Stencil.js makes building Web Components easier and more efficient by giving developers a familiar, framework-like experience. It allows you to create reusable, native-feeling components using TypeScript and JSX while still outputting pure Web Components. Stencil also has built-in optimizations and automatic documentation generation, making it a great choice for building modern, customizable elements with minimal effort.

2. Customize workflow steps with overrides

Our goal when designing the new Nylas Scheduler v3 was to provide a simple, out-of-the-box workflow that is easy to integrate into any web application while being flexible enough to work with the most complicated customer workflows.  Each stage of the scheduling workflow provided by our components is fully customizable with code, ensuring that our customers can implement their specific business logic without adding unnecessary complexity to their own applications.

Scheduling: Default workflow

The default workflow follows a straightforward “happy path” where a user selects a date, picks a timeslot, confirms the booking, and receives a confirmation email. This flow is designed to be simple and effective for most use cases.

Let’s take a look at the default scheduling flow:

Scheduling workflow_Smart Web Components
  1. Select date
    • Event triggered: dateSelected
    • Action: The user selects a date from the available calendar options.
  2. Choose Time-slot
    • Event triggered: timeslotSelected
    • Action: After selecting a date, the user selects an available time-slot for their booking.
  3. Time-slot confirmation
    • Event triggered: timeslotConfirmed
    • Action: Once a time-slot is chosen, the system confirms the time-slot, and the user is presented with the booking form to complete their details.
  4. User enters details (name, email, etc.)
    • Event triggered: nameChanged and emailChanged
    • Action: The user inputs required booking details like name and email.
  5. User clicks “Book Now”
    • Event triggered: detailsConfirmed
    • Action: The user confirms all details and clicks the “Book Now” button.
  6. API request to Book Event
    • Action: The system sends a booking request to the backend API, making sure the appointment is reserved.
  7. Booking confirmed
    • Action: After a successful booking request (response code 200), the user is shown the Booking Confirmed page.

Custom flow example: Confirming user login

Developers can override key events to customize the workflow. For example, they may want to check if a user is logged in before confirming their booking:

custom scheduling flow_smart Web Components

The above diagram demonstrates a custom scheduling flow where we introduce an additional step to confirm the user is logged in before booking a time-slot. This is done by overriding the default workflow (i.e. when the user confirms the time slot).

Timeslot confirmation override: 

  • Instead of directly proceeding after timeslotConfirmed, the workflow intercepts the confirmation event and checks if the user is logged in.
  • If the user is not logged in, they are redirected to a login page.
const [storedtimeslot, setTimeslot] = useState({})
<NylasScheduling
  eventOverrides={{
    timeslotConfirmed: async (event, connector) => {
      const timeslot = event.detail;
       if (!userLoggedIn) {
         // Interrupt default flow
         event.preventDefault();
         // Store timeslot
         setTimeslot(timeslot);
         redirectUserToLogin();
       }
     }
  }}
/>
  • Once logged in, the user is redirected back to the scheduling page, updating the defaultSchedulerState so that the user can resume the flow from where it was interrupted.
<NylasScheduling
  defaultSchedulerState={{
    selectedDate: new Date(storedTimeslot.start_time),
    selectedTimeslot: storedTimeslot,
    showBookingForm: true
  }}
/>

Why overrides matter

Event overrides are an essential feature of the Nylas Scheduling components that allow customers to alter the behavior of key events in the default scheduling workflow. Our components expose all meaningful workflow events as JS events that can have their behavior overwritten by developers. This flexibility ensures that customers can customize as much or as little of the scheduling workflow to fit their specific use case.  

Examples include:

  • Authentication: Requiring users to log in before booking (as shown in the custom flow).
  • Custom business logic: Triggering external APIs or services when certain events occur (e.g., notifying a CRM system when a booking is made, interrupting the flow to confirm payment before the booking is made). 

How to implement overrides

Overrides in the Nylas Scheduler are simple to implement using JavaScript. Here are three key points for developers to consider:

  1. Choose the event to override: Identify the event in the default flow where custom logic should be introduced (e.g., timeslotConfirmed, detailsConfirmed).
  2. Write custom logic: Use JavaScript to define what should happen at that point (e.g., redirect to a login page, validate input, trigger an API call).
  3. Prevent default behavior: If the default behavior should be skipped, use event.preventDefault() to stop the normal flow.

By using event overrides, developers can build highly customized scheduling workflows that integrate seamlessly into their existing systems without rewriting the core logic of the scheduler.

For more information on custom event handlers, check out our documentation

3. Styling

When offering customizability in terms of styling with HTML and CSS, it’s crucial to strike the right balance between flexibility and simplicity for implementers. Based on our experience with Scheduling components, here are some key takeaways to ensure that implementers don’t inadvertently cause issues with their customization:

1. Offer multiple levels of customization

Simple customization: Make it easy for customers to quickly update colors, fonts, and spacing without needing to delve into complex CSS or internal component structures. The themeConfig prop is an excellent example of this. It allows users to apply a few simple variables for fast changes, like primary colors or error styles.

Example:

<NylasScheduling
  themeConfig={{
    "--nylas-primary": "#2563eb",
    "--nylas-error": "#cc4841"
  }}
/>

Advanced customization: For users who need more granular control, provide mechanisms like CSS Shadow Parts. This allows them to fine-tune specific parts of the component without having to override everything. It keeps the component structure safe while allowing deep customizations when necessary.

Example:

nylas-scheduling::part(ndp__date--selected) {
  color: green;
}

2. Provide clear guidelines and examples

Providing comprehensive documentation and examples is essential to help implementers fully understand how to customize components effectively and follow best practices.

  • Detailed shadow parts documentation: Clearly document each component’s shadow parts, offering a complete list of customizable elements. Expose these shadow parts at the parent component level, allowing users to easily apply styles without needing to dive deep into individual components. This approach ensures that customization is efficient and consistent across the application.
  • Consistent naming of shadow parts (BEM-inspired): Use a shortened prefix to indicate the component (e.g., `ndp__date–selected` for the selected date button in nylas-date-picker). This structure follows the Block-Element-Modifier (BEM) convention, making identifying and targeting specific elements within a component easier. 

3. Provide sensible defaults

Ensure that the Scheduler comes with well-designed, sensible default styles that look polished and professional right out of the box. This reduces the need for users to extensively customize every element. Most styling needs should be addressed by simply adjusting the themeConfig, allowing users to make minor tweaks without diving into advanced customization. Defaults should be robust enough to stand independently, with deeper customization as an optional enhancement, not a requirement. This approach simplifies the implementation process and ensures that the component works well for a wide range of users with minimal effort.

4. Maintainability

To ensure our Scheduler is both reliable and adaptable, we’ve focused on several key areas that make it easier to maintain and scale:

  • Modular components: We break the Scheduler into small, reusable Web Components. This keeps everything focused and easy to manage. If we need to fix a bug or add a feature, we can do it without affecting the whole system, making updates smoother.
  • Clear documentation: Thanks to Stencil.js, we automatically generate detailed documentation so our team and customers can quickly understand how everything works and how to implement it.
  • Scalable customizations with event overrides: Instead of hard-coding custom features, we let you define your own logic with event overrides. This keeps the core system clean while giving you the flexibility to add your own customizations without creating extra maintenance headaches.
  • Easy versioning: We strive to add new features or changes in a way that won’t break what’s already in place so you can confidently keep your implementation up to date.

Enhance developer productivity with accessible tools and smart Web Components

At Nylas, we believe that the power of computing should be accessible to everyone. That’s why we focus on creating building blocks that are easy to use and flexible enough to adapt to your unique needs. With the newly imagined Scheduler, we’ve taken significant steps to ensure our tools empower you without getting in your way when your use case goes beyond the ordinary.

Ready to explore what the Scheduler can do for you? Dive into our product documentation and getting started guide to learn more and start building for free today.

Related resources

Introducing the new Nylas Scheduler: Experience the future of in-app scheduling

Get access to modular, customizable, and native components for bespoke scheduling in your app.

Group scheduling — control your events participation with Ruby

Learn how to control your events participation by creating attendance limits using group scheduling with Ruby

How to build a scheduling application using Python and Flask

Do you want to create your own custom scheduling application? Here’s an extensive guide for you including Virtual Calendars