Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dvlkit/nuxe/llms.txt

Use this file to discover all available pages before exploring further.

Nuxe eliminates manual router configuration by scanning your app/pages/ directory at build and dev time. Every .vue file inside that directory becomes a route — the file’s path relative to app/pages/ maps directly to a URL segment. Add a file, get a route. Delete a file, the route is gone. No router file to maintain.

File-to-route mapping

The scanner converts each file path into a Vue Router route using simple rules: directory separators become / segments, index.vue files strip the trailing /index from their path, square-bracket filenames become dynamic segments, and [...name].vue produces a catch-all.
FileRoute path
pages/index.vue/
pages/about.vue/about
pages/admin/users.vue/admin/users
pages/[id].vue/:id
pages/[...slug].vue/:slug(.*)*
An index.vue inside a subdirectory strips the /index suffix from the final route path. For example, pages/blog/index.vue produces /blog, not /blog/index.

Declaring page metadata with definePage

Inside any page component you can call definePage to attach metadata — a layout name, route middleware, or custom meta fields. The macro is a no-op at runtime; Nuxe transforms it away at build time and hoists the options into the generated router config. definePage is auto-imported, so no import statement is needed in <script setup>.
pages/admin.vue
<script setup lang="ts">
definePage({
  meta: {
    layout: 'admin',
    middleware: 'admin'
  }
})
</script>

<template>
  <h1>Admin Page</h1>
  <p>This is rendered inside the Admin Layout</p>
</template>
The full PageMeta type accepted by definePage is:
interface PageMeta {
  meta?: {
    middleware?: string | string[]
    layout?: string
    [key: string]: unknown   // any extra fields end up in route.meta
  }
  routeRules?: RouteRules
}

Route rules

routeRules inside definePage lets you control how the server handles each route without touching any server config. The options come from the RouteRules interface in the scanner:
interface RouteRules {
  ssr?: boolean
  prerender?: boolean | string
  redirect?: string
}

Disable SSR for a single page

Set ssr: false to render the page entirely in the browser (SPA mode for that route). The server still delivers a minimal HTML shell so the client JavaScript can boot.
pages/spa.vue
<script setup>
definePage({
  routeRules: { ssr: false },
})

useHead({ title: 'SPA Mode | my-app' })

const counter = ref(0)
</script>

<template>
  <div>
    <h1>SPA Mode</h1>
    <p>This page is rendered only on the client.</p>
    <p>Counter: {{ counter }}</p>
    <button type="button" @click="counter++">Increment</button>
  </div>
</template>

Prerender a page at build time

Set prerender: true and Nuxe will render the page during nuxe build and write the result to .output/public/ as a static HTML file.
pages/static.vue
<script setup>
definePage({
  routeRules: { prerender: true },
})

useHead({ title: 'Static | my-app' })
</script>

<template>
  <div>
    <h1>Static Page</h1>
    <p>This page is prerendered at build time.</p>
  </div>
</template>
You can also supply a custom output path as the value:
routeRules: { prerender: '/static-landing' }

Redirect from a route

redirect makes the server respond with a 302 to the given path whenever the route is requested.
pages/old.vue
<script setup>
definePage({
  routeRules: { redirect: '/' },
})
</script>

<template>
  <div>This page redirects to home.</div>
</template>

Skipping a file with the _ prefix

Any .vue file whose name starts with _ is silently ignored by the scanner. Use this for shared fragments, page partials, or any component you store inside pages/ that should not become a route.
pages/
├── index.vue        # → /
├── _partials/       # skipped — directory name starts with _
│   └── hero.vue     # skipped
└── about.vue        # → /about
The same rule applies to subdirectories: a directory whose name starts with _ is not scanned.

Typed navigation

Nuxe generates a typed-router.d.ts file inside .nuxe/ at startup. This file teaches vue-router’s TypesConfig about every route name and its required params. Two composables are generated into .nuxe/composables/ and auto-imported so you can use them without any explicit import:
  • navigateTo(to, options?) — typed wrapper around the framework’s navigateTo that accepts either a route path literal or a named-location object with the correct params type.
  • useNuxeRoute(name?) — typed wrapper around useRoute() that narrows route.params to the params of the named route.
pages/index.vue
<script setup lang="ts">
// navigateTo is auto-imported; the type-checker enforces valid paths
async function goToAdmin() {
  await navigateTo('/admin')
}

// Named navigation — TypeScript checks that `id` is provided
async function goToUser(id: string) {
  await navigateTo({ name: 'users-id', params: { id } })
}
</script>

<template>
  <button @click="goToAdmin">Go to Admin</button>
</template>
navigateTo accepts an options bag as its second argument:
interface NavigateToOptions {
  replace?: boolean      // use router.replace instead of router.push
  redirectCode?: number  // HTTP status code for server-side redirects (default 302)
  external?: boolean     // navigate to an external URL
}

Aborting navigation in middleware

Inside a route middleware you can call abortNavigation to cancel the current navigation. It is auto-imported and accepts an optional error descriptor:
// Abort silently
abortNavigation()

// Abort with a message (shows in the error page)
abortNavigation('You do not have access to this page.')

// Abort with a status code
abortNavigation({ statusCode: 403, statusMessage: 'Forbidden' })

// Abort with an Error instance
abortNavigation(new Error('Something went wrong'))
Its full signature is:
function abortNavigation(
  err?: Error | string | { statusCode?: number; statusMessage?: string }
): false | AbortNavigationResult
The generated RouteNamedMap, RoutePaths, and NuxeRouteLocationRaw types are exported from .nuxe/typed-router.d.ts and are automatically available throughout your project via the .nuxe/auto-imports.d.ts ambient declarations.

Build docs developers (and LLMs) love