Sunset Notice

Turns Sunset and Deprecation response headers into a visible countdown, so an API shutdown isn't a surprise outage.

StopsAPI shutdown arrives as an outage

GET /v1/orders · 200 OK

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/sunset-notice.json

The files land in your project. They're yours to edit.

Usage

sunset-notice-usage.tsx
import { SunsetNotice } from "@/components/ui/sunset-notice"

<SunsetNotice
  key={run}
  subject="Orders API v1"
  headers={headers}
  storageKey={storageKey}
  onSnooze={setSnoozed}
  stops={["Creating orders with POST /v1/orders", "Webhooks in the v1 payload format"]}
/>

What it catches

  • Sunset and Deprecation dates from response headers
  • Sunset earlier than deprecation, or already past
  • A local date that differs from the header's UTC date
  • Approaching deadlines (soonDays, finalDays)
  • Migration and policy links from Link rel=deprecation/sunset

Props

SunsetNotice props
PropTypeDefault
subject* (required)

What is going away, e.g. "Orders API v1".

string—
headers

The API response (or its Headers, or a plain header map). Cross-origin APIs must list Sunset, Deprecation and Link in Access-Control-Expose-Headers.

HeaderSource—
sunset

Overrides the Sunset header.

When—
deprecation

Overrides the Deprecation header.

When—
stops

Exactly what stops working at sunset.

string[][]
migrateHref

Migration guide. Defaults to the Link rel="deprecation", then rel="sunset".

string—
timeZone

Time zone for dates; defaults to the reader's own.

string—
locale

Locale for dates.

string—
storageKey

Remembers "Remind me later" per subject and sunset date. A changed date shows the notice again.

string"cui-sunset"
onSnooze

Called when the user snoozes, with the days-left mark the notice returns at.

(days: number) => void—
soonDays

Turns amber this many days before sunset, red at `finalDays`.

number30
finalDays

Days before sunset when the notice turns red.

number7
announcedText

Templates: `{subject}`, `{left}`, `{date}`, `{utc}`, `{days}` are filled in.

string"{subject} will be deprecated on {date}"
deprecatedText

Text once deprecated.

string"{subject} is deprecated"
sunsetText

Text with the sunset date.

string"{subject} stops working in {left}"
pastText

Text once the sunset has passed.

string"{subject} was due to stop on {date}"
noDateText

Text when deprecated with no date.

string"No shutdown date has been announced yet."
shiftedText

Note when the local day differs from the UTC date.

string"{date} your time ({utc} in UTC)"
pastDetailText

Detail after the sunset passed.

string"Requests may start failing at any moment."
stopsLabel

Heading of what stops working.

string"Stops working"
migrateLabel

Label of the migration link.

string"Migration guide"
remindLabel

Label of the remind-me-later button.

string"Remind me {days} before"
deprecatedLabel

Label of the deprecation date.

string"Deprecated {date}"
sunsetLabel

Label of the sunset date.

string"Sunset {date}"

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Banner is a region with an aria-label; status is role=status, or role=alert once past
  • Snooze and migrate are labelled actions; icons are aria-hidden
  • Countdown bar is aria-hidden

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Sunset timestamps are hints; the API can stop earlier or later
  • Snooze state lives in localStorage on this device
  • Accepts legacy "Deprecation: true" with no date

Rules

Rules last verified:

Confirmed: Sunset = HTTP-date with rel="sunset" links; Deprecation is a Structured Field date (e.g. @1688169599). Copied components don't update themselves, so re-check after rule changes (see updating a component).

What it stops

API shutdown arrives as an outage

Also known as

sunset header · deprecation · api versioning · end of life · breaking change · migration · rfc 8594 · developer console

Field type

Dependencies

Pairs well with