DEV Community

Cristina Rodriguez
Cristina Rodriguez

Posted on

Building an "Add to Calendar" Button: A Story of Turning a Small Project into a Big Win

You’ve just graduated from your coding bootcamp and feel ready to tackle real-world projects—but the job market feels like hell on earth. You start wondering how to keep your momentum and grow your skills. Then, a couple of friends reach out to you with an exciting request: they’re launching a boutique business and need your help building a simple website for their open house event. They don’t have the budget for platforms like Eventbrite or Luma, but they believe in your talent. It's a win-win—you get to showcase your skills, and they get a website.

“Yes!” you say. Building a landing page with HTML, CSS, and some React sounds like a fun challenge—the perfect way to demonstrate your growing Next.js expertise. The structure comes together beautifully: the event details look sleek, the form styling is modern, and the layout is responsive. Everything feels great.
Until you get to that feature: the “Add to Calendar” button.

Suddenly, you’re stuck. How do you dynamically connect the event with different calendar services like Google Calendar, Outlook, and Yahoo? Surely there must be a way to pre-fill these calendar forms without forcing users to copy and paste event details. You pause, realizing this isn’t just a small feature—this button could be a seamless, professional touch that enhances the entire user experience. It’s time to level up

The Mission: A Seamless Calendar Integration

You roll up your sleeves, determined to make it work. Here's how you solved it, step by step:

Step 1: Cloning the Project and Setting Up
This tutorial assumes that you already have a landing page set up locally using Next.js in JavaScript. If you don't have an initial project, feel free to use the code from this repository to get started.

You install the dependencies and start the development server:

npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

Now, with the project running locally, you’re ready to start building the feature.

Step 2: Understanding How Calendar Links Work

Before diving into any complex solutions, you investigate how different calendar services handle event links. You notice that services like Google Calendar use URL parameters to prefill event details. For example, a Google Calendar link looks something like this:

https://calendar.google.com/calendar/render?action=TEMPLATE&text=Treasures+4+Femme+Open+House&details=Join+us+for+an+evening+of+trendy+apparel,+gifts,+and+fun!&location=Seattle,+WA&dates=20250222T170000Z/20250222T190000Z
Enter fullscreen mode Exit fullscreen mode

You realize that by passing parameters like text, details, location, and dates, you can programmatically create links that pre-fill these fields for the users.

Step 3: A Smarter Approach with calendar-link

After some research, you find a npm package called calendar-link that simplifies generating these URLs for various calendar platforms. You install it:

npm install calendar-link
Enter fullscreen mode Exit fullscreen mode

Then, in your Next.js component, you import the necessary functions:

import { google, outlook, yahoo, ics } from 'calendar-link';
Enter fullscreen mode Exit fullscreen mode

Step 4: Defining the Event Details

You create an event object that holds all the necessary information:

const event = {
  title: 'Treasures 4 Femme Open House',
  description: 'Join us for an evening of trendy apparel, gifts, and fun!',
  location: 'Seattle, WA',
  start: '2025-02-22T17:00:00-08:00',
  end: '2025-02-22T19:00:00-08:00',
};
Enter fullscreen mode Exit fullscreen mode

This event object contains the title, description, location, start time, and end time of the open house.

Step 5: Creating Dynamic Calendar Links

Next, you dynamically generate calendar links for each service:

<ul>
  <li><a href={google(event)} target="_blank" rel="noopener noreferrer">Google</a></li>
  <li><a href={outlook(event)} target="_blank" rel="noopener noreferrer">Outlook</a></li>
  <li><a href={yahoo(event)} target="_blank" rel="noopener noreferrer">Yahoo</a></li>
  <li><a href={ics(event)} download="event.ics">Other Calendar (ICS)</a></li>
</ul>
Enter fullscreen mode Exit fullscreen mode

These links allow users to add the event to their preferred calendar with a single click.

Step 6: Adding the Dropdown Menu

To make the interface clean, you wrap the links inside a dropdown that appears when users click a button:

import { useState } from 'react';

const [isOpen, setIsOpen] = useState(false);

<div className="relative">
  <button onClick={() => setIsOpen(!isOpen)} className="inline-block px-4 py-3 border border-zinc-500 shadow-lg rounded">
    Add to your Calendar!
  </button>
  {isOpen && (
    <ul className="absolute top-full left-0 w-full bg-white shadow-lg rounded py-3">
      <li><a href={google(event)} target="_blank">Google</a></li>
      <li><a href={outlook(event)} target="_blank">Outlook</a></li>
      <li><a href={yahoo(event)} target="_blank">Yahoo</a></li>
      <li><a href={ics(event)} download="event.ics">Other Calendar</a></li>
    </ul>
  )}
</div>
Enter fullscreen mode Exit fullscreen mode

Step 7: Styling the Menu with Tailwind CSS

Using Tailwind CSS, you add transitions and positioning to ensure the dropdown appears smoothly:

<ul className="absolute top-full left-0 w-full bg-white shadow-lg rounded py-3 transition-all duration-300 ease-in-out transform origin-top z-10">
Enter fullscreen mode Exit fullscreen mode

This makes the dropdown feel polished with a subtle fade-in effect.

Step 8: Closing the Dropdown on Outside Click

You realize that users might want to close the dropdown by clicking anywhere outside the menu. To achieve this, you add a useEffect hook that listens for outside clicks:

import { useRef, useEffect } from 'react';

const menuRef = useRef(null);

useEffect(() => {
  const handleClickOutside = (event) => {
    if (menuRef.current && !menuRef.current.contains(event.target)) {
      setIsOpen(false);
    }
  };

  document.addEventListener('mousedown', handleClickOutside);
  return () => document.removeEventListener('mousedown', handleClickOutside);
}, [menuRef]);

<div ref={menuRef} className="relative">
  {/* Button and Links */}
</div>
Enter fullscreen mode Exit fullscreen mode

This ensures the dropdown closes when users interact with other parts of the page.

Step 9: Adding Icons for a Professional Touch

To improve the user experience, you decide to add icons for each calendar service. You use SVG icons and display them alongside the text:

<li className="flex items-center gap-2">
  <img src="/google-icon.svg" alt="Google" className="w-4 h-4" />
  <a href={google(event)} target="_blank">Google</a>
</li>
Enter fullscreen mode Exit fullscreen mode

The Moment of Triumph

You deploy the updated landing page and invite your friends to check it out. They’re thrilled with the result. The dropdown menu, icons, and seamless calendar integration make the site feel polished and professional. But more than that, you’ve proven ready to take on unexpected challenges and learn.

The 4 Femme open house is a success; you walk away with a stronger portfolio piece and renewed confidence. You turned a simple feature into an opportunity to grow, and you’re already thinking about how to apply this experience to your next project.

Screenshot landing page for event with a Add to Calendar button

Top comments (0)