How to use layouts in Nuxt-Content v3
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.6 Replies
Hi @FoxCode. 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
In your
- Using
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 like
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
1. Set the Layout in the Page ComponentIn your
pages/[...slug].vue
(the catch-all page for document-driven mode), you should use the definePageMeta
macro 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:
2. 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.
3. Accessing Content Data in LayoutsLayouts 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 like
useAsyncData
or useContent
inside 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:
----------------------<@363971301947342848> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai I can't use definePageMeta inside if() statement because: [plugin:nuxt:pages-macros-transform] await in definePageMeta
Let me check the knowledge base for you again. One moment! :books:
----------------------
You are correct: you cannot use
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
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:
- definePageMeta
is 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:
----------------------<@363971301947342848> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@farnabaz So, is it impossible to use layouts without rebuilding everything (consider a different architectural approach)? In that case, "Implementing document driven mode in Content v3 is quite easy" and "Don't worry, you don't need to modify your content files. We made sure that Content v3 handles content in the same way as Content v2." - those statements aren't really true.