What Causes This Error?
This error occurs when you pass multiple elements or non-string content to the <Title> component from @unhead/vue or Nuxt’s head management.
The Problem
<!-- ❌ Wrong - multiple elements -->
<template>
<Title>
<span>My Site</span>
<span> - Home</span>
</Title>
</template>
<!-- ❌ Wrong - component inside Title -->
<template>
<Title>
<MyTitleComponent />
</Title>
</template>
<!-- ❌ Wrong - mixed content -->
<template>
<Title>
Home
<span>Page</span>
</Title>
</template>
The Fix
Pass only a single string:
<!-- ✅ Correct - simple string -->
<template>
<Title>My Site - Home</Title>
</template>
<!-- ✅ Correct - interpolated string -->
<template>
<Title>{{ pageTitle }} - My Site</Title>
</template>
<!-- ✅ Correct - computed string -->
<template>
<Title>{{ fullTitle }}</Title>
</template>
<script setup>
const pageTitle = ref('Home')
const fullTitle = computed(() => `${pageTitle.value} - My Site`)
</script>
Alternative: Use useHead
For dynamic titles, useHead is often cleaner:
<script setup>
const pageTitle = ref('Home')
useHead({
title: computed(() => `${pageTitle.value} - My Site`)
})
</script>
<template>
<!-- No Title component needed -->
<div>Content</div>
</template>
Alternative: Use useSeoMeta
For SEO-focused titles:
<script setup>
useSeoMeta({
title: 'Home - My Site',
ogTitle: 'Home - My Site'
})
</script>
With Title Template
Use titleTemplate for consistent formatting:
// nuxt.config.ts or app.vue
useHead({
titleTemplate: '%s - My Site'
})
Then in pages:
<script setup>
useHead({
title: 'Home' // Becomes "Home - My Site"
})
</script>
Dynamic Titles
<script setup>
const route = useRoute()
const { data: post } = await useFetch(`/api/posts/${route.params.id}`)
useHead({
title: computed(() => post.value?.title || 'Loading...')
})
</script>
Similar Error: Style Component
The same rule applies to <Style>:
<!-- ❌ Wrong -->
<template>
<Style>
<span>.class { color: red; }</span>
</Style>
</template>
<!-- ✅ Correct -->
<template>
<Style>.class { color: red; }</Style>
</template>
Quick Reference
| Usage | Valid? |
|---|---|
<Title>Simple Text</Title> | ✅ Yes |
<Title>{{ variable }}</Title> | ✅ Yes |
<Title>{{ a }} - {{ b }}</Title> | ✅ Yes |
<Title><span>Text</span></Title> | ❌ No |
<Title>Text<br/>More</Title> | ❌ No |
useHead({ title: 'Text' }) | ✅ Yes |
Best Practices
- Prefer useHead - More flexible and composable
- Use titleTemplate - For consistent site-wide formatting
- Compute titles - Use
computed()for reactive titles - Keep it simple - Titles should be plain strings
Quick Checklist
- Title contains only text, no HTML elements
- No components inside Title
- Use string interpolation for dynamic parts
- Consider using
useHeadinstead - Check
<Style>components for same issue