Render Elsewhere in the DOM Tree
Teleport
`<Teleport>` keeps the component logic where it belongs but renders the output somewhere else — perfect for modals and tooltips.
What you'll learn
- Use `<Teleport to="body">`
- Build a modal that escapes overflow:hidden parents
- Disable Teleport conditionally
Modals, tooltips, and toasts often need to escape the DOM ancestor’s overflow or z-index. <Teleport> keeps the component logic in place but moves the DOM output to a different node — body, a #modal-root, anywhere.
Basic Use
<template>
<button @click="open = true">Open modal</button>
<Teleport to="body">
<div v-if="open" class="modal">
<p>This DOM lives at the end of body.</p>
<button @click="open = false">Close</button>
</div>
</Teleport>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const open = ref(false)
</script> The <div class="modal"> element is appended to <body>. Reactivity, events, and component state all still work — only the DOM placement changes.
Target Selector
to accepts any CSS selector or an Element. A custom mount root is common:
<!-- index.html -->
<body>
<div id="app"></div>
<div id="modal-root"></div>
</body> <Teleport to="#modal-root">…</Teleport> Conditional Teleport
Need the same component to render in place on mobile and teleport on desktop? Use the disabled prop.
<Teleport to="body" :disabled="isMobile">
<Dialog />
</Teleport> When NOT to Use It
For “render this elsewhere” needs that don’t involve escaping DOM context (overflow, z-index, focus traps), regular slots are usually clearer.
KeepAlive — Preserve Component State →