Add to Calendar Button — Google/Outlook/ICS UI

Add to Calendar Button · Buttons · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Five calendar targets
Google, Outlook, Office 365, Yahoo links plus a universal .ics download covering Apple and every other client.
Single event object
Title, description, location, and times live in one EVENT object — update the event in one place.
Correct per-provider URL formats
buildUrl() handles each provider's distinct parameter names and date encoding, the part most implementations get wrong.
Standards-compliant .ics generation
Builds a valid VCALENDAR/VEVENT block, downloads it via a Blob, and revokes the object URL to avoid a leak.
Automatic UTC conversion
toUTC() converts local times to the calendar-required YYYYMMDDTHHMMSSZ format, preventing off-by-an-hour bugs.
Accessible menu
aria-haspopup, aria-expanded, role="menu"/"menuitem", and Escape/outside-click dismissal — a real menu, not a styled div.
New-tab links, in-place download
Web providers open in a new tab with noopener; the .ics choice downloads without leaving the page.
Animation-safe dropdown
Opacity and transform-only transitions keep the menu smooth across every framework export.

About this UI Snippet

Add to Calendar Button — Multi-Provider Event Links & .ics Download

Screenshot of the Add to Calendar Button snippet rendered live

"Add to calendar" is the single most effective way to stop people forgetting an event they signed up for — but doing it right means supporting every major calendar app, because you never know whether your attendee lives in Google Calendar, Outlook, or Apple Calendar. This snippet builds a complete add-to-calendar dropdown in plain HTML, CSS, and vanilla JavaScript: pre-filled event links for Google, Outlook, Office 365, and Yahoo, plus a downloadable .ics file that works with Apple Calendar and everything else.

One event object, every provider

All the event details — title, description, location, start, and end — live in a single EVENT object. Each menu choice builds the right URL or file from it, so updating the event is a one-place change. The web providers (Google, Outlook, Office 365, Yahoo) each have their own URL format with their own parameter names and date encoding, and buildUrl() handles those differences in one function: Google and Yahoo take UTC timestamps in their dates/st/et params, while Outlook and Office 365 take ISO datetimes in startdt/enddt. Getting these formats exactly right is the fiddly part most hand-rolled implementations get wrong, and it's done here for you.

The .ics file covers Apple and everything else

Apple Calendar has no "add event" URL scheme, so the universal answer is an .ics file — the iCalendar standard that every calendar app on every platform can import. downloadIcs() assembles a minimal valid VCALENDAR/VEVENT block with the event fields and the required UTC timestamps, wraps it in a Blob, and triggers a download via a temporary object URL (revoked immediately after to avoid a memory leak). Opening that file adds the event to whatever calendar the user's device defaults to — Apple Calendar on a Mac or iPhone, or any desktop client.

Timezone handling, done correctly

Calendar URLs and .ics files want UTC timestamps in the compact YYYYMMDDTHHMMSSZ format. toUTC() parses the local ISO start/end times and converts them through Date's toISOString(), stripping the separators and milliseconds. This means you author the event in plain local time and the conversion to the calendar-required format happens automatically — the most common source of "the event landed an hour off" bugs is skipping this conversion, which this snippet does for you.

A proper accessible dropdown

The trigger carries aria-haspopup="menu" and a toggled aria-expanded, the menu is role="menu" with role="menuitem" links, and it closes on an outside click or the Escape key — the standard menu pattern. The panel animates in with opacity and transform only (never height), so it stays smooth across every framework export, and web-provider links open in a new tab with noopener for safety while the .ics choice downloads in place.

Why support so many providers

It's tempting to ship only a Google Calendar link, but that abandons every Outlook and Apple user — a large share of any audience. Offering all the major web providers plus the universal .ics file means essentially everyone can add your event in one click, which directly improves attendance for webinars, sales, and appointments.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to compare calendar URL formats by hand — paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why toUTC strips separators and milliseconds from an ISO string, and why Google/Yahoo need UTC dates in their URL while Outlook and Office 365 take a different parameter format entirely. The same assistant is useful for optimizing it — asking whether the .ics Blob and object URL cleanup in downloadIcs is handling the revokeObjectURL timing correctly across browsers, or whether the menu's outside-click and Escape listeners could be consolidated. It's just as good for extending the button: ask it to add an RRULE line to the .ics output for recurring events, support multiple time zones with a VTIMEZONE block, or generate all five calendar links server-side from one event object shared with a confirmation email. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build an "add to calendar" dropdown button in plain HTML, CSS, and JavaScript — no libraries, supporting Google Calendar, Outlook, Office 365, Yahoo, and a downloadable .ics file, all generated from one shared event data object.

Requirements:
- A single JavaScript object holding the event's title, description, location, start time, and end time in local ISO format, used as the single source of truth for every calendar target.
- A URL-building function that returns a correctly formatted link for each web provider: Google Calendar's render endpoint expects UTC timestamps in a single "dates" parameter joined by a slash; Yahoo expects separate start/end UTC parameters; Outlook and Office 365 use their own deeplink compose endpoints with different parameter names (startdt/enddt) and do not require the UTC conversion. Get each provider's specific parameter names and encoding right, not a single generic format.
- A UTC conversion helper that takes a local ISO datetime string and produces the compact YYYYMMDDTHHMMSSZ format required by calendar URLs and the .ics standard, by converting through the Date object's ISO output and stripping dashes, colons, and milliseconds.
- An .ics file generator that assembles a valid VCALENDAR/VEVENT block (with UID, DTSTAMP, DTSTART, DTEND, SUMMARY, DESCRIPTION, LOCATION using CRLF line endings), wraps it in a Blob with a text/calendar MIME type, creates a temporary object URL, triggers a download via a hidden anchor click, and revokes the object URL immediately after to avoid a memory leak.
- A dropdown trigger button with aria-haspopup and aria-expanded, a menu with role="menu" and role="menuitem" links, closing on outside click, Escape key, and after a selection is made — animated with opacity/transform only, never height or display toggling mid-transition.
- Web-provider menu items should open their generated URL in a new tab with rel=noopener; the .ics item should trigger the file download without navigating away from the page.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSAn event card with an "Add to calendar" button renders. Click it to open the provider menu.
  2. 2
    Pick a providerChoose Google, Outlook, Office 365, or Yahoo — a pre-filled event opens in a new tab ready to save.
  3. 3
    Download the .icsChoose "Apple / .ics file" to download a universal calendar file that imports into Apple Calendar or any client.
  4. 4
    Edit the event detailsUpdate the EVENT object's title, description, location, start, and end — every provider link and the .ics rebuild from it.
  5. 5
    Check the timezoneAuthor start/end in local ISO time; toUTC() converts them to the UTC format calendars require automatically.
  6. 6
    Drop it into your pagePlace the button on an event, webinar, or booking confirmation page so attendees can save the date in one click.

Real-world uses

Common Use Cases

Webinar and event registration
Let registrants save the date the moment they sign up — pair with a countdown timer to the event.
Booking and appointment confirmations
Add the appointment to the customer's calendar right after booking, reducing no-shows.
Conference and meetup pages
Offer every session as a one-click calendar add across all major providers.
Email and ticket confirmations
Embed the same logic in a confirmation page (alongside an animated success checkmark) so attendees never lose the date.
Course and class schedules
Let students add recurring or one-off classes to their calendar of choice.
Learning calendar URL + .ics generation
A reference for multi-provider calendar links and standards-compliant .ics files — pair with a timezone converter for global events.

Got questions?

Frequently Asked Questions

Apple Calendar has no "add event" URL scheme, so a downloadable .ics file (the iCalendar standard) is the only way to support Apple users — and it works as a universal fallback for any calendar app on any platform. Offering web links for Google/Outlook/Yahoo plus the .ics means essentially every attendee can add your event in one click.

Author the start/end in local ISO time (e.g. 2026-07-12T18:30:00) and let toUTC() convert to the UTC YYYYMMDDTHHMMSSZ format calendars expect. For an event in a specific timezone that differs from the visitor's, include the timezone offset in the ISO string (…T18:30:00-04:00) so the conversion anchors to the right moment regardless of where the visitor is.

For the .ics file, add an RRULE line to the VEVENT (e.g. RRULE:FREQ=WEEKLY;COUNT=8 for eight weekly occurrences). The web-provider URLs have limited recurrence support, so for recurring events the .ics file is the most reliable option — most apps honor its RRULE on import.

In the .ics file, add a VALARM block inside the VEVENT (BEGIN:VALARM, ACTION:DISPLAY, TRIGGER:-PT30M, END:VALARM for a 30-minute-before reminder). Web-provider URLs generally don't accept reminder parameters, so reminders are an .ics-only feature on import.

In React, pass the event as a prop and compute the provider URLs with useMemo, generating the .ics in the click handler; in Vue, use a computed for the URLs; in Angular, use component methods. The URL-building and .ics-generation functions are framework-agnostic — only the dropdown open/close state moves into each framework's reactivity.