Does useHead not exist in Nuxt 4?
If it does, what is the correct syntax for using it in the app page, I just updated Nuxt 3 to Nuxt 4 and am seeing a TS error with the useHead. What am I doing wrong?
7 Replies
Hi @Sagar Kapoor. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Yes,
useHead
does exist in Nuxt 4. However, there are some important changes and migration steps you need to be aware of when upgrading from Nuxt 3 to Nuxt 4, especially regarding how you import and use useHead
.
Key Points for Nuxt 4
- useHead
is still available and is the recommended way to manage head/meta tags.
- Imports: In Nuxt 4, you should use the auto-imported useHead
(or import from #imports
or nuxt/app
), not from @unhead/vue
. Importing from @unhead/vue
will not work outside of Vue context (e.g., in plugins or middleware) and can cause errors. This is a breaking change from previous versions where such imports might have worked.
- TypeScript Changes: The types for useHead
have changed. In Nuxt 4, useHead()
always returns an ActiveHeadEntry
(not void
), and the types are stricter. If you see a TS error, it may be due to passing a function where a plain object or a computed value is expected.
Correct Usage Example in app.vue
If you need to use computed or reactive values for properties like htmlAttrs
, wrap the entire object in a computed
and pass it to useHead
:
This approach avoids the TypeScript error you might see if you try to pass a function directly to a property like htmlAttrs
instead of wrapping the whole object in a computed. This is confirmed as a solution in a real-world issue after upgrading to Nuxt 4 [Nuxt useHead TypeError].
Summary of What Might Be Wrong
- Importing from @unhead/vue
instead of using the Nuxt auto-import or #imports
.
- Passing a function to a property (e.g., htmlAttrs: () => ...
) instead of wrapping the whole object in a computed and passing that to useHead
.
- Not updating your code to match the stricter types in Nuxt 4.
For more details, see the migration notes and examples in the official documentation and related issues [Unhead v2 Upgrade Guide], [Nuxt useHead TypeError], [feat(nuxt): upgrade Unhead v2 major].
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@565461230060306432> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai
Is this approach wrong?
Let me check the knowledge base for you again. One moment! :books:
----------------------
Your approach is correct for using
Your approach is correct and matches the official Nuxt documentation. If you encounter errors, double-check that you are not placing this in
useHead
in Nuxt, and the syntax you provided is valid:
- Setting htmlAttrs
as an object is the recommended way to set attributes like lang
on the <html>
tag.
- Using a function for titleTemplate
is also supported, but note that this cannot be set in your nuxt.config
—it should be set in a file like app.vue
or a layout, as you are doing here. This is explicitly recommended in the documentation for dynamic title templates [SEO and Meta Features].
If you are seeing a TypeScript error, it is likely due to how the function is being passed or a mismatch in types elsewhere, but the structure you posted matches the documented usage for Nuxt 3 and Nuxt 4 [useHead API].
Summary:Your approach is correct and matches the official Nuxt documentation. If you encounter errors, double-check that you are not placing this in
nuxt.config
and that you are using the correct import or auto-import for useHead
in your setup file.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@565461230060306432> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
what's the error?
Got it working, since I am using docker with Taskfile, I realised the project was being built in another docker container, fixed it and the TS errors disappeared, it was a silly error. 😅
Good to see you here though!