useServerHead()
useServer* composables (including useServerHead, useServerSeoMeta, etc.) are deprecated.
Use useHead() with import.meta.server conditionals instead, as described in the Bundle Optimizations guide.Modern Alternative
Instead of using the deprecated useServerHead, use the useHead() composable with environment conditionals:
import { useHead } from '@unhead/angular'
// Only runs on the server
if (import.meta.server) {
useHead({
title: 'My Page',
meta: [
{
name: 'description',
content: 'My page description',
},
],
})
}
Or use the mode option for more declarative code:
import { useHead } from '@unhead/angular'
useHead({
title: 'My Page',
meta: [
{
name: 'description',
content: 'My page description',
},
],
}, { mode: 'server' })
For a complete guide on optimizing your bundle with server and client-only tags, see the Bundle Optimizations guide.
Use Cases for Server-Only Tags
Server-only tags are beneficial in several scenarios:
- Performance optimization: Reduces client-side JavaScript bundle size
- SEO focus: Most search engines only read the initial HTML response
- Server-specific resources: Enables use of tags with values only available during server rendering
Safe Usage with Untrusted Data
When working with user-generated content, use the safe option to ensure proper sanitization:
import { useHead } from '@unhead/angular'
useHead({
title: userProvidedTitle,
meta: [
{
name: 'description',
content: userProvidedDescription,
},
],
}, {
mode: 'server',
// Enable sanitization for user-provided content
safe: true
})
Tree Shaking
Server-only tags can be tree-shaken from your client bundle in most frameworks when using the recommended approach:
- Import.meta conditionals: Code inside
if (import.meta.server)blocks is automatically tree-shaken - Mode option: When using
{ mode: 'server' }, most bundlers can optimize this - Additional optimization: Use the Unhead Vite Plugin for enhanced tree-shaking
Important Considerations
No Lifecycle Events
Server-rendered tags do not have lifecycle events. If you use server-rendered tags on a specific page, they won't be automatically removed when navigating away from that page.
Tag Persistence
Consider this example:
// pages/about.vue
if (import.meta.server) {
useHead({
meta: [
{
name: 'description',
content: 'About page description',
},
],
})
}
When this page is server-rendered, the meta tag is included in the HTML. However, when you navigate from /about to another page, the tag will remain in the document <head> because there's no client-side code to remove it.
Solutions for Tag Management
To manage server-rendered tags effectively:
- Add keys to all tags: Use the
keyproperty to enable replacement - Use in app root only: Place server-only tags in root components for app-wide metadata
- Manual cleanup: Register empty tags with matching keys on other pages to remove them
- Prefer client tags: Use regular
useHead()without mode restrictions for page-specific tags that need to change with navigation
Working Example: Managing Page-Specific Scripts
This pattern demonstrates how to add a page-specific script and properly remove it when navigating away:
// pages/about.vue
import { useHead } from '@unhead/angular'
if (import.meta.server) {
useHead({
script: [
{
src: await import('~/assets/js/about.js?url'),
key: 'page-script'
}
]
})
}
// pages/contact.vue
import { useHead } from '@unhead/angular'
useHead({
script: [
{
// This removes the script when navigating to this page
key: 'page-script'
}
]
})
Best Practices
- Use server-only tags primarily for static metadata that doesn't change between pages
- Always add keys to server-rendered tags that might need to be replaced later
- Use
useHead()with environment conditionals instead of legacyuseServer*composables - Test navigation flows to ensure proper tag management
For complete documentation on bundle optimization strategies, see the Bundle Optimizations guide.