install
source · Clone the upstream repo
git clone https://github.com/Intense-Visions/harness-engineering
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/codex/nuxt-layouts-pages" ~/.claude/skills/intense-visions-harness-engineering-nuxt-layouts-pages-2fa9a2 && rm -rf "$T"
manifest:
agents/skills/codex/nuxt-layouts-pages/SKILL.mdsource content
Nuxt Layouts and Pages
Structure applications with file-based routing, named layouts, and per-page configuration via definePageMeta
When to Use
- You are building out the route structure of a Nuxt application
- You need multiple layouts (default, auth, dashboard) with different navigation or sidebar configurations
- You want to configure page-level metadata, transitions, middleware, or keepAlive from within the page SFC
- You are implementing nested routes or catch-all pages
Instructions
Pages — file-based routing:
- Create
files in.vue
— the path maps directly to the URL route:pages/
pages/ index.vue → / about.vue → /about users/ index.vue → /users [id].vue → /users/:id [...slug].vue → /* (catch-all)
- Place
in<NuxtPage />
(or within a layout) to render the active page:app.vue
<!-- app.vue --> <template> <NuxtLayout> <NuxtPage /> </NuxtLayout> </template>
- Access route params with
:useRoute
const route = useRoute(); const id = route.params.id; // typed if using typed routes
Layouts:
- Create layouts in
. Thelayouts/
layout is applied automatically. Named layouts require explicit opt-in:default.vue
<!-- layouts/default.vue --> <template> <div> <AppHeader /> <slot /> <AppFooter /> </div> </template>
<!-- layouts/dashboard.vue --> <template> <div class="dashboard-grid"> <DashboardSidebar /> <main><slot /></main> </div> </template>
- Apply a named layout from a page using
:definePageMeta
// pages/admin/users.vue <script setup lang="ts"> definePageMeta({ layout: 'dashboard' }) </script>
- Disable the layout entirely for specific pages (e.g., a full-screen login page):
definePageMeta({ layout: false });
- Switch layouts dynamically at runtime using
:setPageLayout
const { setPageLayout } = useLayout(); setPageLayout('minimal');
definePageMeta — per-page configuration:
- Use
for all page-level config — it is a compiler macro and must be called at the top level ofdefinePageMeta
:<script setup>
definePageMeta({ layout: 'dashboard', middleware: ['auth', 'role-admin'], keepalive: true, pageTransition: { name: 'slide-left', mode: 'out-in' }, title: 'User Management', // custom meta field });
Page transitions:
- Configure route transitions globally in
or per-page:nuxt.config.ts
// nuxt.config.ts export default defineNuxtConfig({ app: { pageTransition: { name: 'page', mode: 'out-in' }, }, });
/* assets/transitions.css */ .page-enter-active, .page-leave-active { transition: opacity 0.3s; } .page-enter-from, .page-leave-to { opacity: 0; }
Details
Nested routes:
Create a parent page component alongside a subdirectory of the same name to implement nested routing. The parent must include
<NuxtPage /> to render the child:
pages/ parent.vue → /parent (contains <NuxtPage />) parent/ child.vue → /parent/child
Optional catch-all:
[[...slug]].vue matches both / (optional slug) and /a/b/c. Useful for CMS-driven routing.
Typed routes:
Enable
experimental.typedPages in nuxt.config.ts to get full TypeScript inference for route params and query strings:
export default defineNuxtConfig({ experimental: { typedPages: true }, });
NuxtPage key — force remount on param change:
By default, navigating between
/users/1 and /users/2 reuses the page component. Force a remount with a :key binding:
<NuxtPage :page-key="route => route.fullPath" />
Layout transitions vs. page transitions:
— animates thepageTransition
slot content<NuxtPage />
— animates the outerlayoutTransition
when switching layouts<NuxtLayout />
Both accept Vue transition options or a boolean.
Custom page meta:
Extend
definePageMeta with custom fields by augmenting the PageMeta interface:
// types/nuxt.d.ts declare module '#app' { interface PageMeta { title?: string; requiresRole?: string; } }
Then read it in middleware:
to.meta.requiresRole.
Source
https://nuxt.com/docs/guide/directory-structure/pages
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.