Skip to main content
vinext implements Next.js file-system routing conventions for both the Pages Router and App Router. Routes are discovered by scanning the pages/ and app/ directories at startup and hot-reloaded when files change.

Pages Router

The Pages Router follows the original Next.js routing conventions:

Basic Routes

Dynamic Routes

Dynamic segments are defined using square brackets:
pages/posts/[id].tsx

Catch-All Routes

Catch-all routes capture multiple segments:

API Routes

API routes are defined in pages/api/:
pages/api/hello.ts

Route Precedence

vinext matches routes following Next.js specificity rules:
  1. Static routes (most specific)
  2. Dynamic routes (by position — earlier is more specific)
  3. Catch-all routes
  4. Optional catch-all (least specific)

App Router

The App Router introduces a more powerful routing system with layouts, loading states, and parallel routes.

File Conventions

Basic Routes

Layouts

Layouts wrap multiple pages and persist across navigation:
When navigating from /dashboard/analytics to /dashboard/settings, the dashboard layout persists — only the page component re-renders.

Route Groups

Route groups organize files without affecting the URL structure:
Route groups (denoted by parentheses) are invisible in URLs but allow multiple layouts at the same level.

Dynamic Routes

Dynamic routes work the same as Pages Router:
app/posts/[id]/page.tsx
vinext supports both await params (Next.js 15+) and direct property access params.id (pre-15) via thenable objects.

Parallel Routes

Parallel routes allow rendering multiple pages in the same layout:
app/dashboard/layout.tsx
Slots are passed as props to the layout at their directory level. If a slot doesn’t have a matching page for a route, default.tsx is rendered:
app/dashboard/@analytics/default.tsx

Intercepting Routes

Intercepting routes allow showing a different page when navigating from within the app:
Interception conventions:
app/feed/@modal/(.)photos/[id]/page.tsx
Refreshing the page or direct navigation to /photos/123 renders the regular route instead.

Route Matching Implementation

vinext converts Next.js file conventions to internal URL patterns:
packages/vinext/src/routing/pages-router.ts

Precedence Scoring

Routes are sorted by specificity using a scoring algorithm:
packages/vinext/src/routing/pages-router.ts
Lower scores = higher priority. Static segments don’t add to the score, making them most specific.

Route Discovery

Routes are discovered at startup and cached:
packages/vinext/src/routing/pages-router.ts
The cache is invalidated when files are added or removed:
The Vite plugin sets up a file watcher that calls invalidateRouteCache() when the directory structure changes.

i18n Routing

vinext supports internationalized routing for Pages Router:
next.config.js
This enables locale prefixes automatically:
  • / → default locale (en)
  • /fr → French
  • /fr/about → French about page
The useRouter() hook exposes the current locale:
Domain-based i18n routing is not supported. Only path-based locale prefixes work.

basePath

Deploy your app under a URL prefix:
next.config.js
All routes are automatically prefixed:
  • pages/index.tsx/docs
  • pages/getting-started.tsx/docs/getting-started
  • Links and navigation respect the basePath automatically

trailingSlash

Force URLs to end with or without a trailing slash:
next.config.js
vinext issues 308 redirects to the canonical form:
  • /about/about/ (with trailingSlash: true)
  • /about//about (with trailingSlash: false)

Next Steps

Server Components

Learn how RSC integration works in App Router

Caching & ISR

Understand incremental static regeneration

Architecture

Deep dive into vinext’s architecture

API Routes

Build API endpoints