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/solid-js'
// 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/solid-js'
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/solid-js'
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
key
property 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/solid-js'
if (import.meta.server) {
useHead({
script: [
{
src: await import('~/assets/js/about.js?url'),
key: 'page-script'
}
]
})
}
// pages/contact.vue
import { useHead } from '@unhead/solid-js'
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.