Vue Safe Teleport

0.1.2 · active · verified Sun Apr 19

vue-safe-teleport is a utility package for Vue 3 applications that enhances the built-in `<Teleport>` component to prevent common runtime errors related to target availability. It provides `<SafeTeleport>` and `<TeleportTarget>` components, ensuring that content is only teleported once its designated target DOM element is fully mounted and available. The current stable version is `0.1.2`. While the package is relatively new, its recent bug fixes (e.g., v0.1.2 for import extensions) indicate active maintenance. Key differentiators include its explicit `TeleportTarget` component for robust target registration and a fallback single-frame delay when using `SafeTeleport` with a standard DOM selector, directly addressing the "Failed to locate Teleport target with selector" issue that frequently arises from race conditions in component lifecycles. It aims to be a drop-in replacement for `<Teleport>` with added safety.

Common errors

Warnings

Install

Imports

Quickstart

This code demonstrates how to install `vue-safe-teleport`, register it as a Vue plugin, and then use both `TeleportTarget` to define a persistent teleport destination and `SafeTeleport` to send dynamic content to it, preventing common "target not found" errors. It also shows using `SafeTeleport` with a standard DOM element, which introduces a single-frame delay if the target isn't immediately present.

// main.js or similar
import { createApp } from 'vue';
import App from './App.vue';
import VueSafeTeleport from 'vue-safe-teleport';

const app = createApp(App);
app.use(VueSafeTeleport);
app.mount('#app');

// App.vue or another component
<template>
  <div>
    <h1>My Vue App</h1>
    <!-- Define a dedicated teleport target -->
    <TeleportTarget id="modals" />

    <button @click="showModal = true">Open Safe Teleported Modal</button>

    <!-- Content to be safely teleported to #modals -->
    <SafeTeleport to="#modals" v-if="showModal">
      <div style="background: white; border: 1px solid #ccc; padding: 20px; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1000;">
        <h2>Modal Content</h2>
        <p>This content is teleported securely.</p>
        <button @click="showModal = false">Close</button>
      </div>
    </SafeTeleport>

    <!-- Example without TeleportTarget, waits one frame -->
    <SafeTeleport to="#floating-element">
      <div style="position: absolute; bottom: 10px; right: 10px; background: lightblue; padding: 5px;">
        Floating Message
      </div>
    </SafeTeleport>
    <div id="floating-element" style="position: relative; width: 100px; height: 100px;"></div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { SafeTeleport, TeleportTarget } from 'vue-safe-teleport';

const showModal = ref(false);
</script>

<style>
/* Basic styling for demo */
body { margin: 0; font-family: sans-serif; }
#app { padding: 20px; }
</style>

view raw JSON →