Skip to content

v2.1.0

Choose a tag to compare

@metonym metonym released this 05 Jul 02:01
· 46 commits to master since this release
v2.1.0
d71bc8b

Features

  • Add intersectAttachment, an attachment (Svelte 5.29+) equivalent of the intersect action, wrapping it via svelte/attachments's fromAction

Usage guide

intersectAttachment attachment

As of Svelte 5.29, attachments are the preferred replacement for actions. intersectAttachment wraps the intersect action with svelte/attachments's fromAction, reusing the same observer logic but plugging into {@attach ...} instead of use:.

<script>
  import { intersectAttachment } from "svelte-intersection-observer";

  let intersecting = $state(false);
</script>

<header class:intersecting>
  {intersecting ? "Element is in view" : "Element is not in view"}
</header>

<div
  {@attach intersectAttachment(() => ({ once: true }))}
  onobserve={(e) => (intersecting = e.detail.isIntersecting)}
>
  Hello world
</div>

Note: unlike use:intersect, which takes the options object directly, intersectAttachment takes a function that returns the options object (this is how fromAction tracks reactive dependencies).

Choosing between intersect and intersectAttachment

Both wrap the same observer logic and share the same options and dispatched events, so pick whichever fits your codebase. Attachments have a few architectural advantages over actions:

  • No separate update() lifecycle method; they rerun reactively like a $effect
  • Just plain functions, so they're easier to compose and generate dynamically
  • Can be forwarded through components as ordinary props, unlike actions

intersect remains fully supported and unchanged; this is purely additive.

<!-- use:intersect (unchanged) -->
<div
  use:intersect={{ once: true }}
  onobserve={(e) => (intersecting = e.detail.isIntersecting)}
>
  Hello world
</div>

<!-- {@attach intersectAttachment} (new) -->
<div
  {@attach intersectAttachment(() => ({ once: true }))}
  onobserve={(e) => (intersecting = e.detail.isIntersecting)}
>
  Hello world
</div>

Type imports

intersectAttachment shares IntersectActionOptions with intersect — no new type import is needed:

import type { IntersectActionOptions } from "svelte-intersection-observer/intersect.svelte";
import { intersectAttachment } from "svelte-intersection-observer";