Typed Layout Props in definePageMeta
Pass fully-typed props to a layout straight from a page's definePageMeta — no provide/inject, with autocomplete and type-checking.
What's new#
In 4.3 you could pass layout props via setPageLayout. Nuxt 4.4 lets you do it declaratively from a page inside definePageMeta — and the props are fully typed against the layout's own defineProps.
Why you'd care#
For page-specific layout config (a title, a sidebar toggle), middleware was the wrong home. Now the page that knows its own needs declares them, and the compiler checks you passed the right shape.
Before#
You reached for provide/inject or a store to parameterise a layout per page:
<script setup lang="ts">
provide('layoutTitle', 'Dashboard')
provide('layoutSidebar', true)
</script>
Untyped, easy to typo, and the coupling was invisible.
After#
Declare the layout and its props together, with types enforced:
<script setup lang="ts">
definePageMeta({
layout: {
name: 'panel',
props: {
sidebar: true,
title: 'Dashboard',
},
},
})
</script>
<script setup lang="ts">
defineProps<{
sidebar?: boolean
title?: string
}>()
</script>
If panel defines those props, you get autocomplete and type-checking on the props object in definePageMeta.
Do it yourself#
- Add typed
definePropstolayouts/panel.vue(sidebar?,title?). - In a page, set
definePageMeta({ layout: { name: 'panel', props: { title: 'Dashboard', sidebar: true } } }). - Render
titleandsidebarin the layout template. - Confirm the page shows its props applied.
- Pass a wrong type (e.g.
sidebar: 'yes') and confirm the type error surfaces.
Gotchas#
- This is the page-driven counterpart to 4.3's
setPageLayout(name, props). UsedefinePageMetafor static per-page config; usesetPageLayoutwhen the decision is dynamic (middleware, runtime conditions). - Typing only works if the layout declares
defineProps— an untyped layout gives you an untypedpropsobject.
Recap#
definePageMeta({ layout: { name, props } }) gives each page a typed way to configure its layout. Cleaner and safer than provide/inject.