Skip to content

Headless client

init() from @rollout/js gives you the same data the widget uses, without any UI.

import { init } from '@rollout/js'
const rollout = init({
projectKey: 'pk_live_…',
apiUrl: 'https://api.rollout.so',
token: () => fetch('/api/rollout-token').then((r) => r.text()),
})
const unsubscribe = rollout.subscribe(({ status, announcements, unreadCount, hasMore, error }) => {
// render your own UI
})
Option Default Description
projectKey Required. Publishable key (pk_live_…).
apiUrl Required. Base URL of the rollout API.
token Signed identity token, or a function returning one. Called once, then again after a 401.
user Unverified identity { id, org?, createdAt?, attrs? }. Ignored when token is set.
refresh.onLoad true Load the feed immediately.
refresh.onFocus true Reload when the tab becomes visible again.
refresh.intervalMs 0 Poll every n milliseconds; 0 disables polling.
pageSize 20 Announcements per page (at most 50).
fetch A custom fetch, e.g. for tests or server rendering.

You must pass token or user; see Identity.

subscribe(listener) calls your listener right away and after every change. It returns a function that unsubscribes. getState() returns the current state.

Field Description
status idle, loading, ready or error.
announcements The loaded announcements, newest first.
unreadCount Unread announcements for this user, across all pages.
hasMore Older announcements can be loaded with loadMore().
error A RolloutError (status, code, message) when loading failed.

Each announcement has:

Field Description
id Announcement id (ann_…).
title Title.
publishedAt ISO timestamp.
image Lead image or null: url (up to 1600px wide), thumbnailUrl (up to 320px), alt, width, height.
tags Snippet categories in order: new, improved, fixed.
html Rendered body (hero, intro, snippets), without the title.
markdown The same body as Markdown, or null for old announcements.
text Plain text.
read Whether this user has read it.
Method Description
refresh() Reloads the feed, keeping pages loaded with loadMore().
loadMore() Appends the next page of older announcements.
markRead(id) Marks one announcement read. Updates the state right away.
markAllRead() Marks everything read. Updates the state right away.
destroy() Stops polling and removes listeners.

markRead and markAllRead update the state before the request finishes; the next refresh reconciles it if the request failed.

Code blocks in html arrive syntax-highlighted, as <pre><code class="language-ts hljs"> with highlight.js token classes (hljs-keyword, hljs-string, …). Add any highlight.js theme stylesheet to colour them; without one they render as plain code.

Failed requests reject with RolloutError: status (HTTP status, 0 for network errors), code (for example invalid_token, origin_not_allowed) and message. With a token function, a 401 fetches a fresh token and retries once.

Pass the client to the widget’s client property to share one connection, for example to show your own unread badge next to the widget. See Widget → Your own trigger.