Docs: rendering framework components as step content, and why DOM injection belongs in when.show
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,thisis the Step — an arrow function silently breaksthis.getElement(). - A per-step
whenreplacesdefaultStepOptions.whenwholesale (shallowObject.assignin_setOptions). - Scope queries with
this.getElement()rather thandocument.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.
Source: shipshapecode/shepherd