---
title: "Declarative triggers"
url: "https://twistcal.com/docs/triggers"
description: "Turn any element into a calendar trigger with data-twistcal attributes. Auto-initializes on DOMContentLoaded, or bind manually for dynamic content."
---

Use your own buttons, links, or divs. Add `data-twistcal` to any element and it becomes a calendar trigger — no JS needed. Auto-initializes on `DOMContentLoaded`.

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

<!-- Google Calendar -->
<button data-twistcal
  data-twistcal-action="google"
  data-twistcal-title="Team Sync"
  data-twistcal-start="2026-01-15T10:00:00"
  data-twistcal-end="2026-01-15T11:00:00"
  data-twistcal-location="Room A">
  Add to Google
</button>

<!-- Outlook -->
<a href="#" data-twistcal
  data-twistcal-action="outlook"
  data-twistcal-title="Team Sync"
  data-twistcal-start="2026-01-15T10:00:00"
  data-twistcal-end="2026-01-15T11:00:00">
  Add to Outlook
</a>

<!-- Download .ics -->
<button data-twistcal
  data-twistcal-action="ics"
  data-twistcal-title="Team Sync"
  data-twistcal-start="2026-01-15T10:00:00"
  data-twistcal-end="2026-01-15T11:00:00">
  Download .ics
</button>
```

## Trigger attributes

| Attribute | Required | Description |
| --- | --- | --- |
| data-twistcal | yes | Marks the element as a trigger |
| data-twistcal-action | yes | google \| outlook \| yahoo \| ics |
| data-twistcal-title | yes | Event title |
| data-twistcal-start | yes | Start datetime |
| data-twistcal-end | yes | End datetime |
| data-twistcal-description | no | Event description |
| data-twistcal-location | no | Event location |
| data-twistcal-url | no | Event URL (.ics only) |
| data-twistcal-timezone | no | IANA timezone |

## Manual binding

### Auto-init a container

If you add triggers dynamically (e.g. after an AJAX load), call `autoInit` on the new container:

```
import { autoInit } from '@freshjuice/twistcal';

// After injecting HTML:
autoInit(document.getElementById('new-content'));
```

### Bind a single element

Or bind a single element with an explicit event object (skips attribute parsing):

```
import { bindTrigger } from '@freshjuice/twistcal';

const event = {
  title: 'Team Sync',
  start: '2026-01-15T10:00:00',
  end: '2026-01-15T11:00:00'
};
bindTrigger(document.getElementById('my-btn'), 'google', event);
```

## `twistcal:add` event

Each trigger click fires a `twistcal:add` `CustomEvent` on `document` with `{ action, event }` detail:

```
document.addEventListener('twistcal:add', (e) => {
  console.log('Added to:', e.detail.action, e.detail.event);
});
```

## Next

-   [API](/docs/api/) — `autoInit`, `bindTrigger`, and all exports
-   [Web component](/docs/web-component/) — the `<twist-cal>` element