---
title: 'Install Unhead on TypeScript Projects'
description: 'Get started with Unhead by installing the dependency to your project.'
navigation:
title: 'Installation'
---
## Introduction
Unhead is built for JavaScript applications that need to manage the head of their document in both server and client-rendered environments.
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.
:FrameworkSelectorMinimal{class="mb-7"}
### Demos
- [StackBlitz - Unhead - Vite + TS SSR](https://stackblitz.com/edit/github-hhxywsb5)
## 1. Install Dependency
Install `unhead`{lang="bash"} dependency to your project.
:ModuleInstall{name="unhead"}
## 2. Setup Client-Side Rendering
To begin with, we'll import the function to initialize Unhead in our _client_ app from `unhead/client`{lang="bash"}.
In Vite this entry file is typically named `entry-client.ts`{lang="bash"}. If you're not server-side rendering, you can add this to your main app entry instead.
```ts {4,6} [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.
::note
Follow the [Wrapping Composables](/docs/typescript/guides/wrapping-composables) guide for the recommended way to handle context.
::
## 3. Setup Server-Side Rendering (optional)
::note
Serving your app as an SPA? You can [skip](#4-your-first-tags) this step.
::
Somewhere in your server entry, create a server head instance.
```ts {2,6-8} [main.ts]
import { createHead } from 'unhead/server'
import typescriptLogo from './typescript.svg'
export function render(_url: string) {
const head = createHead()
const 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()`{lang="ts"}.
```ts {1,9-13} [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(``, rendered.html ?? '')
)
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
}
catch (e) {
// ...
}
})
// ..
```
### 4. Your First 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.
- ``
- ``
- ``
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.
```ts {2,6-8} [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 = ``
return { html, head }
}
```
Here is an example of how you can use `useHead()`{lang="ts"} in your app for a counter:
```ts [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)
}
```
### Next Steps
Your app is now setup for head management, congrats! 🎉
Try next:
1. Learn more about app context in the [Wrapping Composables](/docs/typescript/guides/wrapping-composables) guide
2. Consider using the [Vite plugin](/addons/vite-plugin)