← Back to Docs

Events and Callbacks

The widget dispatches custom DOM events on document. Listen for analytics, moderation alerts, or custom UI logic.

Listening to Events

document.addEventListener('threadline:comment:posted', (e) => {
  const detail = (e as CustomEvent).detail;
  console.log('New comment:', detail.commentId, 'by', detail.authorName);

  // Push to your analytics
  if (typeof gtag === 'function') {
    gtag('event', 'comment_posted', { page_id: detail.pageId });
  }
});

document.addEventListener('threadline:error', (e) => {
  const { code, message } = (e as CustomEvent).detail;
  console.error(`Threadline error [${code}]: ${message}`);
});

Event Reference

threadline:ready
Payload: { widgetVersion: string }

Fired when the widget has finished loading and is ready to interact with.

threadline:comment:posted
Payload: { commentId: string, authorName: string, pageId: string }

Fired after a comment is successfully submitted. Does not fire for blocked comments.

threadline:comment:deleted
Payload: { commentId: string, pageId: string }

Fired when a comment is deleted by the author or a moderator.

threadline:comment:flagged
Payload: { commentId: string, reason: string, pageId: string }

Fired when a visitor flags a comment. Reason: "spam", "offensive", or "other".

threadline:error
Payload: { code: string, message: string }

Fired on error. Codes: "SITE_NOT_FOUND", "RATE_LIMITED", "NETWORK_ERROR", "AUTH_FAILED".

Example use cases

Common patterns using the DOM events above. For live updates inside the open widget, socket events also exist (new_comment, reaction_updated, and related) - those power real-time UI and are separate from the document CustomEvents listed here.

Analytics on comment posted

document.addEventListener('threadline:comment:posted', (e) => {
  const { commentId, authorName, pageId } = (e as CustomEvent).detail;
  analytics.track('Comment Posted', { commentId, authorName, pageId });
});

Toast on error

document.addEventListener('threadline:error', (e) => {
  const { code, message } = (e as CustomEvent).detail;
  showToast(`${code}: ${message}`, { type: 'error' });
});

Open login on AUTH_FAILED

document.addEventListener('threadline:error', (e) => {
  const { code } = (e as CustomEvent).detail;
  if (code === 'AUTH_FAILED') {
    window.location.href = '/login?next=' + encodeURIComponent(location.pathname);
  }
});

Sync comment count to page header

const el = document.querySelector('#comment-count');
let count = Number(el?.textContent || 0);

document.addEventListener('threadline:comment:posted', () => {
  count += 1;
  if (el) el.textContent = String(count);
});

document.addEventListener('threadline:comment:deleted', () => {
  count = Math.max(0, count - 1);
  if (el) el.textContent = String(count);
});