---
title: "useHeadSafe() · v2 · Unhead"
meta:
  "og:description": "API reference for the useHeadSafe composable that provides security features for head tags."
  "og:title": "useHeadSafe() · v2 · Unhead"
  description: "API reference for the useHeadSafe composable that provides security features for head tags."
---

**Composables**

# **useHeadSafe()**

**On this page **

- [How It Works](#how-it-works)
- [API Reference](#api-reference)
- [Examples](#examples)
- [Security Considerations](#security-considerations)
- [Common Use Cases](#common-use-cases)
- [Common Questions](#common-questions)
- [See Also](#see-also)

The `useHeadSafe` composable is a security-focused wrapper around the [**useHead**](https://unhead.unjs.io/docs/v2/head/api/composables/use-head) composable that restricts input to only allow safe values, providing protection against XSS attacks when working with untrusted content.

**Quick Start:**

```
useHeadSafe({
  title: userInput.title, // Automatically sanitized
  meta: [{ name: 'description', content: userInput.description }]
})
```

## [How It Works](#how-it-works)

The composable implements a strict whitelist of allowed tags and attributes. When you attempt to use a tag or attribute that isn't on the whitelist, it will be silently ignored to prevent potential security issues.

The whitelist is intentionally restrictive since there are many vectors for XSS attacks. If you need to use a tag or attribute that isn't on the whitelist, you can use the [**useHead**](https://unhead.unjs.io/docs/v2/head/api/composables/use-head) composable instead, but **you must sanitize the input yourself**.

### [Security Whitelist](#security-whitelist)

The security whitelist specifies which attributes are allowed for each tag type:

```
import { useHeadSafe } from '#imports'

// The whitelist used internally by useHeadSafe
const WhitelistAttributes = {
  htmlAttrs: ['class', 'style', 'lang', 'dir'] satisfies (keyof HtmlAttributes)[],
  bodyAttrs: ['class', 'style'] satisfies (keyof BodyAttributes)[],
  meta: ['name', 'property', 'charset', 'content', 'media'] satisfies (keyof Meta)[],
  noscript: ['textContent'] satisfies (Partial<keyof Noscript> | 'textContent')[],
  style: ['media', 'textContent', 'nonce', 'title', 'blocking'] satisfies (Partial<keyof Style> | 'textContent')[],
  script: ['type', 'textContent', 'nonce', 'blocking'] satisfies (Partial<keyof Script> | 'textContent')[],
  link: ['color', 'crossorigin', 'fetchpriority', 'href', 'hreflang', 'imagesrcset', 'imagesizes', 'integrity', 'media', 'referrerpolicy', 'rel', 'sizes', 'type'] satisfies (keyof Link)[],
} as const
```

### [Additional Restrictions](#additional-restrictions)

The following security restrictions also apply:

- Scripts of any sort are not allowed, except for JSON (`<script type="application/json">`) - use `textContent: myObject`
- `http-equiv` attribute is not allowed on meta tags
- `data-*` attributes are allowed on all elements
- Link tags will strip invalid href values (like `data:`, `javascript:`)
- Link tags don't support these rel values: `['stylesheet', 'canonical', 'modulepreload', 'prerender', 'preload', 'prefetch']`

## [API Reference](#api-reference)

```
function useHeadSafe(input: UseHeadInput, options?: HeadEntryOptions): ActiveHeadEntry
```

The API signature is identical to [**useHead**](https://unhead.unjs.io/docs/v2/head/api/composables/use-head), but with additional security filtering applied to the input.

## [Examples](#examples)

### [Handling Untrusted Data](#handling-untrusted-data)

When working with head data from an untrusted data source:

```
import { useHeadSafe } from '#imports'

// Load metadata from a third-party source
const thirdPartyMeta = loadMeta()

// Safely apply the metadata
useHeadSafe(thirdPartyMeta)
```

### [User-Generated Content](#user-generated-content)

When allowing users to provide custom meta tags:

```
import { useHeadSafe } from '#imports'

// User profile with user-defined metadata
const userProfile = await fetchUserProfile(userId)

useHeadSafe({
  title: userProfile.pageTitle,
  meta: [
    { name: 'description', content: userProfile.pageDescription },
    ...userProfile.customMetaTags // These will be filtered for safety
  ]
})
```

## [Security Considerations](#security-considerations)

While `useHeadSafe` offers protection for most XSS vectors, there are still some important security considerations:

### [Styles](#styles)

While style attributes are permitted, it's important to note that [**clickjacking**](https://en.wikipedia.org/wiki/Clickjacking) vulnerabilities can still be introduced through malicious CSS. Always validate style content even when using `useHeadSafe`.

### [Best Practices](#best-practices)

For maximum security when handling untrusted content:

1. Apply additional validation to any user inputs before passing to `useHeadSafe`
2. Consider using a dedicated content security policy (CSP)
3. Use the built-in sanitization but don't rely on it as your only defense
4. Avoid allowing custom styles when possible with untrusted content

## [Common Use Cases](#common-use-cases)

- Working with user-generated content
- Displaying metadata from third-party APIs
- Creating CMS systems where content editors can customize SEO fields
- Implementing white-label solutions where customers can customize branding

## [Common Questions](#common-questions)

### [When should I use useHeadSafe instead of useHead?](#when-should-i-use-useheadsafe-instead-of-usehead)

Use `useHeadSafe()` whenever you're working with untrusted or user-provided input to prevent XSS attacks.

### [What gets sanitized?](#what-gets-sanitized)

All string values are HTML-escaped. Script tags and event handlers are stripped. Only safe attributes are allowed.

## [See Also](#see-also)

- [**useHead()**](https://unhead.unjs.io/docs/v2/head/api/composables/use-head) - General head management
- [**useSeoMeta()**](https://unhead.unjs.io/docs/v2/head/api/composables/use-seo-meta) - SEO meta tags
- [**Security Considerations**](https://unhead.unjs.io/docs/v2/head/api/composables/use-head#security-considerations)

[Edit this page](https://github.com/unjs/unhead/edit/v2.1.2/docs/v2/head/7.api/composables/1.use-head-safe.md)

**Did this page help you? **

[**useHead()** API reference for the useHead composable.](https://unhead.unjs.io/docs/v2/head/api/composables/use-head) [**useSeoMeta()** The simplest way to add SEO meta tags to your site with full TypeScript support](https://unhead.unjs.io/docs/v2/head/api/composables/use-seo-meta)

**On this page **

- [How It Works](#how-it-works)
- [API Reference](#api-reference)
- [Examples](#examples)
- [Security Considerations](#security-considerations)
- [Common Use Cases](#common-use-cases)
- [Common Questions](#common-questions)
- [See Also](#see-also)