Teleport

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.

4 min read Level 2/5 #vue#teleport#modals
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 →