File-Based Routing
Kimesh uses file-based routing where routes are automatically generated based on your file structure in the routes directory.
Basic Concept
Every .vue file in your routes directory becomes a route:
| File | Route Path |
|---|---|
index.vue | / |
about.vue | /about |
blog/index.vue | /blog |
blog/post.vue | /blog/post |
Route Types
Index Routes
Files named index.vue render at the parent path:
routes/
├── index.vue # /
└── blog/
└── index.vue # /blogPage Routes
Regular .vue files create routes at their path:
routes/
├── about.vue # /about
├── contact.vue # /contact
└── blog/
└── archive.vue # /blog/archiveLayout Routes
When a file has a matching directory, it becomes a layout that wraps child routes:
routes/
├── posts.vue # Layout for /posts/*
└── posts/
├── index.vue # /posts
└── $id.vue # /posts/:idThe posts.vue component wraps all routes in the posts/ directory with shared UI:
<!-- posts.vue -->
<template>
<div class="posts-layout">
<PostsSidebar />
<RouterView />
</div>
</template>Pathless Layouts
Use _name.vue prefix for layouts that don't add a URL segment:
routes/
├── _auth.vue # Pathless layout (wraps children, no URL segment)
├── _auth/
│ ├── login.vue # /login (not /auth/login)
│ └── register.vue # /registerPathless layouts can be nested recursively - a pathless layout can contain another pathless layout:
routes/
├── _auth.vue # Outer pathless layout
├── _auth/
│ ├── _onboarding.vue # Nested pathless layout
│ ├── _onboarding/
│ │ ├── step1.vue # /step1 (wrapped by both layouts)
│ │ └── step2.vue # /step2
│ ├── login.vue # /login (wrapped by _auth only)
│ └── register.vue # /registerThe route merger recursively collects routes from nested pathless layouts, ensuring proper layer integration.
Group Folders
Use parentheses for organizational grouping without a layout component:
routes/
├── (marketing)/
│ ├── pricing.vue # /pricing
│ └── features.vue # /features
├── (app)/
│ ├── dashboard.vue # /dashboard
│ └── settings.vue # /settingsUnlike pathless layouts, group folders don't create a wrapping component - they only affect file organization.
Dynamic Routes
Use $param prefix for dynamic segments:
routes/
├── users/
│ └── $id.vue # /users/:id
└── posts/
└── $slug.vue # /posts/:slugAccess params in your component:
<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.params.id) // "123" for /users/123
</script>Catch-All Routes
Use $.vue to match any remaining path segments:
routes/
├── docs/
│ └── $.vue # /docs/* (any path under /docs)
└── $.vue # /* (global 404)The matched path is available as route.params.pathMatch.
Route Hierarchy
Routes are nested based on directory structure and layouts:
routes/
├── __root.vue # Root layout (wraps everything)
├── index.vue # /
├── _auth.vue # Pathless auth layout
├── _auth/
│ ├── login.vue # /login
│ └── register.vue # /register
├── dashboard.vue # Layout for /dashboard/*
└── dashboard/
├── index.vue # /dashboard
└── settings.vue # /dashboard/settingsThe component hierarchy for /dashboard/settings:
__root.vue
└── dashboard.vue
└── dashboard/settings.vueGenerated Routes
Kimesh generates a routes.gen.ts file in the .kimesh directory:
// Auto-generated by @kimesh/router-generator
// Do not edit this file manually
export const routes = [
{
path: '/',
component: () => import('../src/routes/__root.vue'),
children: [
{ path: '', name: 'index', component: () => import('../src/routes/index.vue') },
{ path: 'about', name: 'about', component: () => import('../src/routes/about.vue') },
{
path: 'posts',
component: () => import('../src/routes/posts.vue'),
children: [
{ path: '', name: 'posts', component: () => import('../src/routes/posts/index.vue') },
{ path: ':id', name: 'posts-id', component: () => import('../src/routes/posts/$id.vue') },
],
},
],
},
]Related
- File Naming Conventions - Complete reference for all patterns
- Type Safety - Type-safe navigation and params
- Data Loading - Load data before routes render
- Middleware - Route guards and navigation control