# Teleport in Vue 3: modals outside the parent DOM

Teleport moves a modal under body, where no parent overflow or transform can clip it. The component stays the same, only the node changes.

> Page: https://ui.eneawork.it/blog/vue-3-teleport-modal
> Markdown: https://ui.eneawork.it/blog/vue-3-teleport-modal.md

*2026-11-01*

Una modale in Vue 3 esce dalla gerarchia visiva del genitore con <Teleport>: il nodo finisce sotto body, dove nessun overflow: hidden o transform lo può tagliare.

Misurato il 1 novembre 2026: il catalogo conta 111.985 componenti, 1.556 blocchi e 12.808 icone da 1.472 librerie, letti da /api/stats. Su 1.514 profili di libreria 10 riguardano Vue, 8 dei quali dichiarano licenza MIT: Gli esempi qui sotto usano solo l’API pubblica di Vue 3. Metodo: lettura di data/library_profiles.json e della risposta di /api/stats con uno script Node, sul repository EneUI.

## Il problema che risolve

Un pannello con position: fixed si posiziona rispetto all’antenato con transform, filter o perspective più vicino, non rispetto alla finestra. Dentro una card animata la modale appare ritagliata e l’overlay copre metà schermo.

import { ref } from "vue"; const open = ref(false); Open Title Close

L’attributo to accetta un selettore CSS o un elemento. Il v-if sta dentro il Teleport: così il contenuto non esiste nel DOM quando la modale è chiusa.

## Un contenitore dedicato, oppure no

... -->

Un contenitore vuoto in index.html evita di appoggiarsi a body: se un altro script monta un elemento sul body, il tuo nodo resta tuo. Con :disabled il Teleport si spegne e il contenuto torna al suo posto, utile nei test.

## Teleport, dialog nativo, libreria

## Errori comuni

## Il limite da mettere in conto

Teleport sposta il DOM, non il contesto: provide, inject, emit e listener continuano a funzionare perché l’istanza non cambia. Non risolve però focus trap e blocco dello scroll, che restano da scrivere o da prendere da una libreria headless.

## Dove continuare

Nel catalogo: shadcn-vue, PrimeVue e vue-bits; i blocchi di dialogo sono in /blocks. Le guide: Composition API e Pinia. I confronti: portal in React e Vue vs React.

## FAQ

### Posso usare Teleport per una modale accessibile?

Sì, ma Teleport gestisce solo la posizione nel DOM. Focus trap, blocco dello scroll e chiusura con ESC vanno scritti o presi da una libreria headless.

### Si perde il contesto del componente?

No. L’istanza resta la stessa: provide, inject, emit e stato reattivo funzionano come prima dello spostamento.

### Perché la modale non compare?

Il selettore in to non trova nulla. Vue avvisa in console e salta il rendering: controlla che il nodo esista prima del mount.

### Teleport funziona con il rendering lato server?

Sì, con un’avvertenza: sul server il contenuto viene reso dove è dichiarato. Usa l’attributo disabled durante l’idratazione per evitare disallineamenti.

### Serve un contenitore dedicato?

Non è obbligatorio. body funziona, ma un nodo tuo evita conflitti con altri script che montano sullo stesso body.
