---
title: "Reactivity in Svelte"
description: "Use Svelte 5 $state() and $effect() with useHead() for reactive head tags. Use patch() to update entries."
canonical_url: "https://unhead.unjs.io/docs/svelte/head/guides/core-concepts/reactivity"
last_updated: "2026-07-20T12:13:14.986Z"
---

In Svelte 5, create one entry with `useHead()` and patch it from an `$effect()` that reads your `$state()` values.

<note>

[Svelte effects run only in the browser](https://svelte.dev/docs/svelte/$effect). Pass initial values to `useHead()` when tags must appear in the server response, then use an effect to patch later client-side changes.

</note>

## Svelte Integration

The adapter reads the head instance from Svelte context. Each component can create an entry; the adapter disposes it with `onDestroy()` in the browser.

## Reactive Head Tags

Svelte tracks the state read synchronously inside an effect and reruns it when that state changes. Use two steps:

1. Initialize a head entry using `useHead()`
2. Use the returned `patch()` function within a Svelte `$effect` to update when state changes

### Basic Pattern

```svelte
<script lang="ts">
import { useHead } from '@unhead/svelte'

// Reactive state
let title = $state('My Page Title')

// Create a head entry instance
const entry = useHead({
  title,
  meta: [{ name: 'description', content: `Description for ${title}` }],
})

// Set up the reactive effect
$effect(() => {
  entry.patch({
    title,
    meta: [
      { name: 'description', content: `Description for ${title}` }
    ]
  })
})

function updateTitle() {
  title = 'Updated Title'
}
</script>

<button onclick={updateTitle}>Update Title</button>
```

## Entry Lifecycle

### Initialize Once, Patch Often

Create the head entry once, outside of the effect, and use `patch()` within the effect:

```svelte
// ✅ Good: Create entry once
const entry = useHead()

$effect(() => {
  entry.patch({ title })
})

// ❌ Avoid: Creating new entry on each update
$effect(() => {
  useHead({ title })
})
```

Creating the entry outside the effect avoids adding another entry on every update.

### Component Cleanup

The adapter disposes the entry from Svelte's `onDestroy` hook.

## Advanced Usage

### Multiple Components

When multiple components modify the same head properties, Unhead handles priorities based on mount order (later components have higher priority):

```svelte
<!-- ComponentA.svelte -->
<script>
import { useHead } from '@unhead/svelte'

let count = $state(0)
const entry = useHead()

$effect(() => {
  entry.patch({
    title: `Count A: ${count}`
  })
})
</script>

<!-- ComponentB.svelte -->
<script>
import { useHead } from '@unhead/svelte'

let count = $state(0)
const entry = useHead()

$effect(() => {
  entry.patch({
    title: `Count B: ${count}`
  })
})
</script>
```

If both components are mounted, ComponentB wins because it mounted last.

### Other Composables

The same reactivity pattern applies to other Unhead composables:

```svelte
<script>
import { useSeoMeta } from '@unhead/svelte'

let title = $state('My Page')
let description = $state('Page description')

const entry = useSeoMeta()

$effect(() => {
  entry.patch({
    title,
    description
  })
})
</script>
```
