@tour-kit/announcements
v3.0.0
Published
In-app product announcements for React — modal, toast, banner, slideout, spotlight with frequency rules and changelog support.
Maintainers
Readme
@tour-kit/announcements
In-app product announcements for React — modal, toast, banner, slideout, spotlight with frequency rules and changelog support.
Drop-in product announcements, what's-new modals, release notes, and in-app notifications for React. Five UI variants — Modal, Slideout, Banner, Toast, Spotlight — with a priority queue, frequency rules, audience targeting, and optional schedule gating.
Pro tier — requires a license key. See Licensing.
Alternative to: Headway, Beamer, Announcekit, Pendo announcements, LaunchNotes, in-app changelog widgets.
Features
- 5 display variants — Modal, Slideout, Banner, Toast, Spotlight
- Priority queue —
critical>high>normal>low - Stack behaviors —
queue,replace, orstackup tomaxConcurrent - Frequency rules —
once,session,always,times: N,interval: days - Audience targeting — show announcements only to matching user segments
- Optional schedule — pair with
@tour-kit/schedulingfor time-windowed releases - Headless variants with render props for full UI control
- Persistence via custom
AnnouncementStorageAdapter(localStorage by default) - TypeScript-first, supports React 18 & 19
Installation
npm install @tour-kit/announcements @tour-kit/license
# or
pnpm add @tour-kit/announcements @tour-kit/licenseQuick Start
import { LicenseProvider } from '@tour-kit/license'
import { AnnouncementsProvider, AnnouncementModal } from '@tour-kit/announcements'
function App() {
return (
<LicenseProvider licenseKey={process.env.NEXT_PUBLIC_TOURKIT_LICENSE!}>
<AnnouncementsProvider
announcements={[
{
id: 'welcome',
variant: 'modal',
title: 'Welcome to v2!',
description: "Here's what's new.",
frequency: 'once',
},
]}
>
<AnnouncementModal id="welcome" />
<YourApp />
</AnnouncementsProvider>
</LicenseProvider>
)
}Registered announcements that pass their eligibility checks auto-show on mount. Set autoShow: false on a config to trigger imperatively via show(id).
i18n & interpolation
All user-facing strings in @tour-kit/announcements accept the {{var | fallback}} interpolation grammar from @tour-kit/core. Wrap your tree in <LocaleProvider> and every announcement title and description resolves automatically.
import { LocaleProvider } from '@tour-kit/core'
import { AnnouncementsProvider, AnnouncementModal } from '@tour-kit/announcements'
<LocaleProvider locale="en" messages={{ 'welcome.title': 'Hi {{user.name | there}} — what is new' }}>
<AnnouncementsProvider
announcements={[{ id: 'welcome', variant: 'modal', title: { key: 'welcome.title' }, description: 'See the highlights below.' }]}
>
<AnnouncementModal id="welcome" />
</AnnouncementsProvider>
</LocaleProvider>Full guide: https://usertourkit.com/docs/guides/i18n
Public changelog page
@tour-kit/announcements also exports <ChangelogPage> (server-renderable, category filter, emoji reactions, media support) plus serializeFeed() for RSS 2.0 + JSON Feed 1.1 syndication. The page lives behind the @tour-kit/announcements/changelog subpath so toast/modal/banner-only consumers tree-shake out the renderer.
Full guide: https://usertourkit.com/docs/announcements/changelog
Variants
| Variant | When to use | |---|---| | Modal | Centered dialog for important announcements; blocks UI | | Slideout | Side panel for detailed content; non-blocking | | Banner | Top/bottom strip for persistent messages | | Toast | Corner notification with auto-dismiss timer | | Spotlight | Highlights a target element with floating content |
Frequency rules
type FrequencyRule =
| 'once' // ever
| 'session' // per browser session
| 'always' // every time conditions match
| { type: 'times', count: N } // up to N times total
| { type: 'interval', days: N } // every N daysHeadless components
import { HeadlessToast } from '@tour-kit/announcements/headless'
<HeadlessToast
id="release-notes"
render={({ isVisible, dismiss, announcement, progress }) => (
isVisible ? (
<div className="custom-toast">
<h3>{announcement.title}</h3>
<button onClick={dismiss}>×</button>
</div>
) : null
)}
/>Available headless components: HeadlessModal, HeadlessSlideout, HeadlessBanner, HeadlessToast, HeadlessSpotlight.
API Reference
Components (styled)
| Export | Purpose |
|---|---|
| AnnouncementsProvider | Context provider — registers announcements, manages queue |
| AnnouncementModal | Centered dialog variant |
| AnnouncementSlideout | Side panel variant |
| AnnouncementBanner | Top/bottom strip variant |
| AnnouncementToast | Corner toast variant with auto-dismiss |
| AnnouncementSpotlight | Element highlight variant |
| AnnouncementOverlay | Background overlay primitive |
| AnnouncementClose, AnnouncementContent, AnnouncementActions | Sub-components |
Hooks
| Hook | Description |
|---|---|
| useAnnouncement(id) | Single announcement state + show, dismiss, complete, actionClicked |
| useAnnouncements(filter?) | All announcements (filter by variant, status, etc.) |
| useAnnouncementQueue() | Queue inspection: current, queued, dequeue manually |
| useAnnouncementsContext() | Raw context (advanced) |
Core utilities
| Export | Purpose |
|---|---|
| PriorityQueue, createComparator | Queue primitives |
| AnnouncementScheduler | Queue manager |
| canShowByFrequency, canShowAfterDismissal, getViewLimit | Frequency evaluation |
| matchesAudience, validateConditions | Audience targeting |
Variants (CVA)
import {
modalOverlayVariants, modalContentVariants,
slideoutOverlayVariants, slideoutContentVariants,
bannerVariants,
toastContainerVariants, toastVariants, toastProgressVariants,
spotlightOverlayVariants, spotlightContentVariants,
} from '@tour-kit/announcements'Types
import type {
AnnouncementConfig,
AnnouncementVariant, // 'modal' | 'slideout' | 'banner' | 'toast' | 'spotlight'
AnnouncementPriority, // 'critical' | 'high' | 'normal' | 'low'
AnnouncementState,
AnnouncementAction,
AnnouncementMedia,
FrequencyRule,
DismissalReason,
AudienceCondition,
AnnouncementStorageAdapter,
// Position
BannerPosition, SlideoutPosition, ToastPosition,
// Variant options
ModalOptions, SlideoutOptions, BannerOptions, ToastOptions, SpotlightOptions,
// Queue
PriorityOrder, StackBehavior, QueueConfig, QueueItem,
// Context
AnnouncementsContextValue, AnnouncementsProviderProps,
// Events
AnnouncementEvent, AnnouncementEventType,
} from '@tour-kit/announcements'
// Runtime export
import { DEFAULT_QUEUE_CONFIG } from '@tour-kit/announcements'Gotchas
show()may queue — atmaxConcurrent, the call returns immediately and enters the queue rather than rendering.- Frequency persists in localStorage by default — incognito mode bypasses, custom adapter for cookies / remote.
- Audience targeting needs
userContext— pass it to the provider, otherwise audience-targeted announcements never show. @tour-kit/schedulingis optional — only required if you pass ascheduleprop.
Related packages
@tour-kit/scheduling— schedule announcements with timezone-aware rules@tour-kit/react— sequential product tours@tour-kit/hints— single-element feature hints@tour-kit/checklists— onboarding checklists@tour-kit/license— required Pro license key validation
Documentation
Full documentation: https://usertourkit.com/docs/announcements
License
Pro tier — see LICENSE.md. Requires a Tour Kit Pro license key.
