Skip to main content

Menu

Choose a theme and configure high-contrast mode. Preferences are saved in your browser only.

User Preferences

Theme

Pick a palette or follow your system preference.

High Contrast

Sharper text and borders. System follows your OS setting.

Web component

The twist-cal custom element — all attributes, calendar selection, JSON event data, all-day events, and the twistcal:add callback.

Drop <twist-cal> on the page. It renders a button with a dropdown menu. All styles live in a Shadow DOM root — no bleed in either direction.

<script defer src="https://cdn.jsdelivr.net/npm/@freshjuice/twistcal/dist/twistcal.min.js"></script>

<twist-cal
  title="Product Launch Webinar"
  start="2026-02-10T14:00:00"
  end="2026-02-10T15:30:00"
  location="Online"
  description="Join us for the launch of TwistCal v1.">
</twist-cal>

Attributes

Attribute Required Description
title yes Event title (calendar subject)
start yes Start datetime — any value new Date() understands
end yes End datetime
description no Event description (calendar body)
location no Event location
url no Event URL (included in .ics)
timezone no IANA timezone (e.g. Europe/Oslo). Naive start/end are interpreted as wall-clock in that zone, converted to UTC. DST-aware. Ignored if start/end already carry an offset. See Datetime.
label no Button text. Default: auto-detected from lang or Add to Calendar
lang no Language code. Auto-detected from <html lang> or navigator.language if omitted. See i18n.
variant no solid (default) or outline (white bg, dark border, dark text)
show-icons no true (default) or false — show/hide brand icons in dropdown
show-icon no true (default) or false — show/hide the calendar icon on the button
calendars no Comma-separated list of calendars to show, in order: google,outlook,yahoo,ics. Default: all four. ics and ical both work. Alias: services.
all-day no true or false (default). Date-only .ics and Google/Yahoo formats.
branding no true (default) or false — show/hide “Powered by TwistCal” link in dropdown

Calendar selection

Show only the calendars you want, in the order you want:

<!-- Google + Apple Calendar only -->
<twist-cal calendars="google,ics" title="..." start="..." end="...">
</twist-cal>

<!-- Single calendar — effectively a download button -->
<twist-cal calendars="ics" label="Download .ics" title="..." start="..." end="...">
</twist-cal>

Rich data via JSON

For long descriptions or structured data, pass the event as JSON inside the element:

<twist-cal label="Add to my calendar">
  <script type="application/json">
  {
    "title": "Quarterly Review — Q1 2026",
    "start": "2026-03-15T09:00:00",
    "end": "2026-03-15T10:00:00",
    "location": "Conference Room B, 4th Floor",
    "description": "Bring your Q1 metrics.\nDial-in: +1-555-0100, code 4521#",
    "url": "https://twistcal.com/demo"
  }
  </script>
</twist-cal>

JSON overrides matching attributes. Attributes not in the JSON are still read from the element.

All-day events

Set all-day="true" for date-only formats:

<twist-cal
  all-day="true"
  title="Company offsite"
  start="2026-04-20"
  end="2026-04-22">
</twist-cal>

Produces date-only .ics (VALUE:DATE) and Google/Yahoo all-day URLs.

twistcal:add callback

Each click dispatches a twistcal:add CustomEvent on the <twist-cal> element with { action, event } detail:

<twist-cal id="cal" title="..." start="..." end="..."></twist-cal>

<script>
  document.getElementById('cal').addEventListener('twistcal:add', (e) => {
    console.log('Added to:', e.detail.action, e.detail.event);
  });
</script>

action is google, outlook, yahoo, ics, or a custom calendar id. The event also fires on document for declarative triggers.

Next