Nuxt useHead TypeError

I created an issue on GitHub 2 months ago, but besides two likes I didn't get an answer. Maybe here can somebody help with this problem. Here's the link to the issue and a reproduction: https://github.com/nuxt/nuxt/issues/31764 Thank you!
GitHub
Nuxt useHead TypeError · Issue #31764 · nuxt/nuxt
Environment Operating System: Darwin Node Version: v20.19.0 Nuxt Version: 3.16.2 CLI Version: 3.24.1 Nitro Version: 2.11.8 Package Manager: bun@1.2.8 Builder: - User Config: compatibilityDate, devt...
18 Replies
kapa.ai
kapa.ai4mo ago
Hi @Bonobobby™. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- I'm sorry, but the knowledge sources provided do not contain information about the specific Nuxt useHead TypeError described in GitHub issue #31764. While there are several documents discussing useHead, Unhead, and related issues or regressions, none of them reference this particular issue number or provide details about the error or its resolution. If you can share the error message or a summary of the problem here, I may be able to help further by referencing the general guidance and troubleshooting steps for useHead and Unhead in Nuxt. Otherwise, based on the current knowledge sources, I cannot provide a specific answer to your question. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4mo ago
<@279754526888689666> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Bonobobby™
Bonobobby™OP4mo ago
@kapa.ai The error message is this:
Type '() => MetaAttrs' is not assignable to type 'ResolvableProperties<HtmlAttr & DataKeys & ResolvesDuplicates & TagPriority>'. Index signature for type 'xmlns:${string}' is missing in type '() => MetaAttrs'
Type '() => MetaAttrs' is not assignable to type 'ResolvableProperties<HtmlAttr & DataKeys & ResolvesDuplicates & TagPriority>'. Index signature for type 'xmlns:${string}' is missing in type '() => MetaAttrs'
And comes from this line of code:
htmlAttrs: () => localeHead.value.htmlAttrs
htmlAttrs: () => localeHead.value.htmlAttrs
kapa.ai
kapa.ai4mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the knowledge sources provided, there is no explicit mention of the specific TypeScript error you are encountering with useHead and the use of a function for htmlAttrs. However, I can summarize what is documented about the usage of htmlAttrs in useHead: - The useHead composable allows you to set htmlAttrs as part of the meta object, and it supports reactive values such as ref, computed, and reactive properties. The documentation and examples show htmlAttrs being set to an object or a computed value, but not to a function that returns an object Docs: useHead. - The type signature for useHead expects htmlAttrs to be an object or a computed value, not a function. For example:
const lang = computed(() => locales[locale.value].code)
const dir = computed(() => locales[locale.value].dir)

useHead({
htmlAttrs: {
lang,
dir
}
})

const lang = computed(() => locales[locale.value].code)
const dir = computed(() => locales[locale.value].dir)

useHead({
htmlAttrs: {
lang,
dir
}
})

or
useHead({
htmlAttrs: computed(() => ({ lang: 'en', dir: 'ltr' }))
})

useHead({
htmlAttrs: computed(() => ({ lang: 'en', dir: 'ltr' }))
})

but not:
useHead({
htmlAttrs: () => ({ lang: 'en', dir: 'ltr' }) // This is not shown in the docs
})

useHead({
htmlAttrs: () => ({ lang: 'en', dir: 'ltr' }) // This is not shown in the docs
})

- The error message you are seeing suggests that the type system expects htmlAttrs to be an object (or a computed/ref), not a function returning an object. Recommendation:
Try changing your code from:
htmlAttrs: () => localeHead.value.htmlAttrs
htmlAttrs: () => localeHead.value.htmlAttrs
to:
htmlAttrs: computed(() => localeHead.value.htmlAttrs)
htmlAttrs: computed(() => localeHead.value.htmlAttrs)
or, if localeHead.value.htmlAttrs is already reactive, you can pass it directly:
htmlAttrs: localeHead.value.htmlAttrs
htmlAttrs: localeHead.value.htmlAttrs
This approach aligns with the documented usage and should resolve the type error Docs: useHead. If this does not resolve your issue, the knowledge sources do not provide further details about this specific TypeScript error or its root cause. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4mo ago
<@279754526888689666> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Bonobobby™
Bonobobby™OP4mo ago
@kapa.ai With the computed Variant I get the following error:
Type 'ComputedRef<MetaAttrs>' is not assignable to type 'ResolvableProperties<HtmlAttr & DataKeys & ResolvesDuplicates & TagPriority>'.
Index signature for type '`xmlns:${string}`' is missing in type 'ComputedRef<MetaAttrs>'.
Type 'ComputedRef<MetaAttrs>' is not assignable to type 'ResolvableProperties<HtmlAttr & DataKeys & ResolvesDuplicates & TagPriority>'.
Index signature for type '`xmlns:${string}`' is missing in type 'ComputedRef<MetaAttrs>'.
kapa.ai
kapa.ai4mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I'm sorry, but the knowledge sources do not contain information about this specific TypeScript error regarding ComputedRef<MetaAttrs> and the ResolvableProperties<HtmlAttr & DataKeys & ResolvesDuplicates & TagPriority> type, nor do they provide details about the xmlns:${string} index signature issue. The official documentation shows that htmlAttrs can be set to a plain object or a computed value, but it does not address this particular type incompatibility or the use of MetaAttrs in this context Docs: useHead. There is also no mention of the xmlns:${string} index signature requirement in the provided sources. If you need further assistance, you may want to consult the Nuxt or Unhead repositories directly, or provide more context about how localeHead.value.htmlAttrs is structured, as the knowledge sources do not provide enough information to resolve this specific TypeScript typing issue. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4mo ago
<@279754526888689666> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
elliott
elliott4mo ago
Sharing a snippet of what you're trying to do would be helpful.
No description
Bonobobby™
Bonobobby™OP4mo ago
In this issue is everything explained: https://github.com/nuxt/nuxt/issues/31764
GitHub
Nuxt useHead TypeError · Issue #31764 · nuxt/nuxt
Environment Operating System: Darwin Node Version: v20.19.0 Nuxt Version: 3.16.2 CLI Version: 3.24.1 Nitro Version: 2.11.8 Package Manager: bun@1.2.8 Builder: - User Config: compatibilityDate, devt...
elliott
elliott4mo ago
well, I had to click into the issue, then click into the demo repo, then find the component that was calling useHead. A little snippet of how you're calling the function might lead to more help.
Bonobobby™
Bonobobby™OP4mo ago
<template>
<div>
<ul>
<li v-for="locale in locales" :key="locale.code">
<NuxtLink :to="switchLocalePath(locale.code)">
{{ locale.code }}
</NuxtLink>
</li>
</ul>
<NuxtPage />
</div>
</template>

<script setup lang="ts">
const { locales } = useI18n();

const switchLocalePath = useSwitchLocalePath();

const localeHead = useLocaleHead({
dir: true,
seo: true,
key: "id",
});

useHead({
htmlAttrs: () => localeHead.value.htmlAttrs,
link: () => localeHead.value.link,
meta: () => localeHead.value.meta,
});
</script>
<template>
<div>
<ul>
<li v-for="locale in locales" :key="locale.code">
<NuxtLink :to="switchLocalePath(locale.code)">
{{ locale.code }}
</NuxtLink>
</li>
</ul>
<NuxtPage />
</div>
</template>

<script setup lang="ts">
const { locales } = useI18n();

const switchLocalePath = useSwitchLocalePath();

const localeHead = useLocaleHead({
dir: true,
seo: true,
key: "id",
});

useHead({
htmlAttrs: () => localeHead.value.htmlAttrs,
link: () => localeHead.value.link,
meta: () => localeHead.value.meta,
});
</script>
Okay sorry. Here it is. Can you help with this issue? 🙂
elliott
elliott4mo ago
Try this?
const headData = computed(() => ({
htmlAttrs: localeHead.value.htmlAttrs,
link: localeHead.value.link,
meta: localeHead.value.meta,
}));

useHead(headData);

const headData = computed(() => ({
htmlAttrs: localeHead.value.htmlAttrs,
link: localeHead.value.link,
meta: localeHead.value.meta,
}));

useHead(headData);

Bonobobby™
Bonobobby™OP3mo ago
Yeah, really big thanks! This works. The reactivity is still there and the type-error is away, but I don't really understand why. It seems that this why the type-checking is off. Or has it another reason?
elliott
elliott3mo ago
Glad I could help! The typescript error you shared is pretty cryptic so I’m not sure. In your snippet, it looks like you’re passing a regular object to useHead, an object with functions. I n the working code, what are you passing to useHead?
Bonobobby™
Bonobobby™OP3mo ago
I did it exactly like you did. The funny thing is, that it still shows an error, when doing this way:
useHead({
htmlAttrs: computed(() => localeHead.value.htmlAttrs),
link: computed(() => localeHead.value.link),
meta: computed(() => localeHead.value.meta),
});
useHead({
htmlAttrs: computed(() => localeHead.value.htmlAttrs),
link: computed(() => localeHead.value.link),
meta: computed(() => localeHead.value.meta),
});
so one computed object to pass works, but for every attribute directly not I get this error message then:
Type 'ComputedRef<MetaAttrs>' is not assignable to type 'ResolvableProperties<HtmlAttr & DataKeys & ResolvesDuplicates & TagPriority>'.
Index signature for type '`xmlns:${string}`' is missing in type 'ComputedRef<MetaAttrs>'.
Type 'ComputedRef<MetaAttrs>' is not assignable to type 'ResolvableProperties<HtmlAttr & DataKeys & ResolvesDuplicates & TagPriority>'.
Index signature for type '`xmlns:${string}`' is missing in type 'ComputedRef<MetaAttrs>'.
elliott
elliott3mo ago
Yea that makes sense. What’s the signature of these two different objects you’re passing? It’s quite a different shape.
Bonobobby™
Bonobobby™OP3mo ago
Hmm, but why does it work, when I put it in one computed instead of 3 single computed values. Sorry for asking, but I don't see the big change which changes the type error So the one with type errors:
useHead({
htmlAttrs: computed(() => localeHead.value.htmlAttrs),
link: computed(() => localeHead.value.link),
meta: computed(() => localeHead.value.meta),
});
useHead({
htmlAttrs: computed(() => localeHead.value.htmlAttrs),
link: computed(() => localeHead.value.link),
meta: computed(() => localeHead.value.meta),
});
and your variant without type error:
const headData = computed(() => ({
htmlAttrs: localeHead.value.htmlAttrs,
link: localeHead.value.link,
meta: localeHead.value.meta,
}));

useHead(headData);
const headData = computed(() => ({
htmlAttrs: localeHead.value.htmlAttrs,
link: localeHead.value.link,
meta: localeHead.value.meta,
}));

useHead(headData);

Did you find this page helpful?