---
title: "ssr:render Hook"
description: "Hook for changing resolved tags and per-render serialization options during SSR."
canonical_url: "https://unhead.unjs.io/docs/head/api/hooks/ssr-render"
last_updated: "2026-08-11T00:39:05.751Z"
---

The `ssr:render` hook runs after tags have been resolved and immediately before they are serialized into an `SSRHeadPayload`.

## Hook Signature

```ts
export interface Hook {
  'ssr:render': (ctx: {
    tags: HeadTag[]
    options: RenderSSRHeadOptions
  }) => HookResult
}
```

### Parameters

<table>
<thead>
  <tr>
    <th>
      Name
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        ctx.tags
      </code>
    </td>
    
    <td>
      <code>
        HeadTag[]
      </code>
    </td>
    
    <td>
      Sanitized tags selected for this render
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ctx.options
      </code>
    </td>
    
    <td>
      <code>
        RenderSSRHeadOptions
      </code>
    </td>
    
    <td>
      Fresh copy of the renderer options for this render
    </td>
  </tr>
</tbody>
</table>

`RenderSSRHeadOptions` includes `omitLineBreaks`, `resolvedTags`, and `tagWeight`. At this stage, `resolvedTags` and `tagWeight` have already been used to select and order `ctx.tags`; changing them has no effect on the current render. Changing `omitLineBreaks` affects serialization.

Although the hook type permits a promise, serialization starts immediately after the hook call. Keep this hook synchronous.

## Usage Example

```ts
import { defineHeadPlugin } from '@unhead/dynamic-import/plugins'

export const ssrReportPlugin = defineHeadPlugin({
  key: 'ssr-report',
  hooks: {
    'ssr:render': ({ tags }) => {
      console.log(`Serializing ${tags.length} head tags`)
    }
  }
})
```

Use [`MinifyPlugin`](/docs/head/guides/plugins/minify) instead of setting `omitLineBreaks` directly when you also want to minify inline JavaScript, CSS, or JSON.
