All skills

Nuxt full-stack Vue framework with SSR, auto-imports, and file-based routing. Use when working with Nuxt apps, server routes, useFetch, middleware, or hybrid rendering.

  • 19 files
  • 119.3 KB
  • Updated last week
  • GitHub

Use this Skill: https://skilld.dev/gh/onmax/claude-config/nuxt

This session only. Nothing lands on disk.

referencescore-routing.md

โ‰ˆ1.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Routing

Nuxt uses file-system routing based on vue-router. Files in app/pages/ automatically create routes.

Basic Routing

pages/
โ”œโ”€โ”€ index.vue      โ†’ /
โ”œโ”€โ”€ about.vue      โ†’ /about
โ””โ”€โ”€ posts/
    โ”œโ”€โ”€ index.vue  โ†’ /posts
    โ””โ”€โ”€ [id].vue   โ†’ /posts/:id

Dynamic Routes

Use brackets for dynamic segments:

pages/
โ”œโ”€โ”€ users/
โ”‚   โ””โ”€โ”€ [id].vue       โ†’ /users/:id
โ”œโ”€โ”€ posts/
โ”‚   โ””โ”€โ”€ [...slug].vue  โ†’ /posts/* (catch-all)
โ””โ”€โ”€ [[optional]].vue   โ†’ /:optional? (optional param)

Access route parameters:

<script setup lang="ts">
const route = useRoute()
// /posts/123 โ†’ route.params.id = '123'
console.log(route.params.id)
</script>

Navigation

NuxtLink Component

<template>
  <nav>
    <NuxtLink to="/">Home</NuxtLink>
    <NuxtLink to="/about">About</NuxtLink>
    <NuxtLink :to="{ name: 'posts-id', params: { id: 1 } }">Post 1</NuxtLink>
  </nav>
</template>

NuxtLink automatically prefetches linked pages when they enter the viewport.

Programmatic Navigation

<script setup lang="ts">
const router = useRouter()

function goToPost(id: number) {
  navigateTo(`/posts/${id}`)
  // or
  router.push({ name: 'posts-id', params: { id } })
}
</script>

Route Middleware

Named Middleware

// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
  const isAuthenticated = false // Your auth logic

  if (!isAuthenticated) {
    return navigateTo('/login')
  }
})

Apply to pages:

<script setup lang="ts">
definePageMeta({
  middleware: 'auth',
  // or multiple: middleware: ['auth', 'admin']
})
</script>

Global Middleware

Name files with .global suffix:

// middleware/logging.global.ts
export default defineNuxtRouteMiddleware((to, from) => {
  console.log('Navigating to:', to.path)
})

Inline Middleware

<script setup lang="ts">
definePageMeta({
  middleware: [
    function (to, from) {
      // Inline middleware logic
    },
  ],
})
</script>

Page Meta

Configure page-level options:

<script setup lang="ts">
definePageMeta({
  title: 'My Page',
  layout: 'custom',
  middleware: 'auth',
  validate: (route) => {
    // Return false for 404, or object with status/statusText
    return /^\d+$/.test(route.params.id as string)
  },
})
</script>

Route Validation

<script setup lang="ts">
definePageMeta({
  validate: (route) => {
    // Must return boolean or object with status
    return typeof route.params.id === 'string' && /^\d+$/.test(route.params.id)
  },
})
</script>

Layouts

Define layouts in app/layouts/:

<!-- layouts/default.vue -->
<template>
  <div>
    <header>Header</header>
    <slot />
    <footer>Footer</footer>
  </div>
</template>
<!-- layouts/admin.vue -->
<template>
  <div class="admin">
    <AdminSidebar />
    <main>
      <slot />
    </main>
  </div>
</template>

Use in pages:

<script setup lang="ts">
definePageMeta({
  layout: 'admin',
})
</script>

Dynamic layout:

<script setup lang="ts">
const layout = ref('default')

function enableAdmin() {
  setPageLayout('admin')
}
</script>

Passing Props to Layouts (Nuxt 4.4+)

Use the object syntax for layout to pass typed props to the layout component:

<!-- app/pages/dashboard.vue -->
<script setup lang="ts">
definePageMeta({
  layout: { name: 'panel', props: { sidebar: true, title: 'Dashboard' } },
})
</script>
<!-- app/layouts/panel.vue -->
<script setup lang="ts">
const props = defineProps<{ sidebar?: boolean, title?: string }>()
</script>

Props are fully typed from the layout's defineProps. Also works dynamically: setPageLayout('panel', { sidebar: true }).

Named Views

A route can render into multiple <NuxtPage> outlets. Add named view files with the name@view.vue convention next to the default route file:

pages/
โ”œโ”€โ”€ parent.vue
โ””โ”€โ”€ parent/
    โ”œโ”€โ”€ child.vue           โ†’ default <NuxtPage />
    โ””โ”€โ”€ child@sidebar.vue   โ†’ <NuxtPage name="sidebar" />
<!-- pages/parent.vue -->
<template>
  <NuxtPage />
  <aside><NuxtPage name="sidebar" /></aside>
</template>

definePageMeta is read from the default route file only.

Navigation Hooks

<script setup lang="ts">
onBeforeRouteLeave((to, from) => {
  // Confirm before leaving
  const answer = window.confirm('Leave?')
  if (!answer) return false
})

onBeforeRouteUpdate((to, from) => {
  // Called when route changes but component is reused
})
</script>
<!-- Source references: - https://nuxt.com/docs/4.x/getting-started/routing - https://nuxt.com/docs/4.x/directory-structure/app/pages - https://nuxt.com/docs/4.x/directory-structure/app/middleware - https://nuxt.com/docs/4.x/api/utils/define-page-meta -->

Source: SKILL.md on GitHub

No third-party reports yet.

Signed by skilld at e44f20d. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 9 hours ago.

Activeupdated last week
Other metadata
metadata
{
  "author": "Anthony Fu",
  "version": "2026.6.22",
  "source": "Generated from https://github.com/nuxt/nuxt, scripts located at https://github.com/antfu/skills"
}

README badge

README badge for onmax/claude-config/nuxt