---
title: "Installing Unhead with React · Unhead"
meta:
  "og:description": "Set up Unhead in React with UnheadProvider and useHead() hook. Drop-in replacement for react-helmet with SSR support."
  "og:title": "Installing Unhead with React · Unhead"
  description: "Set up Unhead in React with UnheadProvider and useHead() hook. Drop-in replacement for react-helmet with SSR support."
---

**Get Started**

# **Installing Unhead with React**

[Copy for LLMs](https://raw.githubusercontent.com/unjs/unhead/refs/heads/main/docs/0.react/head/guides/0.get-started/1.installation.md)

Last updated **Jan 29, 2026** by [Harlan Wilton](https://github.com/harlan-zw) in [doc: broken install tag](https://github.com/unjs/unhead/commit/0f03491427a6d90d1ee6221428fd9456c62a2a96).

**On this page **

- [Introduction](#introduction)
- [How Do I Install Unhead in React?](#how-do-i-install-unhead-in-react)
- [Next Steps](#next-steps)

## [Introduction](#introduction)

Unhead has first-class support for React, allowing you to manage your head tags using a `<Head>` component, the `useHead()` hook, and other ecosystem hooks.

It can directly replace [`react-helmet`](https://github.com/nfl/react-helmet), handling a more diverse set of use cases from SEO to structured data.

It's designed to work with any React setup, however this guide assumes you're following a similar structure to the [**Vite: ssr-react-ts**](https://github.com/bluwy/create-vite-extra/tree/master/template-ssr-react-ts) template or a similar SPA setup.

**Quick Start:** Install `@unhead/react`, wrap your app with `UnheadProvider`, and use `useHead()` in components. For SSR, use `transformHtmlTemplate()` to inject head tags.

### [Demos](#demos)

- [**StackBlitz - Unhead - Vite + React SSR**](https://stackblitz.com/edit/github-5hqsxyid)
- [**StackBlitz - Unhead - React SPA**](https://stackblitz.com/edit/vitejs-vite-ggqxj5nx)

## [How Do I Install Unhead in React?](#how-do-i-install-unhead-in-react)

### [1. Add Dependency](#_1-add-dependency)

Install `@unhead/react` dependency to your project.

`pnpm add @unhead/react@next`

### [2. How Do I Set Up Client-Side Rendering?](#_2-how-do-i-set-up-client-side-rendering)

To begin with, we'll import the function to initialize Unhead in our _client_ React app from `@unhead/react/client`.

In Vite this entry file is typically named `entry-client.ts`. If you're not server-side rendering, you can add this to your main React app entry instead.

src/entry-client.ts

```
import { createHead, UnheadProvider } from '@unhead/react/client'
import { StrictMode } from 'react'
import { hydrateRoot } from 'react-dom/client'
import App from './App'
import './index.css'

const head = createHead()

hydrateRoot(
  document.getElementById('root') as HTMLElement,
  <StrictMode>
    <UnheadProvider head={head}>
      <App />
    </UnheadProvider>
  </StrictMode>,
)
```

### [3. How Do I Set Up Server-Side Rendering?](#_3-how-do-i-set-up-server-side-rendering)

Serving your app as an SPA? You can [**skip**](#4-how-do-i-add-head-tags) this step.

Setting up server-side rendering is more complicated as it requires rendering out the tags to the HTML string before sending it to the client.

We'll start with setting up the plugin in the _server_ entry this time. Make sure to import from `@unhead/react/server` instead and add the `head` in the return object.

src/entry-server.ts

```
import { createHead, UnheadProvider } from '@unhead/react/server'
import { StrictMode } from 'react'
import { renderToString } from 'react-dom/server'
import App from './App'

export function render(_url: string) {
  const head = createHead()
  const html = renderToString(
    <StrictMode>
      <UnheadProvider value={head}>
        <App />
      </UnheadProvider>
    </StrictMode>,
  )
  return { html, head }
}
```

Now we need to render out the head tags _after_ React has rendered the app.

Within your `server.js` file or wherever you're handling the template logic, you need to transform the template data for the head tags using `transformHtmlTemplate()`.

server.ts

```
import { transformHtmlTemplate } from '@unhead/react/server'
// ...

// Serve HTML
app.use('*all', async (req, res) => {
  try {
    // ...

    const rendered = await render(url)

    const html = await transformHtmlTemplate(
      rendered.head,
      template.replace(\`<!--app-html-->\`, rendered.html ?? '')
    )

    res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
  }
  catch (e) {
    // ...
  }
})
// ..
```

### [4. How Do I Add Head Tags?](#_4-how-do-i-add-head-tags)

Done! Your app should now be rendering head tags on the server and client.

To improve your apps stability, Unhead will now insert important default tags for you.

- `<meta charset="utf-8">`
- `<meta name="viewport" content="width=device-width, initial-scale=1">`
- `<html lang="en">`

You may need to change these for your app requirements, for example you may want to change the default language. Adding tags in your server entry means you won't add any weight to your client bundle.

src/entry-server.ts

```
import { createHead } from '@unhead/react/server'

export function render(_url: string) {
  const head = createHead({
    // change default initial lang
    init: [
      {
        htmlAttrs: { lang: 'en' },
        title: 'Default title',
        titleTemplate: '%s - My Site',
      },
    ]
  })
  const html = \`<!-- your html -->\`
  return { html, head }
}
```

For adding tags in your components, you can either use the `<Head>` component and the `useHead()` hook.

- `useHead()`: Type safety, more flexible and can access lower level primitives.
- `<Head>`: More declarative and easier to read.

App.tsx

```
import { Head, useHead } from '@unhead/react'

export default function App() {
  // a. use the hook
  useHead({
    title: 'My Awesome Site',
    meta: [
      { name: 'description', content: 'My awesome site description' }
    ]
  })
  // b. use the component
  return (
    <div>
      <Head>
        <title>My Awesome Site</title>
        <meta name="description" content="My awesome site description" />
      </Head>
      <h1>Hello World</h1>
    </div>
  )
}
```

### [5. How Do I Enable Auto-Imports? (Optional)](#_5-how-do-i-enable-auto-imports-optional)

If you're using [**unplugin-auto-import**](https://github.com/antfu/unplugin-auto-import), you can automatically import the composables.

vite.config.ts

```
import { hookImports } from '@unhead/react'
import AutoImport from 'unplugin-auto-import/vite'

export default defineConfig({
  plugins: [
    AutoImport({
      imports: [
        hookImports,
      ],
    }),
    // ...
  ]
})
```

## [Next Steps](#next-steps)

Your React app is now setup for head management, congrats! 🎉

You can get started with any of the hooks or components:

- [`useHead()`](https://unhead.unjs.io/docs/head/api/composables/use-head)
- [`useSeoMeta()`](https://unhead.unjs.io/docs/head/api/composables/use-seo-meta)

If you're coming from `react-helmet`, you can also check out the [**migration guide**](https://unhead.unjs.io/docs/react/head/guides/get-started/migrate-from-react-helmet).

Or explore some of the optional extras:

- Add [`useSchemaOrg()`](https://unhead.unjs.io/docs/schema-org/api/composables/use-schema-org) for structured data
- Use [`useScript()`](https://unhead.unjs.io/docs/head/api/composables/use-script) for performance optimized script loading

[Edit this page](https://github.com/unjs/unhead/edit/main/docs/0.react/head/guides/0.get-started/1.installation.md)

[Markdown For LLMs](https://raw.githubusercontent.com/unjs/unhead/refs/heads/main/docs/0.react/head/guides/0.get-started/1.installation.md)

**Did this page help you? **

[**Vue Components** Schema.org Vue components API (deprecated). Use composables like useSchemaOrg() instead for better TypeScript support.](https://unhead.unjs.io/docs/nuxt/schema-org/guides/core-concepts/vue-components) [**Upgrade Guide** Learn how to migrate between Unhead versions for React users.](https://unhead.unjs.io/docs/react/head/guides/get-started/migration)

**On this page **

- [Introduction](#introduction)
- [How Do I Install Unhead in React?](#how-do-i-install-unhead-in-react)
- [Next Steps](#next-steps)