N
Nuxt2mo ago
Cheaterman

How to access current page SEO Meta from template

How to access current page SEO Meta from template? $route.meta is for definePageMeta() which isn't what I'm looking for.
8 Replies
kapa.ai
kapa.ai2mo ago
Hi @Cheaterman. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To access the current page's SEO meta (such as the tags set with useSeoMeta) directly from the template, the knowledge sources do not provide a built-in or documented way to retrieve the SEO meta object or its values in the template or script after it has been set. - The $route.meta object is specifically for metadata defined via definePageMeta() and not for SEO meta tags set with useSeoMeta or useHead Docs > 4.x > Guide > Directory-structure > App > pages. - The useSeoMeta composable is used to set meta tags, but it does not expose a way to retrieve or read back the current meta values in the template or script after they are set Docs > 4.x > Getting-started > SEO and Meta. If you need to display SEO meta values in your template, you must manage those values yourself in a reactive variable and use them both for useSeoMeta and for display, for example:
<script setup lang="ts">
const title = ref('My Amazing Site')
const description = ref('This is my amazing site.')

useSeoMeta({
title,
description,
ogTitle: title,
ogDescription: description,
})
</script>

<template>
<div>
<h1>{{ title }}</h1>
<p>{{ description }}</p>
</div>
</template>
<script setup lang="ts">
const title = ref('My Amazing Site')
const description = ref('This is my amazing site.')

useSeoMeta({
title,
description,
ogTitle: title,
ogDescription: description,
})
</script>

<template>
<div>
<h1>{{ title }}</h1>
<p>{{ description }}</p>
</div>
</template>
This way, you control the source of truth for your meta values and can use them both for SEO and in your template. Summary:
There is no built-in way to access the current page's SEO meta (set by useSeoMeta or useHead) from the template. You need to manage the values yourself in your component state if you want to use them in both places Docs > 4.x > Api > Composables > useSeoMeta. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@534768504943935500> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Cheaterman
CheatermanOP2mo ago
@kapa.ai Yeah but that's annoying because I want the page title to be accessible from the layout file for example
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're correct—this is a common challenge. According to the Nuxt documentation, there is no built-in or documented way to directly access the SEO meta (such as the page title set via useSeoMeta or useHead) from a layout or another component after it has been set. The only metadata that is accessible via $route.meta is what you define with definePageMeta, which is not the same as the SEO meta tags set for the head Docs > 4.x > Guide > Directory-structure > App > pages. The recommended approach is to use definePageMeta for data you want to access across the app (such as in layouts), since this is merged into the route meta and is accessible via useRoute().meta. However, this does not automatically sync with the title or meta tags set via useSeoMeta or useHead—you would need to keep them in sync manually. Example:
// pages/some-page.vue
<script setup lang="ts">
definePageMeta({
title: 'Some Page',
})
useHead({
title: 'Some Page',
// ...other meta
})
</script>
// pages/some-page.vue
<script setup lang="ts">
definePageMeta({
title: 'Some Page',
})
useHead({
title: 'Some Page',
// ...other meta
})
</script>
// layouts/default.vue
<script setup lang="ts">
const route = useRoute()
console.log(route.meta.title) // 'Some Page'
</script>
// layouts/default.vue
<script setup lang="ts">
const route = useRoute()
console.log(route.meta.title) // 'Some Page'
</script>
If you want the page title to be accessible in the layout, you must set it via definePageMeta and then also use it in your useHead or useSeoMeta call. There is no automatic way to read the current head title from within a layout or component Docs > 4.x > Getting-started > SEO and Meta. Summary:
You need to manage the page title in a way that both your layout and your head/meta logic can access—typically by using definePageMeta for cross-component access, and then manually syncing it with your SEO meta setup. There is no built-in way to read the current head title or meta from a layout or template after it has been set. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@534768504943935500> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Cheaterman
CheatermanOP2mo ago
That's a great idea, thanks @kapa.ai How would one go about type hinting the page meta? This doesn't work:
<script setup lang="ts">
import type { RouteMeta } from 'vue-router'

definePageMeta({
middleware: 'auth',
title: 'Index',
})

const { meta } = useRoute() as { meta: RouteMeta & { title: string } }

useSeoMeta({
title: meta.title,
})
</script>
<script setup lang="ts">
import type { RouteMeta } from 'vue-router'

definePageMeta({
middleware: 'auth',
title: 'Index',
})

const { meta } = useRoute() as { meta: RouteMeta & { title: string } }

useSeoMeta({
title: meta.title,
})
</script>
The initial issue is that the type of meta.title here is unknown:
<script setup lang="ts">
definePageMeta({
middleware: 'auth',
title: 'Index',
})

const { meta } = useRoute()

useSeoMeta({
title: meta.title, // Typescript (rightfully) complains here
})
</script>
<script setup lang="ts">
definePageMeta({
middleware: 'auth',
title: 'Index',
})

const { meta } = useRoute()

useSeoMeta({
title: meta.title, // Typescript (rightfully) complains here
})
</script>
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- To type hint custom page meta properties in Nuxt, you should augment the PageMeta interface provided by Nuxt, rather than trying to cast or extend RouteMeta from vue-router. This is the recommended and documented approach. Here's how you can do it: 1. Augment the PageMeta interface in a .d.ts file (e.g., index.d.ts at your project root):
// index.d.ts
declare module '#app' {
interface PageMeta {
title?: string
// add any other custom properties here
}
}

// It is always important to ensure you import/export something when augmenting a type
export {}
// index.d.ts
declare module '#app' {
interface PageMeta {
title?: string
// add any other custom properties here
}
}

// It is always important to ensure you import/export something when augmenting a type
export {}
Docs > 3.x > Guide > Directory-structure > pages > Page Metadata 2. Now, when you use definePageMeta and access meta from useRoute(), TypeScript will recognize your custom properties:
<script setup lang="ts">
definePageMeta({
middleware: 'auth',
title: 'Index',
})

const { meta } = useRoute()

useSeoMeta({
title: meta.title, // No TypeScript error, title is now typed as string | undefined
})
</script>
<script setup lang="ts">
definePageMeta({
middleware: 'auth',
title: 'Index',
})

const { meta } = useRoute()

useSeoMeta({
title: meta.title, // No TypeScript error, title is now typed as string | undefined
})
</script>
Summary:
- Do not cast useRoute() or meta manually. - Augment the PageMeta interface as shown above for type safety and proper type hinting of your custom meta fields. This is the officially documented and type-safe way to handle custom page meta in Nuxt Docs > 3.x > Guide > Directory-structure > pages > Page Metadata. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@534768504943935500> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?