--- title: "entries:normalize Hook" description: "Learn about the entries:normalize hook in Unhead that processes each entry before converting it to tags" navigation: title: "entries:normalize" --- 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 ```ts export interface Hook { 'entries:normalize': (ctx: { tags: HeadTag[], entry: HeadEntry<any> }) => HookResult } ``` ### Parameters | Name | Type | Description | |------|------|-------------| | `ctx` | Object | Context containing the tags and the entry being processed | | `ctx.tags` | `HeadTag[]` | Array of tags generated from the entry | | `ctx.entry` | `HeadEntry<any>` | The head entry being normalized | ### Returns `HookResult` which is either `void` or `Promise<void>` ## Usage Example ```ts import { createHead } from '@unhead/dynamic-import' 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: ```ts import { defineHeadPlugin } from '@unhead/dynamic-import' 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: ```ts import { defineHeadPlugin } from '@unhead/dynamic-import' 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: ```ts import { defineHeadPlugin } from '@unhead/dynamic-import' 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') } } } }) ```