Guides

Announcing what's new

How the Dashboard tells people that something is new: a tip, a launch or a guided tour. Which one to use, how to write it, and how a cursor can show a step instead of a paragraph explaining it.

Why show instead of tell

  • People do not read. A step that is shown is understood before its sentence is finished.
  • Every step is an interruption of what the person came to do. Fewer, shorter steps cost less.
  • A cursor acting on the real screen shows cause and effect: you switch this, that changes. Text can only claim it.

Pick the size

Three sizes of news, three ways to say it. Start from the smallest one that works.

TipTour, one step

One thing, on one control. A single card pointing at it, with Got it!. No welcome, no dim worth noticing, gone in one click.

"You can now reorder these columns."

LaunchHighlightDialog

A new feature or section. One dialog with something to look at, a title, a sentence, and a button that takes the person there.

"Custom checkouts: a separate checkout for each market."

Guided tourHighlightDialog + Tour

A new layout or a new way of doing something. The dialog is the door; its Primary starts a tour of 3 to 5 steps over the real screen.

"The Checkout Builder has a new layout."

If it needs more than five steps, it is not a tour
Split it into two launches, or let the screen explain itself better. A long tour is skipped at step two, and skipping marks it as seen.

What a guided tour is made of

Four parts, all from the kit. The motion is the same in every tour; only the steps change.

The doorA HighlightDialog. It says what is new and offers two ways on: Skip tour closes it, the Primary starts the tour. Nobody is walked through anything they did not ask for. As a door its outline button reads Skip tour; as a launch on its own it keeps Got it!.
The cut-outThe page dims with the kit's overlay tone and what the step is about stays lit and clickable. Within one scrolling area it moves to the next target on a spring, in one motion; into another view (a conversation opening over the page) it closes where it was and opens where it lands, like an iris. Its corners follow what it lights, and it stops at the edge of the area it is seen through. It stays on that target for the whole step: one steady light.
The cardA TourCard, the design system's Tutorial: title, one sentence, Skip on the first step, Back from the second, the step count, Next and then Got it!, and an X that always closes. It does not ride along while the light moves: it leaves, and arrives beside the next target once the light has landed and the page is still.
The cursorOptional, per step. It acts the step out on the real screen: it goes somewhere, points at something, presses it. The clicks are real, so the screen reacts as it would for the person. Its tip rests where it does not cover what it shows: in the middle of a small control, on the lower edge of anything wider. A click shows as a pulse and as what the screen does; what it only points at gets a soft tint for a moment, with no outline (only on something the size of a control). Whatever is under its tip is marked data-tour-hover, so the screen's hover styles can answer to it as they do to a real pointer. The demo plays twice: once on arrival and once more after a pause, for whoever was still reading, unless the person has started using the screen or the step is set to play it once.

Writing a step

A tour is a list. Each step says what it points at and what it says about it. Mark the target on the screen with a data-tour attribute.

The tour does not remember who has seen it: open and onClose are yours, and so is that memory.
import { Tour, type TourStep } from "@/components/patterns/tour";

const STEPS: TourStep[] = [
  {
    target: "cb-methods",          // data-tour="cb-methods" on the screen
    side: "right",
    title: "Your payment methods",
    body: "Switch a method on or off, and open it with Edit.",
  },
  // ...
];

<Tour steps={STEPS} open={open} onClose={() => setOpen(false)} />
  • One idea per step. If the sentence has an "and also", it is two steps.
  • A title of a few words and one sentence of body.
  • Point at the smallest thing that holds the idea: the list, not the whole page.
  • Find elements by data-tour, never by their text. Text changes with the language.
  • A step whose target is not on the screen needs a before that takes the screen there.

Writing a demo

A demo is what the cursor does on a step: a short list of actions, in order. Every launch writes its own; the cursor, its speed and its timing come from the kit and are the same everywhere.

ActionWhat the cursor does
moveGoes to an element and stays there.
pointGoes to an element, pulses and tints it softly for a moment, without pressing it. For "this is where you would go".
clickGoes to an element, rests, and presses it. The click is real: a switch flips, a menu opens. With act, the press is shown and act runs instead, for a control whose real flow (a dialog to fill in) the guide skips to show where it ends.
typeGoes to a field and types into it, a character at a time, about a second for a sentence. The screen's own validation and formatting react.
dragPicks something up by its grip, carries it to a new place and drops it. The reorder is real and the neighbours slide to make room.
waitHolds still so the result can be seen. With until, it holds until something is on the screen, such as an answer still being written.
to names a data-tour value, or an element inside one: find is a CSS selector and nth picks among its matches.
{
  target: "cb-methods",
  side: "right",
  title: "Your payment methods",
  body: "Switch a method on or off, and open it with Edit.",
  demo: [
    // Turn Pix on, let it be seen, turn it back off: the demo ends where it started.
    { do: "click", to: { tour: "cb-methods", find: '[role="switch"]', nth: 3 } },
    { do: "wait", ms: 900 },
    { do: "click", to: { tour: "cb-methods", find: '[role="switch"]', nth: 3 } },
    // Then show where a method opens, without opening it.
    { do: "point", to: { tour: "cb-methods", find: "button:not([role])", nth: 0 } },
  ],
}
Do
  • Give the Tour an onRestore, so what a demo changes never stays behind.
  • Leave a wait after a click, so the result is seen.
  • Use point for anything that would leave the screen or commit something.
  • Shorten the sentence once the demo shows it.
Don't
  • Don't click Publish, Save, Delete or anything that commits. Point at it, or show where it ends with act and play the step once.
  • Don't act out more than one idea in a step.
  • Don't rely on the demo alone: under reduced motion it does not play, and the sentence has to stand.
  • Don't type real-looking personal or card data into a field.

Putting the screen back

A demo changes the real screen, and the person can press Next in the middle of it. Give the Tour an onRestore and it is called whenever a step whose demo acted is left, on Next, Back or close. onSnapshot is called right before a demo starts, which is the moment to remember how the screen was. With both, a demo may stop anywhere and nothing it did stays behind.

// A product screen restores its own state.
const snapshot = React.useRef(null);

<Tour
  steps={STEPS}
  open={open}
  onClose={() => setOpen(false)}
  onSnapshot={() => { snapshot.current = store.getState(); }}
  onRestore={() => { if (snapshot.current) store.setState(snapshot.current, true); }}
/>

When several things launch at once

Three launches in one week are three interruptions for someone who came to do something else. These rules keep the third one from being closed unread.

  • An announcement belongs to its section. It opens when the person arrives there, never all together at sign-in.
  • Only one opens by itself in a session. The others wait without blocking, as a New mark on their menu entry.
  • Never over a task in progress. It opens on arrival, not while the person is editing.
  • Closing is not losing: there is one place where every current announcement can be opened again.
  • Announcements expire. After a few weeks a new layout is just the layout, and someone new never sees it announced.
  • Only for the people it is for: by role and by access to the feature.
  • Measure it: started, completed, dismissed. Without that nobody knows whether the tour helps.
A proposal, not yet how production works
Production queues tutorials by priority, shows one at a time and remembers per person which ones were seen. Its tutorial hook (read on 8 Oct 2026) has no limit per session, no expiry and no way to reopen one: those rules need engineering work. In a prototype, follow them by hand.

How this maps to production

What a prototype built with these pieces becomes when it ships.

  • The TourCard is production's own card: the design system's Tutorial, re-exported.
  • Production runs tours with react-joyride and a queue with priority, and stores what each person has seen in their settings (viewed_tutorials). The kit's Tour is a prototype of the same thing, without the library.
  • The dim is the same tone: foreground at 24%.
  • The cursor and the HighlightDialog are not in production yet. The dialog exists in the design system's Figma (Highlight / Dialog).

Related

  • Highlight dialogThe launch, and the door to a tour.
  • TourThe pattern itself: its props, its steps and its demo actions.
  • Tour cardThe card of each step.
  • PopoverWhat places the card next to its target.
  • Overlays & full-screenHow to pick between the surfaces that take the person's attention.
  • MotionThe curve and the tokens the tour moves with.