Skip to main content
Mount one WebsiteUpdates beside your application. It needs no provider, API key, Tailwind setup or Tauri dependencies. Import the package stylesheet once. In frameworks with Server Components, mount it inside a client component (for example, a module with 'use client'). Its package can be imported during SSR without accessing browser state; notification work begins after the client mounts.
Install the SDK with pnpm add @feedbackloop/react. WebsiteUpdates is introduced in 0.2.0; verify the registry version before using unreleased source. The ReleaseNotes component remains available when you want the complete embedded release history instead.

Publish a deployment manifest

Serve /version.json from the same website by default. You may choose another URL with manifestUrl. Publish the manifest after the matching application assets are available and configure your hosting provider to return Cache-Control: no-store for it.
Build IDs are opaque strings. Any deployed ID different from the one compiled into the running JavaScript offers Refresh, including a rollback. Do not change the current running build value when the fetched manifest changes. The fetched releaseVersion is optional and never selects the after-refresh notes. The SDK checks on mount, every five minutes while visible, on focus or return to a visible tab with a sixty-second throttle, and immediately when the browser returns online. It requests the manifest without cookies or cache. Only the newest deployment candidate is retained. Not now defers that same candidate in this tab; another deployment can prompt again.

Save safely before refresh

beforeRefresh may return void or a promise. The SDK waits for it before reloading. Use it to flush autosaves, editor drafts or other pending consumer work. A rejection keeps the current document running and offers a retry. Refresh runs once at a time, and a pending callback cannot reload after the component unmounts or switches project/build/manifest identity.

Show what changed after loading

The release preview uses currentBuild.releaseVersion, which describes the JavaScript already loaded. On the first visit, the SDK records that version silently. A later strictly greater semantic version requests its exact fresh published release from Feedback Loop. A missing release never falls back to the latest note, and an offline cache does not open this automatic panel. Publish the note with the matching App version; missing or unavailable notes retry on future lifecycle checks. The acknowledgement is stored only after the matching preview renders. It keeps that panel open until Dismiss what’s new or Read release notes is selected. The article is a real link that opens in a new tab. Preview images preserve their original proportions; unavailable images leave the title, excerpt and article link usable. If a new deployment is discovered while the panel is open, its refresh prompt waits until the panel is dismissed. Preferences are isolated by project and resolved manifest URL. Another tab’s newer acknowledgement is respected, and stale tabs cannot deliberately replace it with an older version. Storage denial suppresses automatic release previews; deployment prompts continue to work. Same-version builds and semantic downgrades stay quiet for release previews, while different build IDs can still offer a refresh.

WebsiteUpdates props

All presentation CSS is scoped under .fl-website-updates, inherits your font and semantic palette variables, and keeps text at text-sm or larger. The notification is nonmodal and does not move keyboard focus. Icon motion uses upstream Animate UI defaults and is disabled for reduced motion.

Embedded release reader

Use ReleaseNotes when you want a full embedded timeline or exact-version document in an existing route, page or dialog. Its reader contract remains compatible with 0.1.1, alongside the new website notifications. Find your public project ID in Release notes → Add to app and publish a note before testing.

Install and render

Install the package:
Import the reader and its scoped stylesheet:
Import the stylesheet once in your application’s client entry point. Render WhatsNew from your existing route, dialog or page. Keep this browser component in client-rendered code when your framework separates server and client components.

Props

The embedded reader has only these three public props. There are no custom fetch, endpoint, authentication or rendered-note callback props.

History and exact versions

Omit version to browse the newest publications and load earlier pages. Pass version="1.2.3" to start with that exact app release. An unavailable exact version offers the full history rather than substituting another version. Set theme to system, light or dark; system follows the operating system. Full history includes unversioned updates and loads ten notes per page. It preserves publication order, including earlier publication dates edited by an owner; it does not sort by semantic version. Unversioned notes use their titles. All versions returns from an exact release to history. A project can publish only one active note for each full version, including its build suffix. Markdown uses the SDK’s restricted renderer for headings, lists, tables, code, task lists, links and images. Managed images resolve through the release-specific image endpoint; HTTP(S) links open safely. No owner-only inventory or private image keys are exposed.

Theme and layout

The precompiled stylesheet is scoped to .fl-release-notes. It does not require your application to install Tailwind or import private Feedback Loop CSS. Existing application variables --background, --foreground, --muted-foreground, --border, --accent and --ring take precedence over the fallback palette selected by theme. Supply your own app theme through those variables; setting theme="dark" does not override a light value you already define. Place the reader in a container with the width you want. It adapts to narrow layouts and scrolls long Markdown without requiring an app-wide layout change. If your app defines a CSP, allow https://feedbackloop.page in connect-src. In img-src, allow the API origin and the actual redirected storage/CDN or external Markdown image origins. An API-origin-only image policy can block the final signed-image redirect.

Loading, errors and saved copies

The reader owns loading, empty history, missing exact release, unavailable project, and retry controls. An unavailable exact version offers full history instead of substituting another version. A missing/deleted project is an authoritative unavailable response and clears affected cached content. A network failure may show a clearly labelled saved copy. The best-effort browser cache is isolated by project and exact version, bounded to five recent views and one megabyte total. It stores Markdown, not image bytes, and tolerates denied storage. A missing exact release never shows another version’s cached note. An open saved-copy or failed view retries on the browser’s online event without polling. A saved copy is not evidence that a note is still published. When testing, distinguish a live response from the reader’s offline label; images may be unavailable while offline.

Verify your integration

Check history and a known exact version, All versions, pagination, keyboard navigation, narrow layout, both palettes and live system changes. Test offline/reconnect and an unavailable project. Publishing a note does not distribute an app binary. For native windows and update controls, use the separate Tauri guide. For your own renderer, use the HTTP API.