{@attach ...}
Attachments are functions that run when an element is mounted to the DOM. Optionally, they can return a function that is called when the element is later removed from the DOM.
Attachments are available in Svelte 5.29 and newer.
<script>
/** @type {import('svelte/attachments').Attachment} */
function myAttachment(element) {
console.log(element.nodeName); // 'DIV'
return () => {
console.log('cleaning up');
};
}
</script>
<div {@attach myAttachment}>...</div>
<script lang="ts">
import type { Attachment } from 'svelte/attachments';
const myAttachment: Attachment = (element) => {
console.log(element.nodeName); // 'DIV'
return () => {
console.log('cleaning up');
};
};
</script>
<div {@attach myAttachment}>...</div>
An element can have any number of attachments.
Attachment factories
A useful pattern is for a function, such as tooltip
in this example, to return an attachment (demo):
<script>
import tippy from 'tippy.js';
let content = $state('Hello!');
/**
* @param {string} content
* @returns {import('svelte/attachments').Attachment}
*/
function tooltip(content) {
return (element) => {
const tooltip = tippy(element, { content });
return tooltip.destroy;
};
}
</script>
<input bind:value={content} />
<button {@attach tooltip(content)}>
Hover me
</button>
<script lang="ts">
import tippy from 'tippy.js';
import type { Attachment } from 'svelte/attachments';
let content = $state('Hello!');
function tooltip(content: string): Attachment {
return (element) => {
const tooltip = tippy(element, { content });
return tooltip.destroy;
};
}
</script>
<input bind:value={content} />
<button {@attach tooltip(content)}>
Hover me
</button>
Since the tooltip(content)
expression runs inside an effect, the attachment will be destroyed and recreated whenever content
changes.
Inline attachments
Attachments can also be created inline (demo):
<script>
import { paint } from './gradient.js';
</script>
<canvas
width={32}
height={32}
{@attach (canvas) => {
const context = canvas.getContext('2d');
$effect(() => {
let frame = requestAnimationFrame(function loop(t) {
frame = requestAnimationFrame(loop);
paint(context, t);
});
return () => {
cancelAnimationFrame(frame);
};
});
}}
></canvas>
<script lang="ts">
import { paint } from './gradient.js';
</script>
<canvas
width={32}
height={32}
{@attach (canvas) => {
const context = canvas.getContext('2d');
$effect(() => {
let frame = requestAnimationFrame(function loop(t) {
frame = requestAnimationFrame(loop);
paint(context, t);
});
return () => {
cancelAnimationFrame(frame);
};
});
}}
></canvas>
Passing attachments to components
When used on a component, {@attach ...}
will create a prop whose key is a Symbol
. If the component then spreads props onto an element, the element will receive those attachments.
This allows you to create wrapper components that augment elements (demo):
<script>
/** @type {import('svelte/elements').HTMLButtonAttributes} */
let { children, ...props } = $props();
</script>
<!-- `props` includes attachments -->
<button {...props}>
{@render children?.()}
</button>
<script lang="ts">
import type { HTMLButtonAttributes } from 'svelte/elements';
let { children, ...props }: HTMLButtonAttributes = $props();
</script>
<!-- `props` includes attachments -->
<button {...props}>
{@render children?.()}
</button>
<script>
import tippy from 'tippy.js';
import Button from './Button.svelte';
let content = $state('Hello!');
/**
* @param {string} content
* @returns {import('svelte/attachments').Attachment}
*/
function tooltip(content) {
return (element) => {
const tooltip = tippy(element, { content });
return tooltip.destroy;
};
}
</script>
<input bind:value={content} />
<Button {@attach tooltip(content)}>
Hover me
</Button>
<script lang="ts">
import tippy from 'tippy.js';
import Button from './Button.svelte';
import type { Attachment } from 'svelte/attachments';
let content = $state('Hello!');
function tooltip(content: string): Attachment {
return (element) => {
const tooltip = tippy(element, { content });
return tooltip.destroy;
};
}
</script>
<input bind:value={content} />
<Button {@attach tooltip(content)}>
Hover me
</Button>
Creating attachments programmatically
To add attachments to an object that will be spread onto a component or element, use createAttachmentKey
.
Edit this page on GitHub llms.txt