Banners
Banners are persistent notification bars that appear at the top or bottom of the viewport. They span the full width of the page and deliver brief, important messages without blocking the user's workflow.
Overview
A banner consists of:
- Bar -- A full-width strip fixed to the top or bottom of the viewport
- Message -- Short text content with optional icon
- Action -- Optional CTA button or link
- Dismiss -- Close button to remove the banner
Banners are ideal for:
- System-wide announcements (maintenance windows, new releases)
- Promotional messages and upgrade prompts
- Persistent warnings or status notifications
- Cookie consent or legal notices
- Trial expiration reminders
Creating a Banner
Via the Admin Panel
- Navigate to Content > Banners and click Create Banner.
- Write the banner message.
- Choose the position (top or bottom).
- Select a style variant (info, success, warning, error, or custom).
- Add an optional CTA button.
- Configure trigger, audience, and scheduling rules.
- Click Publish.
Via the API
All non-tour content shares one admin endpoint — POST /v1/admin/content — discriminated by content_type. Note the field name: body, not message.
POST /v1/admin/content
Content-Type: application/json
X-Api-Key: sk_live_...
{
"content_type": "banner",
"name": "Maintenance Notice",
"body": "Scheduled maintenance on Saturday, 10 PM - 2 AM UTC. Some features may be unavailable.",
"cta": {
"text": "Learn More",
"action": "url",
"url": "/status"
},
"trigger": { "trigger_type": "page_load" },
"schedule": {
"start": "2025-07-18T00:00:00Z",
"end": "2025-07-20T02:00:00Z"
}
}Banner UI fields like
position,variant,icon,dismissible,stickyare handled by the SDK renderer at display time and are configured in the dashboard's banner builder — they aren't part of the wire schema today.
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Internal name for the banner |
message | string | Yes | Banner message text (supports limited safe HTML) |
position | string | No | Where the banner appears: top or bottom (default: top) |
variant | string | No | Visual style: info, success, warning, error, custom (default: info) |
icon | string | No | Icon to display before the message: info, success, warning, error, none |
cta | object | No | Call-to-action button |
dismissible | boolean | No | Whether the banner can be dismissed (default: true) |
sticky | boolean | No | Whether the banner stays fixed on scroll (default: true) |
trigger | object | No | When to show the banner |
audience | object | No | Who should see the banner |
schedule | object | No | Start and end dates for the banner |
Position
Top
The banner appears at the very top of the viewport, above all page content. When sticky is true, it remains fixed during scroll.
{ "position": "top" }TIP
Top banners push page content down. If your application has a fixed header or navigation bar, use the --spot-z-index theme variable to ensure the banner renders at the correct layer.
Bottom
The banner appears at the bottom of the viewport.
{ "position": "bottom" }Style Variants
Each variant applies a distinct colour scheme to the banner:
| Variant | Background | Text | Icon | Use Case |
|---|---|---|---|---|
info | Blue | White | Info circle | General announcements |
success | Green | White | Check circle | Positive confirmations |
warning | Amber/orange | Dark | Warning triangle | Maintenance, caution |
error | Red | White | Error circle | Critical issues |
custom | Uses theme variables | Uses theme variables | None | Brand-specific styling |
{ "variant": "warning" }Custom Variant Styling
When using the custom variant, the banner inherits from your theme variables:
| Variable | Effect |
|---|---|
--spot-primary | Banner background colour |
--spot-primary-text | Banner text colour |
--spot-radius | Banner corner radius (set to 0 for edge-to-edge) |
CTA Button
Add an action button to the banner:
{
"cta": {
"text": "Upgrade Now",
"action": "url",
"url": "/billing/upgrade"
}
}CTA actions:
| Action | Description |
|---|---|
url | Navigate to a URL |
dismiss | Close the banner |
track | Fire a custom event and close |
Dismissal
When dismissible is true, a close button (X) appears on the right side of the banner. The user can click it to dismiss the banner.
Once dismissed, the banner's progress state is recorded. The banner will not reappear for that user on subsequent page loads (unless demoMode is enabled).
Set dismissible: false for banners that must remain visible (e.g., legal notices, critical system alerts):
{
"dismissible": false
}WARNING
Non-dismissible banners stay visible until the schedule ends or the banner is unpublished by an admin. Use sparingly -- persistent, non-dismissible UI is a poor user experience if overused.
Scheduling
Banners support start and end dates for time-limited messages:
{
"schedule": {
"start": "2025-12-20T00:00:00Z",
"end": "2025-12-26T00:00:00Z"
}
}The banner is only shown between the start and end timestamps (inclusive). Outside this window, the banner does not render. This is evaluated server-side, so the banner is not included in the SDK content response outside the schedule.
Sticky Behaviour
When sticky is true (default), the banner is fixed to the viewport edge and remains visible during scroll. When false, the banner scrolls with the page content.
{ "sticky": false }Rich Content
Banner messages support limited safe HTML for inline formatting:
{
"message": "New feature: <b>PDF Export</b> is now available. <a href='/docs/export' target='_blank'>Learn how to use it</a>."
}Supported tags in banners: b, i, strong, em, a, br, span.
TIP
Keep banner messages concise -- one or two sentences maximum. For detailed content, use a CTA button that links to a full page or opens a modal.
Multiple Banners
Multiple banners can be active simultaneously. When more than one banner targets the same position (e.g., two top banners), they stack vertically in the order they were triggered.
WARNING
Stacking more than two banners at the same position creates a poor user experience. Use audience targeting and scheduling to avoid showing multiple banners simultaneously.
Programmatic Control
Banners fire on their trigger + audience + schedule rules. Hook content:dismiss to react when one closes:
Spotlight.on('content:dismiss', (data) => {
console.log(`User dismissed content: ${data.contentId}`);
});Styling
Banners inherit --spot-* theme variables. For the custom variant, key variables include:
| Variable | Effect |
|---|---|
--spot-primary | Background colour (custom variant) |
--spot-primary-text | Text colour (custom variant) |
--spot-font-size-sm | Banner text size |
--spot-font-weight-medium | Banner text weight |
--spot-z-index | Banner stacking order |
Accessibility
- Banners use
role="alert"for important messages androle="status"for informational messages. - The dismiss button has
aria-label="Dismiss banner". - Banner text colour and background colour meet WCAG AA contrast requirements for all built-in variants.
- Keyboard users can tab to the CTA button and dismiss button.