What Causes This Warning?
This warning appears when you import head management functions directly from @unhead/vue instead of using Nuxt’s auto-imported composables. Nuxt provides these functions automatically with proper integration.
The Problem
<script setup>
// ❌ Wrong - direct import
import { useHead, useSeoMeta } from '@unhead/vue'
useHead({
title: 'My Page'
})
</script>
The Fix
Use Auto-Imports
<script setup>
// ✅ Correct - no import needed, auto-imported by Nuxt
useHead({
title: 'My Page'
})
useSeoMeta({
title: 'My Page',
description: 'Page description'
})
</script>
Available Auto-Imports
These are automatically available in Nuxt without imports:
<script setup>
// All auto-imported - no import statement needed
// Basic head management
useHead({
title: 'Page Title',
meta: [
{ name: 'description', content: 'Description' }
]
})
// SEO meta
useSeoMeta({
title: 'SEO Title',
ogTitle: 'Open Graph Title',
description: 'Meta description',
ogDescription: 'OG Description',
ogImage: 'https://example.com/image.jpg'
})
// Server-only head
useServerHead({
link: [{ rel: 'canonical', href: 'https://example.com' }]
})
// Head with template
useHeadSafe({
title: userInput // Sanitized automatically
})
</script>
Why Use Auto-Imports?
1. Proper Context
Nuxt’s auto-imports are integrated with the Nuxt context:
<script setup>
// ✅ Auto-import - has Nuxt context
useHead({
title: 'Works with SSR and client'
})
</script>
2. Type Safety
<script setup lang="ts">
// ✅ Types work correctly with auto-imports
useHead({
title: 'My Page',
meta: [
{ name: 'description', content: 'Description' }
]
})
</script>
3. SSR Support
Auto-imported functions work seamlessly with Nuxt’s SSR:
<script setup>
// ✅ Properly handles server and client rendering
useSeoMeta({
title: 'Server-rendered meta tags'
})
</script>
Composables Pattern
// composables/usePage.ts
export function usePageMeta(options: { title: string; description: string }) {
// ✅ Auto-imports work in composables too
useHead({
title: options.title
})
useSeoMeta({
title: options.title,
description: options.description
})
}
Usage:
<script setup>
// ✅ Use custom composable
usePageMeta({
title: 'Products',
description: 'Browse our products'
})
</script>
Dynamic Head
<script setup>
const route = useRoute()
const { data: product } = await useFetch(`/api/products/${route.params.id}`)
// ✅ Reactive head using computed
useHead({
title: computed(() => product.value?.name || 'Loading...')
})
useSeoMeta({
title: computed(() => product.value?.name),
ogImage: computed(() => product.value?.image)
})
</script>
In nuxt.config.ts
For global head configuration:
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
title: 'Default Title',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
}
}
})
If You Must Import
In rare cases (like testing or library code), explicitly import from #imports:
// ✅ Import from #imports if needed
import { useHead, useSeoMeta } from '#imports'
Not from @unhead/vue:
// ❌ Don't do this in Nuxt
import { useHead } from '@unhead/vue'
Suppressing the Warning
If you have a valid reason to import directly:
// @ts-expect-error - Using direct import intentionally
import { useHead } from '@unhead/vue'
But this is almost never necessary in Nuxt applications.
Quick Checklist
- Don’t import from
@unhead/vuedirectly - Use auto-imported
useHead,useSeoMeta, etc. - Auto-imports work in components and composables
- Use
#importsif explicit import needed - Configure global head in
nuxt.config.ts - Use
computed()for reactive head values