Skip to content

Docs: rendering framework components as step content, and why DOM injection belongs in when.show #3479

Description

@chuckcarpenter

Split out of #2533 and #3216. Both reporters hit the same documentation gap from different directions, and both waited a long time for an answer that should have been a docs link.

What's missing

1. Rendering a framework component as step content.

StepText accepts an HTMLElement, and shepherd-text.ts appends it directly rather than serialising it — so you can mount a live Vue/React/Svelte component to a detached node and hand that node to text, keeping reactivity and event handlers intact. Nothing in the docs says this. #2533 asked for it in Dec 2023, was told "pass HTML", asked for a demo, and never got one.

Worth documenting alongside it: the dialog chrome is Shepherd's own DOM, but everything inside is opt-out — no title/cancelIcon means no header, an empty buttons array means no footer, and arrow: false drops the arrow. With those off a component owns the entire body, which is what people asking this question actually want.

2. Why custom footer/DOM injection has to happen in when.show.

The step element is torn down and rebuilt on every show (_teardownElements() / _setupElements()), and createShepherdFooter builds a fresh <footer> each time. So a one-time DOM injection cannot survive a step change. #3216 spent a retry loop and a setTimeout ladder working around this without ever being told the element is simply recreated.

Two sharp edges belong in the same section:

  • Inside when.show, this is the Step — an arrow function silently breaks this.getElement().
  • A per-step when replaces defaultStepOptions.when wholesale (shallow Object.assign in _setOptions).
  • Scope queries with this.getElement() rather than document.querySelector, which returns the first match in document order and will find a previous step's node, since hidden steps stay attached.

Suggested home

docs-src/src/content/docs/recipes/cookbook.md already demonstrates the when.show pattern for progress indicators without explaining why it must be that hook — extending that recipe and adding a "custom content / framework components" entry would cover both.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions