Install Unhead on TypeScript Projects · Unhead

[Unhead Home](https://unhead.unjs.io/ "Home")

- [Docs](https://unhead.unjs.io/docs/typescript/head/guides/get-started/overview)
- [Tools](https://unhead.unjs.io/tools)
- [Learn](https://unhead.unjs.io/learn/guides/what-is-capo)

[Releases](https://unhead.unjs.io/releases)

Search…```k`` /`

[Unhead on GitHub](https://github.com/unjs/unhead)

[User Guides](https://unhead.unjs.io/docs/typescript/head/guides/get-started/overview)

[API](https://unhead.unjs.io/docs/typescript/head/api/get-started/overview)

[Releases](https://unhead.unjs.io/docs/typescript/releases/v3)

TypeScript

- [Switch to TypeScript](https://unhead.unjs.io/docs/typescript/head/guides/get-started/installation)
- [Switch to Vue](https://unhead.unjs.io/docs/vue/head/guides/get-started/installation)
- [Switch to React](https://unhead.unjs.io/docs/react/head/guides/get-started/installation)
- [Switch to Svelte](https://unhead.unjs.io/docs/svelte/head/guides/get-started/installation)
- [Switch to Solid.js](https://unhead.unjs.io/docs/solid-js/head/guides/get-started/installation)
- [Switch to Angular](https://unhead.unjs.io/docs/angular/head/guides/get-started/installation)
- [Switch to Nuxt](https://unhead.unjs.io/docs/nuxt/head/guides/get-started/installation)

v3 (stable)

Head

- [Discord Support](https://discord.com/invite/275MBUBvgP)
- [TypeScript Playground](https://stackblitz.com/edit/github-hhxywsb5)

- Get Started
  - [Overview](https://unhead.unjs.io/docs/typescript/head/guides/get-started/overview)
  - [Introduction to Unhead](https://unhead.unjs.io/docs/typescript/head/guides/get-started/intro-to-unhead)
  - [Starter Recipes](https://unhead.unjs.io/docs/typescript/head/guides/get-started/starter-recipes)
  - [Installation](https://unhead.unjs.io/docs/typescript/head/guides/get-started/installation)
- Core Concepts
  - [Titles & Title Templates](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/titles)
  - [Tag Sorting & Placement](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/positions)
  - [Class & Style Attributes](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/class-attr)
  - [Inline Style & Scripts](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/inner-content)
  - [Tag Deduplication](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/handling-duplicates)
  - [DOM Event Handling](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/dom-event-handling)
  - [Script Loading](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/loading-scripts)
  - [Wrapping Composables](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/wrapping-composables)
  - [StreamingNew](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/streaming)
- Build Plugins
  - [Overview](https://unhead.unjs.io/docs/typescript/head/guides/build-plugins/overview)
  - [Tree-Shaking](https://unhead.unjs.io/docs/typescript/head/guides/build-plugins/tree-shaking)
  - [useSeoMeta Transform](https://unhead.unjs.io/docs/typescript/head/guides/build-plugins/seo-meta-transform)
  - [Minify Transform](https://unhead.unjs.io/docs/typescript/head/guides/build-plugins/minify-transform)
  - [Devtools](https://unhead.unjs.io/docs/typescript/head/guides/build-plugins/devtools)
- Plugins
  - [Template Params](https://unhead.unjs.io/docs/typescript/head/guides/plugins/template-params)
  - [Alias Sorting](https://unhead.unjs.io/docs/typescript/head/guides/plugins/alias-sorting)
  - [Canonical Plugin](https://unhead.unjs.io/docs/typescript/head/guides/plugins/canonical)
  - [Infer SEO Meta](https://unhead.unjs.io/docs/typescript/head/guides/plugins/infer-seo-meta-tags)
  - [Minify](https://unhead.unjs.io/docs/typescript/head/guides/plugins/minify)
  - [Validate](https://unhead.unjs.io/docs/typescript/head/guides/plugins/validate)

Get Started

# Install Unhead on TypeScript Projects

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

Last updated Apr 9, 2026 by [Harlan Wilton](https://github.com/harlan-zw) in [refactor(bundler)!: named Unhead export, ctx-based transforms, dev-mode validate (#733)](https://github.com/unjs/unhead/pull/733).

On this page

- [Introduction](#introduction)
- [How do I install Unhead?](#how-do-i-install-unhead)
- [How do I setup client-side rendering?](#how-do-i-setup-client-side-rendering)
- [How do I setup server-side rendering?](#how-do-i-setup-server-side-rendering)
- [How do I add my first head tags?](#how-do-i-add-my-first-head-tags)
- [What should I do next?](#what-should-i-do-next)

## [Introduction](#introduction)

Unhead is built for JavaScript applications that need to manage the head of their document in both server and client-rendered environments.

**Quick Start:** Install `unhead`, create head with `createHead()`, and use `useHead()` directly. For SSR, use separate client/server instances with `renderSSRHead()`.

This guide is for installing Unhead with just TypeScript and no framework. Using a JavaScript framework? Select your framework below or continue with the TypeScript setup below.

- [Switch to TypeScript](https://unhead.unjs.io/docs/typescript/head/guides/get-started/installation)
- [Switch to Vue](https://unhead.unjs.io/docs/vue/head/guides/get-started/installation)
- [Switch to React](https://unhead.unjs.io/docs/react/head/guides/get-started/installation)
- [Switch to Svelte](https://unhead.unjs.io/docs/svelte/head/guides/get-started/installation)
- [Switch to Solid.js](https://unhead.unjs.io/docs/solid-js/head/guides/get-started/installation)
- [Switch to Angular](https://unhead.unjs.io/docs/angular/head/guides/get-started/installation)
- [Switch to Nuxt](https://unhead.unjs.io/docs/nuxt/head/guides/get-started/installation)

### [Demos](#demos)

- [StackBlitz - Unhead - Vite + TS SSR](https://stackblitz.com/edit/github-hhxywsb5)

## [How do I install Unhead?](#how-do-i-install-unhead)

Install `unhead` dependency to your project.

pnpm

bun

npm

yarn

bash

`pnpm add unhead@next`

> !TIP Generate an Agent Skill for this package using [skilld](https://github.com/harlan-zw/skilld):```
npx skilld add unhead
```
## [How do I setup client-side rendering?](#how-do-i-setup-client-side-rendering)

To begin with, we'll import the function to initialize Unhead in our _client_ app from `unhead/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 app entry instead.

entry-client.ts

```
import { createHead } from 'unhead/client'
import { setupCounter } from './counter'
import './style.css'
import './typescript.svg'

window.__UNHEAD__ = createHead()

setupCounter(document.querySelector('#counter') as HTMLButtonElement)
```

In the above example we are attaching the head instance to the global window object. While hacky, this is useful for when you need to access the head instance in other parts of your app.

Follow the [Wrapping Composables](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/wrapping-composables) guide for the recommended way to handle context.

## [How do I setup server-side rendering?](#how-do-i-setup-server-side-rendering)

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

Somewhere in your server entry, create a server head instance.

main.ts

```
import { createHead } from 'unhead/server'
import typescriptLogo from './typescript.svg'

export function render(_url: string) {
  const head = createHead()
  const html = \`<!-- your html -->\`
  return { html, head }
}
```

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/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) {
    // ...
  }
})
// ..
```

## [How do I add my first head tags?](#how-do-i-add-my-first-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.

main.ts

```
import { createHead } from 'unhead/server'
import typescriptLogo from './typescript.svg'

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

Here is an example of how you can use `useHead()` in your app for a counter:

counter.ts

```
import { useHead } from 'unhead'

export function setupCounter(element: HTMLButtonElement) {
  let counter = 0
  const setCounter = (count: number) => {
    counter = count
    element.innerHTML = \`count is ${counter}\`
    useHead(window.__UNHEAD__, {
      title: () => counter ? \`count is ${counter}\` : null,
    })
  }
  element.addEventListener('click', () => setCounter(counter + 1))
  setCounter(0)
}
```

## [What should I do next?](#what-should-i-do-next)

Your app is now setup for head management, congrats!

Try next:

1. Learn more about app context in the [Wrapping Composables](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/wrapping-composables) guide
2. Consider using the [Vite plugin](https://unhead.unjs.io/docs/head/guides/build-plugins/overview)

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

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

Did this page help you?

[Installation Add Schema.org to Svelte apps with @unhead/schema-org. Setup defineWebSite(), defineWebPage() for Google Rich Results.](https://unhead.unjs.io/docs/svelte/schema-org/guides/get-started/installation) [Wrapping Composables Learn how to create custom head composables by wrapping useHead with your own defaults and context management.](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/wrapping-composables)

On this page

- [Introduction](#introduction)
- [How do I install Unhead?](#how-do-i-install-unhead)
- [How do I setup client-side rendering?](#how-do-i-setup-client-side-rendering)
- [How do I setup server-side rendering?](#how-do-i-setup-server-side-rendering)
- [How do I add my first head tags?](#how-do-i-add-my-first-head-tags)
- [What should I do next?](#what-should-i-do-next)

[GitHub](https://github.com/unjs/unhead) [ Discord](https://discord.com/invite/275MBUBvgP)

[ /llms.txt](https://unhead.unjs.io/llms.txt)

[Part of the UnJS ecosystem](https://unjs.io/)

### Head Management

- [Getting Started](https://unhead.unjs.io/docs/typescript/head/guides/get-started/overview)
- [useHead](https://unhead.unjs.io/docs/typescript/head/api/composables/use-head)
- [useSeoMeta](https://unhead.unjs.io/docs/typescript/head/api/composables/use-seo-meta)
- [useHeadSafe](https://unhead.unjs.io/docs/typescript/head/api/composables/use-head-safe)
- [useScript](https://unhead.unjs.io/docs/typescript/head/api/composables/use-script)

### Schema.org

- [Getting Started](https://unhead.unjs.io/docs/typescript/schema-org/guides/get-started/overview)
- [useSchemaOrg](https://unhead.unjs.io/docs/typescript/schema-org/api/composables/use-schema-org)
- [Nodes](https://unhead.unjs.io/docs/typescript/schema-org/guides/core-concepts/nodes)
- [Recipes](https://unhead.unjs.io/docs/typescript/schema-org/guides/recipes/identity)

### Guides

- [Titles](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/titles)
- [Streaming SSR](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/streaming)
- [DOM Events](https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/dom-event-handling)
- [Plugins](https://unhead.unjs.io/docs/typescript/head/guides/plugins/template-params)

### Tools

- [Meta Tag Generator](https://unhead.unjs.io/tools/meta-tag-generator)
- [OG Image Generator](https://unhead.unjs.io/tools/og-image-generator)
- [Schema.org Generator](https://unhead.unjs.io/tools/schema-generator)
- [Capo.js Analyzer](https://unhead.unjs.io/tools/capo-analyzer)

### Articles

- [What is Capo.js?](https://unhead.unjs.io/learn/guides/what-is-capo)

### Research

- [State of <head> in 2026](https://unhead.unjs.io/learn/research/state-of-head-2026)
- [Streaming Head Performance](https://unhead.unjs.io/learn/research/streaming-head-performance)
- [Capo.js Performance Research](https://unhead.unjs.io/learn/research/capo-performance-research)

Copyright © 2025-2026 Harlan Wilton - [MIT License](https://github.com/unjs/unhead/blob/main/license)