Svelte
Hooks

entries:normalize Hook

The entries:normalize hook is called for each entry when it's being normalized into tags. This hook gives you access to the tags generated from a specific entry, allowing you to transform, add, or remove tags on a per-entry basis.

Hook Signature

export interface Hook {
  'entries:normalize': (ctx: { tags: HeadTag[], entry: HeadEntry<any> }) => HookResult
}

Parameters

NameTypeDescription
ctxObjectContext containing the tags and the entry being processed
ctx.tagsHeadTag[]Array of tags generated from the entry
ctx.entryHeadEntry<any>The head entry being normalized

Returns

HookResult which is either void or Promise<void>

Usage Example

import { createHead } from '@unhead/svelte'

const head = createHead({
  hooks: {
    'entries:normalize': (ctx) => {
      // Log the entry being normalized
      console.log('Normalizing entry:', ctx.entry._i)

      // Modify tags from this specific entry
      ctx.tags.forEach((tag) => {
        if (tag.tag === 'meta' && tag.props.name === 'description') {
          // Modify description meta tag content
          tag.props.content += ' (processed by normalize hook)'
        }
      })
    }
  }
})

Use Cases

Adding Entry-specific Attributes

You can use this hook to add specific attributes based on entry properties:

import { defineHeadPlugin } from '@unhead/svelte'

export const entrySourcePlugin = defineHeadPlugin({
  hooks: {
    'entries:normalize': (ctx) => {
      // Add a data attribute to all tags from this entry to track source
      ctx.tags.forEach((tag) => {
        if (tag.props && typeof tag.props === 'object') {
          // Store the component or source that created this entry
          tag.props['data-source'] = ctx.entry.options.source || 'unknown'
        }
      })
    }
  }
})

Conditional Tag Modification

This hook is useful for modifying tags conditionally based on the entry:

import { defineHeadPlugin } from '@unhead/svelte'

export const developmentInformationPlugin = defineHeadPlugin({
  hooks: {
    'entries:normalize': (ctx) => {
      // Only in development mode
      if (process.env.NODE_ENV === 'development') {
        // Add a custom comment to help with debugging
        ctx.tags.push({
          tag: 'comment',
          textContent: `Entry ID: ${ctx.entry._i} from ${ctx.entry.options.source || 'unknown'}`
        })

        // Enhance title tags with entry information
        ctx.tags.forEach((tag) => {
          if (tag.tag === 'title') {
            tag.textContent = `[DEV] ${tag.textContent}`
          }
        })
      }
    }
  }
})

Processing Template Parameters

You can use this hook to detect and process template parameters in entries:

import { defineHeadPlugin } from '@unhead/svelte'

export const templateParamsPlugin = defineHeadPlugin({
  hooks: {
    'entries:normalize': (ctx) => {
      // Extract template parameters from entry
      const params = ctx.tags.find(t => t.tag === 'templateParams')?.props || {}

      if (Object.keys(params).length > 0) {
        // Store params for later processing
        ctx.entry._templateParams = params

        // Remove the templateParams tag as it's not meant for rendering
        ctx.tags = ctx.tags.filter(t => t.tag !== 'templateParams')
      }
    }
  }
})
Did this page help you?