Skip to content

date: 2026-06-23 tags: [storybook, vue, teleport, vrt] status: active graduated_to:

A page's <Teleport> target in the Storybook decorator leaks content into the capture unless hidden

Symptom — the Dashboard page story rendered the "Tools" menu at the bottom-left corner of an otherwise chrome-free capture, where nothing should be.

Root cause — the Dashboard page teleports its header actions: <Teleport to="#header-actions">. That target lives in the app's layout header, which page stories don't render, so Vue would warn about a missing target. The withInertia decorator supplies one by appending a <div id="header-actions"> to <body> — but unstyled, so the teleported menu rendered at the foot of the body instead of in a header bar.

Fix — hide the host in .storybook/decorators.ts:41 (PR #723): host.style.display = 'none'. The host exists only to absorb the teleport so Vue doesn't warn; it is not a render surface. Page stories are chrome-free, and the real header-actions rendering is covered by the header component's own story.

Guard — the display: none on the decorator's teleport sink. If a future component story genuinely needs to show teleported header actions, render the real header (which owns its own #header-actions), don't un-hide the sink.