Skip to main content

Conditions and preparation

Include relevant steps and prepare interface state before a target is resolved.

Prepare and conditionally include steps

Use when() to decide whether a step belongs in the current journey. Use prepare() to create the interface state that the destination needs.

Skip an irrelevant step

ts
{
  id: 'invite-team',
  target: 'invite-team',
  title: 'Invite your team',
  content: 'Add the people who work on this project.',
  when: () => useState<boolean>('can-invite-team').value,
}

next() and previous() skip a step when when() returns false. An exact goTo('invite-team') call rejects instead of silently opening another step.

Reveal a target before resolving it

ts
{
  id: 'import',
  target: 'import-panel',
  title: 'Import existing work',
  content: 'Upload a CSV file or connect another service.',
  async prepare() {
    const importPanelOpen = useState('import-panel-open', () => false)
    importPanelOpen.value = true
    await nextTick()

    return () => {
      importPanelOpen.value = false
    }
  },
}

Nuxt Tour runs the returned cleanup once when the step ends or fails. The same cleanup runs when the user cancels or another tour replaces this one.

Use the supplied AbortSignal for request cancellation:

ts
async prepare({ signal }) {
  await $fetch('/api/project-tour-context', { signal })
}

Do not use arbitrary delays to wait for rendering. Change the state, await the framework update when necessary, and let target resolution wait for the actual element.

Share a panel across adjacent steps

Preparation for the next step can overlap cleanup from the previous step. Two steps that each open and then close the same panel can therefore close it too early. Give the panel one owner in application code, or use a shared lease count:

ts
function holdImportPanel() {
  const leases = useState('import-panel-tour-leases', () => 0)
  leases.value += 1
  return () => { leases.value -= 1 }
}

// Each step that needs the panel uses this preparation.
const prepare = () => holdImportPanel()

The panel renders while manualOpen || leases > 0. Its normal user-controlled state remains separate from the tour's leases. Each preparation returns its release function immediately; the runtime calls it once, including cancellation. When preparation awaits work after opening UI, always return the cleanup even if the signal was aborted during the wait. Do not return early and lose it.