<ote-events>

A single Web Component that renders upcoming events from any OTE JSON feed. No framework, no build step, no package to install — one <script> tag and one element. This page doubles as its documentation: every control below maps to one HTML attribute, and the snippet at the bottom always reflects exactly what you're seeing.

Try it

data source

The URL of an OTE feed.json document.

Optional maximum number of events to show. Default: no limit.

Optional. Cards use a built-in placeholder when an event has no image.

What happens when a visitor selects an event. Default: modal.

event-actions

Native actions. The default placement is the event detail view.

Adds a custom action with an icon that shows an alert for the selected event.

Optional CSS font-family for the widget.

Optional base font-size for the widget.

fields

Which optional pieces of each event to show. Ignored by the calendar layout.

Language of the widget's own UI text (loading/empty/error messages). "auto" follows the visitor's browser language.

Include events whose start date has already passed. Default: on.

Live preview

Copy-paste snippet

This is the exact markup for the configuration above.

The snippet uses a fixed widget version. Use /embed/latest/ only when you explicitly want automatic updates.

Versioning

Production embeds should use a fixed version URL so future widget changes do not alter existing sites without an explicit upgrade.

Recommended
https://tools.opentechevents.org/embed/v0.3.1/ote-events.js
Automatic updates
https://tools.opentechevents.org/embed/latest/ote-events.js
Legacy alias
https://tools.opentechevents.org/embed/ote-events.js

The widget follows semantic versioning: patch releases are compatible fixes, minor releases add compatible features, and major releases may require migration. Check the changelog before changing the version used by a production page.

Component versions and OTE Spec versions are independent. The component version tells you which widget bundle you are loading; the OTE Spec version tells you which event/feed shape that bundle is designed to consume.

Component OTE Spec Links
v0.3.1 v0.3.0 release script
v0.3.0 v0.3.0 release script
v0.2.0 v0.3.0 release script
v0.1.1 v0.3.0 release script
v0.1.0 v0.3.0 release script

Host app integration

Apps such as OTE Reader can pass already-filtered events in memory and keep subscriptions, folders, read state, and persistence outside the widget. Use sort="none" when the host app owns ordering.

await customElements.whenDefined("ote-events");

const widget = document.querySelector("ote-events");
widget.setAttribute("sort", "none");
widget.setAttribute("event-actions", "none");
widget.events = filteredEvents.map((event) => ({
  ...event,
  _feedUrl: event.feedUrl,
  _feedTitle: event.feedTitle,
}));

widget.eventActions = (context) => [{
  id: "save",
  label: saved.has(context.originalEvent.id) ? "Saved" : "Save",
  icon: saved.has(context.originalEvent.id) ? "bookmark" : "star",
  pressed: saved.has(context.originalEvent.id),
  placement: "preview",
  onClick(_previewEvent, actionContext) {
    saveEvent(actionContext.originalEvent.id, actionContext.feed?.url);
  },
}];

widget.eventClassName = (context) =>
  read.has(context.originalEvent.id) ? "is-read" : "is-unread";
widget.eventBadges = (context) =>
  context.originalEvent.cfpOpen ? [{ label: "CFP", icon: "plus" }] : [];
API Use
el.events Render an in-memory array of OTE events without fetching.
sort="none" Keep the host application's ordering instead of widget date sorting.
empty-message Customize the empty state shown after host-side filters.
eventActions(context) Return per-event actions with dynamic label, icon, placement, and pressed state.
eventClassName(context) Add host-owned state classes such as read, unread, saved, or canceled.
eventBadges(context) Add host-owned badges such as folder, collection, CFP, or saved state.

The ote-event-action event includes action, previewEvent, originalEvent, index, feed, and source. The widget renders only; it does not store favorites, folders, read state, or filters.

Using AI agents?

The embed package includes an agent-facing guide with the typed eventActions contract, placement rules, and the tests that act as living documentation.