A Svelte 5 component that lets you render some children into a different part of the DOM.
npm install @jsrob/svelte-portal
To create a portal, use the <Portal>
component and pass in a target and children:
<script>
import { Portal } from '@jsrob/svelte-portal';
</script>
<Portal target="body">
<p>This child is placed in the document body.</p>
</Portal>
Another example, a modal that is rendered into the body when a button is clicked:
<script>
import { Portal } from '@jsrob/svelte-portal';
let open = $state(false);
</script>
<button onclick={() => (open = true)}>Open Modal</button>
<Portal target="body">
{#if open}
<div class="modal">
<p>Hello from the modal!</p>
<button onclick={() => (open = false)}>Close</button>
</div>
{/if}
</Portal>
<style>
.modal {
position: fixed;
z-index: 999;
top: 20%;
left: 50%;
width: 300px;
margin-left: -150px;
}
</style>
You can also pass components as children:
<script>
import { Portal } from '@jsrob/svelte-portal';
import Component from './Component.svelte';
</script>
<Portal target="#element">
<Component />
</Portal>
All props can be changed dynamically.
Prop | Type | Description | Required |
---|---|---|---|
target |
string | HTMLElement |
Specify target container. Can either be a selector or an actual element. | Yes |
disabled |
boolean |
When true , the content will remain in its original location instead of moved into the target container. |
No |
When updating the target
or disabled
prop value, components in the default snippet are unmounted and re-mounted, which means any changes to their local state are lost.
If you need to persist state, use some sort of state management.
MIT