Skip to content

Guides

Steps and advancing

What a step can say, where its popover sits, and the different ways it can move on to the next one.

A step is one stop on the tour: an element, a short explanation, and a way to continue. Good steps say one thing. If a step needs three paragraphs, it is probably two steps.

{
id: 'invoices',
target: { name: 'invoices-tab' },
title: 'Invoices',
body: 'Click **Invoices** to see everything you have billed.',
format: 'markdown',
media: { type: 'image', src: '/help/invoices.png', alt: 'The invoices list' },
}
  • title is the heading. Keep it short, ideally under six words.
  • eyebrow is a small line above it. Set it once for the whole tour, or per step; '' removes it for one step. See themes.
  • body is plain text by default.
  • With format: 'markdown', a safe subset is rendered: bold, italic, code, links, paragraphs and line breaks.
  • media adds an image or a video above the text. Always give images an alt.

placement says where you would like the popover. It is a preference, not an order:

placement: 'auto' | 'top' | 'right' | 'bottom' | 'left'
| 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end'
| 'left-start' | 'left-end' | 'right-start' | 'right-end'

If the preferred side has no room, the popover flips to the opposite side, then tries the other two, and finally slides along the edge to stay on screen. -start and -end align the popover with one end of the element instead of its middle.

Below 480 px wide there is no room beside an element, so the popover becomes a card as wide as the screen, with a margin around it. When the card fits above or below the element, it sits there and points at it; the step’s placement picks which side it tries first. When it fits on neither side, it docks near the bottom edge, still pointing at the element, and the page scrolls so the element stays visible above it. An element pinned to the bottom of the screen, such as a tab bar, or at the very end of the page gets the card docked at the top instead.

Set options.mobile.layout to choose: 'auto' (the default, as above), 'float' to always sit beside the element, or 'dock' to always dock:

"options": { "mobile": { "layout": "dock" } }

The card itself is laid out for thumbs on a small screen: progress becomes one segment per step across the top, filling as each step opens; the main button (Next or Done) is full width; Back and Skip sit beneath it as quiet text. A step with no target, such as a welcome or a finish, is centred on the screen with a larger title and its image at the top. Set "mobile": { "card": "classic" } to keep the large-screen card on phones.

For a lighter touch, "mobile": { "card": "compact" } turns the card into a coachmark: sized by its content (up to about 70% of the screen), right beside the element and pointing at it, as on a large screen, so most of the page stays in view. Progress becomes a row of dots, Back a round arrow, Next a small pill, and Skip is left to the close button. The buttons are drawn small but keep a full-size area to tap. It never docks unless layout is 'dock': when neither side has room, it overlaps the edge of the element from above or below instead.

"options": { "mobile": { "card": "compact" } }

Change the width with the renderer’s sheetBreakpoint, or set it to 0 to lay the popover out as on a large screen at every size.

The popover never grows taller than the screen. When a step has more text than fits, the text scrolls inside the card, the last line fades while more remains, and the buttons stay put at the bottom. On short screens, such as a phone held sideways, spacing and type tighten a little. If no side has room, the popover sits over part of the element rather than off the edge of the screen.

By default the person presses Next. The advance field lets the tour follow what they actually do instead, which teaches far better than reading.

advance The step moves on when
'button' the person presses Next (default)
{ on: 'click' } they click the target
{ on: 'input', match: '^\\S+@' } what they type matches the regular expression
{ on: 'event', name: 'saved' } your code calls controller.notify('saved'), or docent.track('saved') with the manager
{ on: 'element', target: '#menu' } an element appears
{ on: 'delay', ms: 4000 } the time passes

Normally the spotlighted element cannot be clicked, so nobody triggers an action by accident mid-tour. Click and input steps make it clickable automatically. For any other step, set interaction: 'allow' to let people use the element.

LiveClick, type, and a blocked element

Hide buttons on one step:

buttons: { back: false, skip: false, close: false, next: false }

Change the wording for a whole tour with options.labels, or for every tour at once with the renderer’s labels:

options: {
labels: { next: 'Continue', back: 'Previous', skip: 'Not now', done: 'Finish', progress: 'Step {current} of {total}' },
// `{current2}` and `{total2}` pad to two digits: `03 / 09`.
}

With showProgress on, the popover shows how far along the person is. The count includes every step, even ones later skipped by a condition, so the numbers never jump backwards mid-tour.

progress picks how it is drawn: meter (the default, a slim bar and the count), count, ticks, dots, or none.

options: { showProgress: true, progress: 'dots' }

A step-level condition skips that step when it is false, for example a step about admin settings that only admins should see:

{ id: 'billing', condition: { type: 'trait', key: 'role', op: 'eq', value: 'admin' }, … }

Conditions are covered in Triggers and conditions.