Files
agent-skills/skills/vue-best-practices/reference/teleport-multiple-to-same-target.md
Jason Woltje f5792c40be feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories:
- anthropics/skills: 16 (docs, design, MCP, testing)
- obra/superpowers: 14 (TDD, debugging, agents, planning)
- coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth)
- better-auth/skills: 5 (auth patterns)
- vercel-labs/agent-skills: 5 (React, design, Vercel)
- antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo)
- Plus 13 individual skills from various repos

Mosaic Stack is not limited to coding — the Orchestrator and
subagents serve coding, business, design, marketing, writing,
logistics, analysis, and more.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:27:42 -06:00

3.8 KiB
Raw Blame History

title, impact, impactDescription, type, tags
title impact impactDescription type tags
Multiple Teleports to Same Target Append in Order LOW When multiple Teleport components target the same element, they append in declaration order capability
vue3
teleport
modal
order

Multiple Teleports to Same Target Append in Order

Impact: LOW - Multiple <Teleport> components can mount content to the same target element. Content appends in declaration order - later teleports appear after earlier ones in the DOM.

This is useful for notification stacks, modal layering, and tooltip systems.

Task Checklist

  • Use consistent teleport targets for related UI (e.g., all modals to #modals)
  • Leverage natural stacking order or use z-index for layer control
  • Consider a notification/modal management system for complex cases

Basic Example:

<template>
  <Teleport to="#notifications">
    <div class="notification">First notification</div>
  </Teleport>

  <Teleport to="#notifications">
    <div class="notification">Second notification</div>
  </Teleport>
</template>

Resulting DOM:

<div id="notifications">
  <div class="notification">First notification</div>
  <div class="notification">Second notification</div>
</div>

Practical Example: Notification Stack

<!-- NotificationSystem.vue -->
<template>
  <Teleport to="#notifications">
    <TransitionGroup name="notification" tag="div" class="notification-stack">
      <div
        v-for="notification in notifications"
        :key="notification.id"
        class="notification"
        :class="notification.type"
      >
        {{ notification.message }}
        <button @click="dismiss(notification.id)">×</button>
      </div>
    </TransitionGroup>
  </Teleport>
</template>

<script setup>
import { ref } from 'vue'

const notifications = ref([])

function notify(message, type = 'info') {
  const id = Date.now()
  notifications.value.push({ id, message, type })
  setTimeout(() => dismiss(id), 5000)
}

function dismiss(id) {
  notifications.value = notifications.value.filter(n => n.id !== id)
}

defineExpose({ notify })
</script>

Modal Layering

When modals open other modals, they naturally stack:

<!-- ParentModal.vue -->
<template>
  <Teleport to="#modals">
    <div v-if="visible" class="modal">
      <p>Parent Modal</p>
      <button @click="showChild = true">Open Child Modal</button>
    </div>
  </Teleport>

  <!-- Child modal teleports after parent -->
  <Teleport to="#modals">
    <div v-if="showChild" class="modal child-modal">
      <p>Child Modal (appears on top)</p>
      <button @click="showChild = false">Close</button>
    </div>
  </Teleport>
</template>

<style>
.modal {
  position: fixed;
  /* Later modals naturally have higher stacking order */
}
</style>

Controlling Order with z-index

For explicit control over stacking:

<template>
  <Teleport to="#modals">
    <div v-if="showBase" class="modal" style="z-index: 100;">
      Base Modal
    </div>
  </Teleport>

  <Teleport to="#modals">
    <div v-if="showConfirm" class="modal" style="z-index: 200;">
      Confirmation Dialog (always on top)
    </div>
  </Teleport>
</template>

Cross-Component Teleports

Components from different parts of the app can teleport to the same target:

<!-- Header.vue -->
<template>
  <Teleport to="#global-alerts">
    <div v-if="headerAlert" class="alert">Header alert</div>
  </Teleport>
</template>

<!-- Footer.vue -->
<template>
  <Teleport to="#global-alerts">
    <div v-if="footerAlert" class="alert">Footer alert</div>
  </Teleport>
</template>

<!-- Both appear in #global-alerts, ordered by mount timing -->

Reference