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 @makershq/react@0.3.1. Use WebsiteUpdates for deployment notifications and ReleaseNotes for the complete embedded release history.

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 Maker’s HQ. 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 reader also accepts optional onReleaseRendered and openExternal callbacks. See Custom UI for callback behavior and custom reader hooks.

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 Maker’s HQ 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://makershq.dev 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.

Custom UI

SDK 0.3.0 adds hooks and rendering components for custom UI. Use the supplied components for a ready-made integration, or combine the hooks with your own layout. useReleaseNotesReader({ projectId, version? }) supplies page, loading, loadingMore, cached, error, unavailable, loadMore() and retry(). Version normalization, cancellation, pagination, unavailable-cache invalidation and offline recovery use the same data owner as ReleaseNotes. Your app owns exact-version/history navigation by changing version; omit it for history.
ReleaseMarkdown accepts projectId, release and optional openExternal(url). It retains restricted HTML, HTTP(S) links and release-scoped images. releaseImageUrl(projectId, releaseId, source) returns a safe external/managed URL or undefined for a rejected source when your app supplies its own renderer. ReleaseMarkdownProps and ReleaseNotesReaderOptions are exported beside the existing public data types. Fully custom layout and styling belong to your app; the default stylesheet remains optional for those custom surfaces. The built-in ReleaseNotes also accepts onReleaseRendered(release, { cached }) and openExternal(url) from SDK 0.3.0. Render confirmation reports an exact note mounted by the reader; it does not itself acknowledge any website/native preference. A saved copy is identified by cached: true. Use the native request’s safe callback when connecting an after-update reader.

Custom website notifications

Use one useWebsiteUpdates({ projectId, currentBuild, manifestUrl?, beforeRefresh? }) owner instead of mounting WebsiteUpdates alongside another owner. The hook returns candidate, displayedRelease, refreshing, error and no-argument refresh(), dismissCandidate(), dismissRelease() and onReleaseRendered() callbacks. Keep the loaded build compiled into the bundle, preserve the save barrier, and show a loaded-release preview before an available deployment prompt.
Call onReleaseRendered() after the preview commits, rather than when a request completes or a notice is dismissed. The hook keeps acknowledgment monotonic and fresh-only. Callbacks remain bound to the displayed project/build/release, including replacement, dismissal and rollback. A save barrier cannot reload a replacement deployment. The SDK retains its existing polling and lifecycle triggers; custom UI adds no second checker.