x-teleport
The x-teleport directive allows you to transport part of your Alpine template to another part of the DOM on the page entirely.
By attaching x-teleport to a <template> element, you are telling Alpine to "append" that element to the provided selector.
NOTE
The x-teleport selector can be any string you would normally pass into something like document.querySelector. It will find the first element that matches, be it a tag name (body), class name (.my-class), ID (#my-id), or any other valid CSS selector.
<body>
<div x-data="{ open: false }">
<button @click="open = ! open">Toggle Modal</button>
<template x-teleport="body">
<div x-show="open">
Modal contents...
</div>
</template>
</div>
<div>Some other content placed AFTER the modal markup.</div>
...
</body>When the button is clicked, the actual modal contents show up AFTER the "Some other content..." element.
x-teleport is useful for things like modals (especially nesting them), where it's helpful to break out of the z-index of the current Alpine component.
Forwarding events
Anything you would normally do in a template, you should be able to do inside an x-teleport template. However, native DOM events have no concept of teleportation, so if, for example, you trigger a "click" event from inside a teleported element, that event will bubble up the DOM tree as it normally would.
To make this experience more seamless, you can "forward" events by simply registering event listeners on the <template x-teleport...> element itself like so:
<div x-data="{ open: false }">
<button @click="open = ! open">Toggle Modal</button>
<template x-teleport="body" @click="open = false">
<div x-show="open">
Modal contents...
(click to close)
</div>
</template>
</div>Nesting
Teleporting is especially helpful if you are trying to nest one modal within another. Alpine makes it simple to do so:
<div x-data="{ open: false }">
<button @click="open = ! open">Toggle Modal</button>
<template x-teleport="body">
<div x-show="open">
Modal contents...
<div x-data="{ open: false }">
<button @click="open = ! open">Toggle Nested Modal</button>
<template x-teleport="body">
<div x-show="open">
Nested modal contents...
</div>
</template>
</div>
</div>
</template>
</div>After toggling "on" both modals, they are authored as children, but will be rendered as sibling elements on the page, not within one another.
