@onoxm/vite-plugin-auto-router
@onoxm/vite-plugin-auto-router
A Vite plugin for automatically generating React or Vue route files.
English | 中文
✨ Features
- Auto-generate route configuration, no manual maintenance needed
- Supports both React and Vue frameworks
- Convention-based routing, automatically mapped by directory structure
- Supports dynamic route
[id]syntax - Route groups: wrap a directory name in parentheses to organize pages without adding a URL segment
- Directory layouts: a
__layout__file turns a directory into a shell wrapping its subtree while preserving the index layer (recommended overtype: 'wrap') homepage path automatically converted to/(configurable)__root__page as root route container, wrapping all other routes (configurable) — deprecated, prefer root-level__layout__- Zero-config hot module replacement
- Supports page-level configuration files
- Virtual module only: route code is always served in-memory via
virtual:onoxm-auto-router/{react|vue}and never written to disk — no generated artifacts are left in your project - Auto-injects
vite-env.d.tstype declarations, out-of-the-box TypeScript support - Full IntelliSense: every plugin option ships with English JSDoc (including defaults) in the published type declarations — just hover in your IDE
- TypeScript type safety
🚀 Installation
npm install -D @onoxm/vite-plugin-auto-router
🔄 Migrating from v0.9.x
v0.10.0 is a cleanup release. The following options have been removed — please delete them from your vite.config.ts:
| Removed option | What to do |
|---|---|
virtualModule |
No longer needed. Virtual module is now the only output mode. |
routesFile |
No longer needed. Routes are never written to disk. |
hmr |
No longer needed. HMR is enabled by default. |
hmrDebounceMs |
No longer needed. |
dryRun |
Use log: 'tree' or log: 'json' for preview instead. |
onGenerated |
No longer needed. |
Before (v0.9.x):
autoRouter({
virtualModule: true,
hmr: true,
dryRun: false
})
After (v0.10.0):
autoRouter() // If you don't need other options
// Or
autoRouter({ log: 'tree' }) // If you want a preview
📖 Usage Guide
Page Component Identification Rules
The plugin identifies page components based on the following rules:
React Project
- Page components: Components with default export (
export default) in the pages directory - Regular components: Components with named export (
export const) in the pages directory
Vue Project
- Page components:
- Direct child components in the views directory (e.g.,
src/views/about.vue) - In nested directories, only
index.vueis considered a page component (e.g.,src/views/a/b/index.vue)
- Direct child components in the views directory (e.g.,
- Regular components: Non-
index.vuefiles in nested directories (e.g.,src/views/a/b.vue)
Ignored Directories
The following directory names (plus any directory starting with .) are always skipped while scanning pagesDir — pages inside them never become routes:
| Category | Directory names |
|---|---|
| Dependencies / VCS | node_modules, .git, .hg, .svn, .github, .vscode, .idea |
| Build output / test folders | dist, build, out, .next, .nuxt, .cache, .turbo, .vite, test, tests, __tests__, __test__ |
The second group has nothing to do with pages, so skipping one emits a warning listing the skipped directories (each directory is reported once). Obviously-ignored names such as node_modules stay silent.
The name-based rule cannot be turned off. If you really need pages under a directory called
testorbuild, rename it (e.g.views/acceptance/).
Route Groups (group)
A directory whose name is wrapped in parentheses is a route group. It is purely organizational and does not occupy a URL segment, so you can group pages without changing their final paths:
src/pages/
├── (marketing)/
│ ├── pricing.tsx → /pricing
│ └── contact.tsx → /contact
└── order/
└── (detail)/
└── [id].tsx → /order/:id
(marketing)/pricing.tsxand a top-levelpricing.tsxproduce exactly the same route — same final path, same position in the tree.- Groups can be nested and may appear at any level: the group segments are stripped first, then the remaining segments form the URL.
- Because the segment is stripped, a group is transparent to duplicate-path detection:
(a)/xand(b)/xboth resolve to/xand therefore collide (the plugin throws a duplicate-path error).
⚠️ 404 / notfound must not live inside a group
(marketing)/404.tsxresolves to the not-found path just like a top-level404.tsx, but a 404 page inside a group is almost always a mistake. The plugin throws an error instead of silently treating it as the global 404 (or clashing with an existing one). Move it to the pages root. This rule applies only to group directories — a normal subdirectory such aspages/user/404.tsxkeeps its current behavior.
Group membership is surfaced in the preview only (
log: 'tree'appends[group: marketing];log: 'json'adds agroupfield). It is internal metadata and is never written into the generatedroutesarray.
A group directory can also hold a __layout__.tsx (or .vue). The layout becomes a container for the group's subtree but, like the group itself, does not occupy a URL segment — React emits a pathless layout route (a route object without a path key) and Vue emits path: ''. To give it a URL segment, set an explicit path in its config (the escape hatch). See Directory Layouts __layout__.
Directory Layouts __layout__
A file named __layout__.tsx (React) or __layout__.vue (Vue) placed inside a directory turns that directory into a layout container — a shell component that wraps the directory's entire subtree. Create one by adding the layout file; a matching config file is optional:
| Framework | Layout file | Config file |
|---|---|---|
| React | __layout__.tsx |
__layout__.config.ts |
| Vue | __layout__.vue |
__layout__.meta.ts |
The config is matched by configPattern — the default is /**/*.config.{js,ts,jsx,tsx}. For Vue, the example below overrides it to /**/*.meta.ts.
⚠️ Extension caveat
The React layout config must use a glob-matched extension —
.config.tsor.config.js, not.config.tsx. A__layout__.config.tsxwill not be picked up.
A __layout__ file does not generate its own route. Instead it attaches a layout component plus layout config to the directory's container node.
Preserves the index layer (vs type: 'wrap')
__layout__ keeps the shell and the page as two separate files:
- The shell component (
__layout__.tsx) and the subtree-level config (__layout__.config.ts) land on the container node. - The page's own component (
index.tsx) and its ownindex.config.tsland on the index child route.
type: 'wrap' instead hoists the page's extra props onto the parent and swallows the index layer, so shell and page cannot be separated.
URL segment
- A normal directory inherits its URL segment:
user/__layout__.tsx→ containerpath: 'user'. - A group directory (e.g.
(marketing)/__layout__.tsx) has no directory-derived segment, so React emits a pathless layout route (nopathkey) and Vue emitspath: ''. - Escape hatch: inside a group directory, write an explicit
pathin the layout config to set the URL segment — e.g.(user)/__layout__.config.tswithpath: '/user'behaves just likeuser/__layout__.
Nested groups produce nested containers. The path field (including the [currentPath] placeholder) works on the container node exactly like wrap does today.
Directory structure
src/pages/
├── __root__.tsx
├── (marketing)/
│ ├── __layout__.tsx
│ ├── pricing.tsx # → /pricing
│ └── (legal)/
│ ├── __layout__.tsx
│ └── terms.tsx # → /terms
├── user/
│ ├── __layout__.tsx # → /user
│ ├── __layout__.config.ts # subtree-level config (loader / handle / path)
│ ├── index.tsx # → /user (optional)
│ └── settings.tsx # → /user/settings
└── 404.tsx
Generated tree — React
// segment directory: user/__layout__.tsx
{ path: 'user', element: <UserLayout />, /* layout config */,
children: [ { index: true, element: <UserIndex />, /* page config */ }, { path: 'settings' } ] }
// group directory: (marketing)/__layout__.tsx → pathless
{ element: <MarketingLayout />,
children: [ { path: 'pricing' }, { element: <LegalLayout />, children: [{ path: 'terms' }] } ] }
Generated tree — Vue
// segment directory
{ path: 'user', component: UserLayout, children: [ { path: '', component: UserIndex }, { path: 'settings' } ] }
// group directory → empty path
{ path: '', component: MarketingLayout, children: [ { path: 'pricing' } ] }
Note for Vue: vue-router has no
indexconcept; an exact match on/useris expressed by a default child route with an emptypath.
Root __layout__
A __layout__ in the pages root becomes the root container and replaces __root__ (top-level 404/notfound nests inside it, exactly as with __root__). Root __layout__ and __root__ cannot coexist — the plugin throws an error. With keepRoot: true, __root__ is kept as a plain route, so there is no conflict.
⚠️ Errors
The plugin throws for:
- Multiple layout files resolving to the same directory.
- A
typefield inside a layout config file — a layout is always a shell; remove the field.[currentPath]inside a layout config in a route group — a group directory has no derived path; use a literal path instead.
Migration from type: 'wrap'
| Aspect | type: 'wrap' |
__layout__ |
|---|---|---|
| URL segment | Inherits the page's directory (hoisted) | Inherits the directory; group → pathless |
| Shell vs page | One file — the page doubles as the shell | Two files — __layout__ shell + page stay separate |
| Index layer | Swallowed (index layer removed) | Preserved (index child route kept) |
| Config files | index.config.ts carries both |
__layout__.config.ts (subtree) + index.config.ts (page) |
| Status | Deprecated — works, not recommended for new code | Recommended |
Migration recipe:
- Move the shell markup from
index.tsxinto__layout__.tsx. - Move subtree-level fields (
loader/handle/path, etc.) fromindex.config.tsinto__layout__.config.tsand droptype: 'wrap'. - Add a new
index.tsxif you want an exact page at the directory path. - If the directory only has children (no page of its own), no new
index.tsxis needed.
React Project
Install Dependencies
npm install react-router
Configure Vite
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import autoRouter from '@onoxm/vite-plugin-auto-router/react'
export default defineConfig({
plugins: [react(), autoRouter()]
})
Directory Structure
src/
├── pages/
│ ├── index.tsx
│ ├── __root__.tsx
│ ├── 404.tsx
│ └── user/
│ ├── index.tsx
│ ├── index.config.ts
│ ├── [id].tsx
│ └── [id].config.ts
Special Pages
homepage: Path automatically converted to/, used as home route__root__page: Used as root route container, wrapping all other routes. Deprecated — superseded by a root-level__layout__file (pages/__layout__.tsx/pages/__layout__.vue), which becomes the root container.__root__andkeepRootare planned for removal after 0.12.0.404ornotfoundpage: Path automatically converted to/*, used as the 404 route.- When
__root__is the active root container (the default), the 404 route is nested as the last child of the root route, so the 404 page reuses the root layout. - Otherwise (no
__root__page, orkeepRoot: true), it is a standalone top-level route, not nested under any parent.
- When
- pages-root
__layout__.tsx: A__layout__at the pages root acts as the root container and replaces__root__; the two must not coexist (the plugin throws). See Directory Layouts__layout__
Page Configuration
Inherits from React Router RouteObject, with the following modifications:
- Removed:
Component,element,children,index - Added:
type?: 'single' | 'wrap'(deprecated),asIndex?: boolean
⚠️ Important Note
Configuration files must not use named exports (
export const,export function, etc.). Onlyexport defaultis allowed. If a configuration file contains named exports, the plugin will skip the file and display a warning in the console.
type: 'single'
When type is set to single, the page component will be generated as an independent route:
// src/pages/user/index.config.ts
import { defineConfig } from 'virtual:onoxm-auto-router/react'
export default defineConfig({
type: 'single'
})
Generated route structure:
// virtual:onoxm-auto-router/react
import type { RouteObject } from 'react-router'
import Pages404 from '../pages/404.tsx'
import Pages from '../pages/index.tsx'
import PagesRoot from '../pages/__root__.tsx'
import PagesUser from '../pages/user/index.tsx'
import PagesUserId from '../pages/user/[id]/index.tsx'
type PageConfig = Partial<
Omit<
RouteObject,
'Component' | 'element' | 'children' | 'lazy' | 'index'
> & {
type?: 'single' | 'wrap'
asIndex?: boolean
}
>
export const defineConfig = (config: PageConfig) => config
export const routes: RouteObject[] = [
{
path: '/',
element: <PagesRoot />,
children: [
{
path: '/',
element: <Pages />
},
{
path: '/user',
children: [
{
index: true,
element: <PagesUser />
},
{
path: ':id',
action: async () => {},
loader: async ({ params }) => await { params },
element: <PagesUserId />
}
]
},
{
path: '/*',
element: <Pages404 />
}
]
}
]
type: 'wrap'
⚠️ Deprecated for new code.
type: 'wrap'still works unchanged in 0.11.x–0.12.x (no warning, no behavior change), but prefer directory layouts__layout__for new code — they preserve the index layer. Removal is planned after 0.12.0.
When type is set to wrap, the page component will act as a parent route container wrapping its child routes:
// src/pages/user/index.config.ts
import { defineConfig } from 'virtual:onoxm-auto-router/react'
export default defineConfig({
type: 'wrap'
})
Generated route structure:
// virtual:onoxm-auto-router/react
import type { RouteObject } from 'react-router'
import Pages404 from '../pages/404.tsx'
import Pages from '../pages/index.tsx'
import PagesRoot from '../pages/__root__.tsx'
import PagesUser from '../pages/user/index.tsx'
import PagesUserId from '../pages/user/[id]/index.tsx'
type PageConfig = Partial<
Omit<
RouteObject,
'Component' | 'element' | 'children' | 'lazy' | 'index'
> & {
type?: 'single' | 'wrap'
asIndex?: boolean
}
>
export const defineConfig = (config: PageConfig) => config
export const routes: RouteObject[] = [
{
path: '/',
element: <PagesRoot />,
children: [
{
path: '/',
element: <Pages />
},
{
path: '/user',
element: <PagesUser />,
children: [
{
path: ':id',
action: async () => {},
loader: async ({ params }) => await { params },
element: <PagesUserId />
}
]
},
{
path: '/*',
element: <Pages404 />
}
]
}
]
hydrateFallbackElement / HydrateFallback (React Router lazy mode)
When the page configuration contains hydrateFallbackElement or HydrateFallback, the plugin automatically switches the page to React Router's lazy mode:
- No longer generates
elementfield or synchronousimportstatements - Instead generates a
lazyproperty that dynamically imports the component module and returnsComponent - Preserves the original hydrate field for fallback rendering during SSR hydration
In React Router v7, these are two parallel fields — you can use either or both:
| Field | Type | Accepts |
|---|---|---|
hydrateFallbackElement |
React.ReactNode |
JSX element <Loading /> |
HydrateFallback |
React.ComponentType |
Component reference Loading |
Usage 1: hydrateFallbackElement (JSX element)
The config file extension must be .config.tsx or .config.jsx:
// src/pages/index.config.tsx
import Loading from '../components/Loading'
export default defineConfig({
hydrateFallbackElement: <Loading />
})
Usage 2: HydrateFallback (component reference)
// src/pages/index.config.ts (component reference works with .ts/.js)
import Loading from '../components/Loading'
export default defineConfig({
HydrateFallback: Loading
})
Generated route structure (both usages produce the same output, differing only in the hydrate field):
// virtual:onoxm-auto-router/react
import type { RouteObject } from 'react-router'
import Loading from './components/Loading.tsx'
type PageConfig = Partial<
Omit<
RouteObject,
'Component' | 'element' | 'children' | 'lazy' | 'index'
> & {
type?: 'single' | 'wrap'
asIndex?: boolean
}
>
export const defineConfig = (config: PageConfig) => config
export const routes: RouteObject[] = [
{
path: '/',
hydrateFallbackElement: <Loading />, // or HydrateFallback: Loading
lazy: () => import('./pages/index.tsx').then(m => ({ Component: m.default }))
}
]
lazy Mode Priority
| Page Config | Plugin lazy Option |
Generation Mode |
|---|---|---|
Contains hydrateFallbackElement or HydrateFallback |
Any value | React Router lazy (highest priority, page-level overrides global) |
| No hydrate config | true |
React.lazy() + <Suspense> |
| No hydrate config | false |
Synchronous import + element |
Mixed Scenario
In the same project, routes with hydrate config use React Router lazy, while routes without it follow the global lazy option (React.lazy or synchronous import). The plugin intelligently determines whether to import { lazy, Suspense } from 'react' — when all routes use React Router lazy, it is not imported.
Note
- When using
hydrateFallbackElementwith JSX elements, the extension must be.config.tsxor.config.jsx; when usingHydrateFallbackwith component references, the extension can be.config.tsor.config.js- Imports of fallback components (e.g.,
Loading) are automatically collected, deduplicated, and injected into the generated route code- Do not use lowercase
hydrateFallback(this field name does not exist in React Router v7; onlyHydrateFallbackwith capital H andhydrateFallbackElementare recognized)
Vue Project
Install Dependencies
npm install vue-router
Configure Vite
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import autoRouter from '@onoxm/vite-plugin-auto-router/vue'
export default defineConfig({
plugins: [
vue(),
autoRouter({
pagesDir: './src/views',
configPattern: '/**/*.meta.ts'
})
]
})
Directory Structure
src/
├── views/
│ ├── 404.vue
│ ├── home/
│ │ ├── index.vue
│ │ └── index.meta.ts
│ └── user/
│ ├── index.vue
│ ├── index.meta.ts
│ ├── [id].vue
│ └── [id].meta.ts
Special Pages
homepage: Path automatically converted to/, used as home route__root__page: Used as root route container, wrapping all other routes. Deprecated — superseded by a root-level__layout__file (pages/__layout__.tsx/pages/__layout__.vue), which becomes the root container.__root__andkeepRootare planned for removal after 0.12.0.404ornotfoundpage: Path automatically converted to/:pathMatch(.*)*, used as the 404 route.- When
__root__is the active root container (the default), the 404 route is nested as the last child of the root route, so the 404 page reuses the root layout. - Otherwise (no
__root__page, orkeepRoot: true), it is a standalone top-level route, not nested under any parent.
- When
- views-root
__layout__.vue: A__layout__at the views root acts as the root container and replaces__root__; the two must not coexist (the plugin throws). See Directory Layouts__layout__
Page Configuration
Inherits from Vue Router RouteRecordRaw, with the following modifications:
- Removed:
component,children - Added:
type?: 'single' | 'wrap'(deprecated),asIndex?: boolean
⚠️ Important Note
Configuration files must not use named exports (
export const,export function, etc.). Onlyexport defaultis allowed. If a configuration file contains named exports, the plugin will skip the file and display a warning in the console.
type: 'single'
When type is set to single, the page component will be generated as an independent route:
// src/views/user/index.meta.ts
import { defineConfig } from 'virtual:onoxm-auto-router/vue'
export default defineConfig({
type: 'single'
})
Generated route structure:
// virtual:onoxm-auto-router/vue
import type { RouteRecordRaw } from 'vue-router'
import Views404 from '../views/404.vue'
import ViewsHome from '../views/home/index.vue'
import ViewsUser from '../views/user/index.vue'
import ViewsUserId from '../views/user/[id]/index.vue'
type PageConfig = Partial<
Omit<RouteRecordRaw, 'component' | 'children'> & {
type?: 'single' | 'wrap'
asIndex?: boolean
}
>
export const defineConfig = (config: PageConfig) => config
export const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'home',
component: ViewsHome
},
{
path: '/user',
children: [
{
path: '',
component: ViewsUser
},
{
path: ':id',
component: ViewsUserId
}
]
},
{
path: '/:pathMatch(.*)*',
component: Views404
}
]
type: 'wrap'
⚠️ Deprecated for new code.
type: 'wrap'still works unchanged in 0.11.x–0.12.x (no warning, no behavior change), but prefer directory layouts__layout__for new code — they preserve the index layer. Removal is planned after 0.12.0.
When type is set to wrap, the page component will act as a parent route container wrapping its child routes:
// src/views/user/index.meta.ts
import { defineConfig } from 'virtual:onoxm-auto-router/vue'
export default defineConfig({
type: 'wrap'
})
Generated route structure:
// virtual:onoxm-auto-router/vue
import type { RouteRecordRaw } from 'vue-router'
import Views404 from '../views/404.vue'
import ViewsHome from '../views/home/index.vue'
import ViewsUser from '../views/user/index.vue'
import ViewsUserId from '../views/user/[id]/index.vue'
type PageConfig = Partial<
Omit<RouteRecordRaw, 'component' | 'children'> & {
type?: 'single' | 'wrap'
asIndex?: boolean
}
>
export const defineConfig = (config: PageConfig) => config
export const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'home',
component: ViewsHome
},
{
path: '/user',
component: ViewsUser,
children: [
{
path: ':id',
component: ViewsUserId
}
]
},
{
path: '/:pathMatch(.*)*',
component: Views404
}
]
⚙️ Configuration Options
Plugin Configuration
| Option | Type | Default | Description |
|---|---|---|---|
framework |
'react' | 'vue' |
'react' |
Framework type (usually determined by the import path; no need to set manually) |
pagesDir |
string |
'./src/pages' |
Pages directory |
keepHome |
boolean |
false |
Whether to keep home page path |
keepRoot |
boolean |
false |
Whether to keep __root__ page path. Deprecated — keepRoot only exists to control the deprecated __root__ behavior and will be removed with it |
lazy |
boolean |
true |
Whether to enable lazy loading |
configPattern |
string |
'/**/*.config.{js,ts,jsx,tsx}' |
Config file format |
log |
false | 'tree' | 'json' |
false |
Output route preview to console: 'tree' for readable tree structure, 'json' for formatted (pretty-printed) JSON |
injectTypes |
boolean |
true |
Inject the virtual module type reference into vite-env.d.ts automatically; set to false to never touch your source files |
log Usage Example
The log option only controls whether the route tree preview is printed to the console. Supports three values:
false(default): no output'tree': outputs a readable route tree structure, component list, config imports, and target file path'json': outputs formatted (2-space indented) JSON (route tree with resolved component names, config imports, framework, routes file path) — readable in the console, still parseable by tooling
autoRouter({
log: 'tree' // Print a readable route tree to the console
})
// or
autoRouter({
log: 'json' // Print route info as JSON (pipe to a file or another tool)
})
Virtual Module
Route code is always served in-memory via the Vite virtual module virtual:onoxm-auto-router/react (or /vue). It is never written to disk — no generated artifacts are left in your project.
🚨 First-time Setup Required
The plugin auto-injects
/// <reference types="@onoxm/vite-plugin-auto-router/virtual" />intovite-env.d.tsduring Vite startup. If your build script runstscbeforevite build(e.g.,tsc -b && vite build), the first build may fail becausetsccannot resolvevirtual:onoxm-auto-router/*yet.Fix: Run
vite devorvite buildonce to let the plugin createvite-env.d.ts, then commit that file to your version control. All subsequent builds will work.
Import directly from the virtual module in your app code:
// src/router/index.ts
import { createBrowserRouter } from 'react-router'
import { routes } from 'virtual:onoxm-auto-router/react'
export const router = createBrowserRouter(routes)
Page config files also import defineConfig from the virtual module:
// src/pages/user/index.config.ts
import { defineConfig } from 'virtual:onoxm-auto-router/react'
export default defineConfig({
type: 'single'
})
Build & SSR compatibility
The virtual module works in both vite dev and vite build, including SSR builds. The virtual module is resolved during the build phase just like regular source files. The generated route code is pure data (no browser API dependencies), so it is compatible with server-side rendering environments. However, the plugin does not provide SSR-specific entry points — for React SSR, users need to use createStaticRouter instead of createBrowserRouter in their server entry.
TypeScript type declaration auto-injection
The virtual module virtual:onoxm-auto-router/{react|vue} is an in-memory module with no physical file on disk, so TypeScript cannot resolve its named exports (routes, defineConfig) by default. To pass TS type checks, the module's type declarations must be added to the project's vite-env.d.ts.
The plugin package exposes the type declarations via the ./virtual subpath (@onoxm/vite-plugin-auto-router/virtual). When the project is a TypeScript project (i.e., tsconfig.json exists), the plugin silently auto-injects the following into vite-env.d.ts during Vite's configResolved hook (triggered by both dev and build):
/// <reference types="@onoxm/vite-plugin-auto-router/virtual" />
Injection rules:
| Scenario | Behavior |
|---|---|
src/vite-env.d.ts exists and already contains the reference |
Skipped, content unchanged (idempotent) |
src/vite-env.d.ts exists but lacks the reference |
Appended after a blank line |
Root vite-env.d.ts exists but no src/ one |
Appended to the root file |
Both src/vite-env.d.ts and root exist |
Processes the src/ one, leaves root untouched |
| Neither exists | Creates src/vite-env.d.ts with the reference |
| Any error | Only warns, does not throw, does not block Vite startup |
Injection rewrites a file that is usually tracked in version control. Set
injectTypes: falseif you would rather keep the plugin away from your source tree — you then declare the virtual module types yourself.
Page Configuration
| Option | Type | Default | Description |
|---|---|---|---|
type |
'single' | 'wrap' |
'single' |
Route type (deprecated — prefer __layout__) |
path |
string |
undefined |
Route path, supports [currentPath] placeholder to reference current path |
asIndex |
boolean |
undefined |
Push this leaf page down into an index child route under its own path (see below) |
* |
any |
any |
Inherits from router config |
path Usage Example
Use the [currentPath] placeholder to reference the current path when replacing:
// src/pages/user/index.config.ts
import { defineConfig } from 'virtual:onoxm-auto-router/react'
export default defineConfig({
// Replace /user with /users/v2
path: '/users/v2'
})
// Or use the placeholder to add a suffix to the current path
export default defineConfig({
// Replace /user with /user/v2
path: '[currentPath]/v2'
})
asIndex Usage Example
By default a leaf page emits { path, element } directly, with no extra index child route. To make a page "own its path while its content sits at the index level", set asIndex: true in its config:
// src/pages/about.config.ts
import { defineConfig } from 'virtual:onoxm-auto-router/react'
export default defineConfig({
asIndex: true
})
The generated route uses each framework's native shape for an index child route:
// React
{ path: '/about', children: [{ index: true, element: About }] }
// Vue
{ path: '/about', children: [{ path: '', component: About }] }
Notes:
- Only meaningful for leaf pages: a page that already has child routes is split regardless, and
asIndexdoes not change the result;falseis the same as leaving it unset. - Misuse throws: setting it in a
__layout__.config.*file, or alongsidetype: 'wrap', raises an error — a layout or wrap page is already a shell, so "push myself down into an index child route" does not apply. - You cannot write
indexdirectly in a React page config (indexis react-router's output field, not a config entry, and has been excluded from the writablePageConfigfields); useasIndexfor the same intent.
📄 License
MIT
Related Packages
a vite plugin for automatically generating react or vue route files
A Vite plugin for handling iconify icon sets in environments without internet ac...
Version History
| Version | Released | License |
|---|---|---|
| 0.11.0 | MIT | |
| 0.10.7 | MIT | |
| 0.10.6 | MIT | |
| 0.10.5 | MIT | |
| 0.10.4 | MIT | |
| 0.10.3 | MIT | |
| 0.10.2 | MIT | |
| 0.10.1 | MIT | |
| 0.10.0 | MIT | |
| 0.9.7 | MIT | |
| 0.9.6 | MIT | |
| 0.9.5 | MIT | |
| 0.9.4 | MIT | |
| 0.9.3 | MIT | |
| 0.9.2 | MIT | |
| 0.9.1 | MIT | |
| 0.9.0 | MIT | |
| 0.8.10 | MIT | |
| 0.8.9 | MIT | |
| 0.8.8 | MIT | |
| 0.8.7 | MIT | |
| 0.8.6 | MIT | |
| 0.8.5 | MIT | |
| 0.8.4 | MIT | |
| 0.8.3 | MIT | |
| 0.8.2 | MIT | |
| 0.8.1 | MIT | |
| 0.8.0 | MIT | |
| 0.7.10 | MIT | |
| 0.7.9 | MIT |
Showing the latest 30 of 73. See every release on npm