DocsKeep tours from breaking
Docs

Keep tours from breaking

A tour anchors to elements in your source, so deleting one breaks it silently. rendemo check catches that offline, in CI, with exit codes that are a contract.

Why a deleted button matters

A tour anchors to elements in your source. Rename a button, refactor a page, delete a control a step points at — and the tour breaks for every user, with nothing in your build to say so. The card simply waits for a target that will never appear and then gives up.

rendemo check turns that into a build failure. It is offline, needs no token and no network, and takes about a second.

bash
npx rendemo check

rendemo.tours.json

The check compares your source against a committed lockfile describing the published tour — which is what lets it run with no credentials.

json
{
  "version": 1,
  "tours": {
    "onboarding": {
      "planHash": "b3e09f4136…",
      "steps": [
        { "step": "stage", "route": "/projects/:id" },
        { "step": "pick-step", "route": "/projects/:id", "do": "click", "match": "first" }
      ]
    }
  },
  "ignore": ["fixtures/", "*.stories.tsx"]
}
  • Generated, never hand-edited. rendemo_get_tour_lockfile produces it — pass the current file so other tours survive, since one file describes every tour in the repo.
  • planHash is printed, never compared. The check is offline, so it cannot ask what is published. Printing it is what makes it auditable by a human.
  • ignore replaces the defaults (*.test.*, *.spec.*, __tests__/, e2e/, tests/) — re-list them if you still want them.

Running the check

What it does, in order:

  • Reads rendemo.tours.json at the path.
  • Walks it for source files — .tsx .ts .jsx .js .vue .svelte .html .erb .astro.
  • Finds every marker, in either spelling, plus demo("tour/step", …) calls.
  • Confirms every step in the lockfile resolves to exactly one marker in source.

It skips build output and agent scratch — node_modules, .next, dist, out, .vercel, .claude and the rest — because a built copy of your source carries the same marker strings and scanning both would report every marker as a duplicate. Comment bodies are blanked first, so a marker mentioned only in a comment does not count as present.

It never follows symlinks, but it reports every symlink and unreadable file it skipped. A scan that silently shrank is how “the marker is right there and check says it is missing” becomes unexplainable.

Three things it cannot tell you

All three because it only reads files:

  • Whether the cards say anything useful. The lockfile carries no copy, so the titles and blurbs exist nowhere in your repo. Preview the tour instead — it is the only thing that shows you what the cards actually say.
  • Whether a .map()ed target needs match. One occurrence in source, N elements at runtime. Nothing static can see that.
  • Whether planHash is still what is published. No network. Compare it by hand, or use the studio’s “Changes not live” indicator.

Wiring it into CI

yaml
- run: npx rendemo check

That is the whole integration. It needs actions/checkout before it and nothing else — no token, no network, no npm ci. Put it early in the job: it takes about a second, and failing there beats failing after a full build.

A repo whose own package is named rendemo

npx resolves the local package first and fails with something like could not determine executable to run — which looks nothing like a tour problem. Install the CLI as a devDependency and run ./node_modules/.bin/rendemo check.

What each failure means

FailureWhat to do
missing-markerA step has no marker in source — usually the element was renamed or deleted. The output names the exact attribute to write.
duplicate-markerThe marker appears more than once in source and the step has no match. Either de-duplicate, or give the step a match and republish — never edit the lockfile to add one.
orphan-markerA marker in source that no step references. Delete it, or add the step. This is what you hit when a step was removed and its attribute was left behind.
unknown-flow (warning)Source has markers for a tour the lockfile does not describe, so nothing about that tour is being checked. Regenerate the lockfile, or add the path to ignore if the markers are examples.

Exit codes are a CI contract and are listed in Reference.