What is the correct way to use layout: 'xyz' in .md files so that it works similarly to Nuxt Content v2? Should I use setPageLayout()? If so, where should I use it? I can’t do it in pages/[...slug].vue because the default layout loads first and then it changes, and it doesn’t work properly in middleware either... And if I want to check in the layout whether a given article has a ToC, I need access to data.value, but I can't call it inside layouts/xyz because it's only executed once.
#How to use layouts in Nuxt-Content v3
11 messages · Page 1 of 1 (latest)
Hi @eternal harbor. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
To use layouts in Nuxt Content v3, the recommended approach is to control the layout from your Nuxt page component, not directly from the markdown file’s frontmatter. While in Nuxt Content v2 you could use layout: 'xyz' in the frontmatter and have it automatically applied, this feature is not yet supported in Nuxt 3 according to the official migration docs and component options documentation. The layout property in frontmatter is currently ignored by Nuxt Content v3, and you must use Nuxt’s own layout system instead Docs > Migration > Component Options.
How to Apply Layouts in Nuxt Content v3
-
Set the Layout in the Page Component
In yourpages/[...slug].vue(the catch-all page for document-driven mode), you should use thedefinePageMetamacro to set the layout. You can programmatically determine which layout to use based on the content’s frontmatter, but you must do this in the page component, not in the markdown file itself.Example:
<script setup lang="ts"> const route = useRoute() const { data: page } = await useAsyncData(route.path, () => { return queryCollection('content').path(route.path).first() }) // Set layout dynamically based on frontmatter if (page.value?.layout) { definePageMeta({ layout: page.value.layout }) } </script>
-
Why Not
setPageLayout()in Middleware or Layout?- Using
setPageLayout()in middleware is possible, but you must ensure it runs before the layout is rendered to avoid hydration mismatches. This can be tricky, especially in document-driven mode, because the content data may not be available early enough Docs > Api > Utils > setPageLayout. - Using
setPageLayout()in the layout itself is not recommended, as layouts are only executed once and do not have access to the current page’s data in a reactive way.
- Using
-
Accessing Content Data in Layouts
Layouts in Nuxt 3 are not reactive to page data changes and are only instantiated once. If you need to check for properties like a ToC in the layout, you should pass this information from the page to the layout via props or slots. You cannot reliably call composables likeuseAsyncDataoruseContentinside layouts for per-page data Docs > Guide > Directory Structure > Layouts.
Summary
- Do not use
layout: 'xyz'in markdown frontmatter expecting it to work automatically in Nuxt Content v3. - Do set the layout in your page component, possibly by reading the frontmatter and calling
definePageMeta. - Do not use
setPageLayout()in layouts; use it in middleware or the page component if needed, but be aware of timing issues. - To pass data to layouts, use props or slots from the page component.
The knowledge sources confirm that frontmatter-based layout selection is not yet supported in Nuxt Content v3, and the recommended approach is to handle layout selection in your page logic Docs > Migration > Component Options, Docs > Guide > Directory Structure > Layouts.
If you need more advanced or automatic layout assignment, you may need to implement custom logic in your page component to read the frontmatter and set the layout accordingly.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@eternal harbor Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@keen thistle I can't use definePageMeta inside if() statement because: [plugin
pages-macros-transform] await in definePageMeta
Let me check the knowledge base for you again. One moment! :books:
You are correct: you cannot use definePageMeta inside an if statement or after an await in your <script setup>. The definePageMeta macro must be called synchronously and at the top level of the script, because it is a compile-time macro, not a runtime function. This is a limitation of how Nuxt parses and transforms your code for routing and meta information.
From the official documentation and migration guides:
definePageMetais a compiler macro and must be called at the top level of your page component’s<script setup>. You cannot call it conditionally or after asynchronous operations.
Docs > Api > Utils > definePageMeta
If you need to set the layout (or other meta) dynamically based on content loaded asynchronously (such as from a markdown file’s frontmatter), you cannot do this with definePageMeta directly. Instead, you would need to use other approaches, such as:
- Using
setPageLayout()in middleware or a plugin, but you must ensure the data is available before the layout is rendered, which is tricky in document-driven mode and not always reliable Docs > Api > Utils > setPageLayout. - Alternatively, you may need to restructure your app so that the layout is determined by the route or by static properties, not by asynchronously loaded content.
Summary:
You cannot use definePageMeta inside an if statement or after await. It must be called at the top level of your page’s <script setup>. This is a current limitation of Nuxt’s macro system, and there is no supported workaround for dynamic, async-based meta assignment at this time.
If you need more dynamic control, you may need to wait for future Nuxt features or consider a different architectural approach. The knowledge sources do not provide a supported way to achieve what you are asking for in Nuxt 3 at this time.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@eternal harbor Kapa.ai is still learning and improving, please let me know how I did by reacting below.