import{_ as i,o as a,c as n,ae as t}from"./chunks/framework.C8AWLET_.js";const E=JSON.parse('{"title":"Vite Plugin: Automatic File-based Routing 🚦","description":"","frontmatter":{},"headers":[],"relativePath":"vite/plugin.md","filePath":"vite/plugin.md"}'),l={name:"vite/plugin.md"};function p(h,s,e,k,r,d){return a(),n("div",null,[...s[0]||(s[0]=[t(`
SigPro provides an optional Vite plugin that automatically generates routes based on your file structure. No configuration needed - just create pages and they're instantly available with the correct paths.
While SigPro's router works perfectly with manually defined routes, this plugin:
[param] syntax for parametersThe plugin is included with SigPro, but you need to add it to your Vite config:
// vite.config.js
import { defineConfig } from 'vite';
import { sigproRouter } from 'sigpro/vite';
export default defineConfig({
plugins: [sigproRouter()]
});The plugin scans your src/pages directory and automatically generates routes based on the file structure:
src/pages/
├── index.js → '/'
├── about.js → '/about'
├── blog/
│ ├── index.js → '/blog'
│ └── [slug].js → '/blog/:slug'
└── users/
├── [id].js → '/users/:id'
└── [id]/edit.js → '/users/:id/edit'Add the plugin to your Vite config as shown above.
// main.js
import { $, html } from 'sigpro';
import { routes } from 'virtual:sigpro-routes';
// Use the generated routes directly
const router = $.router(routes);
document.body.appendChild(router);// src/pages/index.js
import { $, html } from 'sigpro';
export default () => {
return html\`
<div>
<h1>Home Page</h1>
<a href="#/about">About</a>
</div>
\`;
};// src/pages/users/[id].js
import { $, html } from 'sigpro';
export default (params) => {
const userId = params.id;
return html\`
<div>
<h1>User Profile: \${userId}</h1>
<a href="#/users/\${userId}/edit">Edit</a>
</div>
\`;
};| File Path | Generated Route |
|---|---|
src/pages/index.js | / |
src/pages/about.js | /about |
src/pages/contact/index.js | /contact |
src/pages/blog/post.js | /blog/post |
| File Path | Generated Route | Example URL |
|---|---|---|
src/pages/users/[id].js | /users/:id | /users/42 |
src/pages/blog/[slug].js | /blog/:slug | /blog/hello-world |
src/pages/users/[id]/posts/[pid].js | /users/:id/posts/:pid | /users/42/posts/123 |
| File Path | Generated Route | Notes |
|---|---|---|
src/pages/settings/index.js | /settings | Index page |
src/pages/settings/profile.js | /settings/profile | Sub-page |
src/pages/settings/security.js | /settings/security | Sub-page |
src/pages/settings/[section].js | /settings/:section | Dynamic section |
// src/pages/blog/index.js - Lists all posts
export default () => {
const posts = $([]);
$.effect(() => {
fetch('/api/posts')
.then(res => res.json())
.then(data => posts(data));
});
return html\`
<div>
<h1>Blog</h1>
\${posts().map(post => html\`
<article>
<h2><a href="#/blog/\${post.slug}">\${post.title}</a></h2>
<p>\${post.excerpt}</p>
</article>
\`)}
</div>
\`;
};// src/pages/blog/[slug].js - Single post
export default (params) => {
const post = $(null);
const slug = params.slug;
$.effect(() => {
fetch(\`/api/posts/\${slug}\`)
.then(res => res.json())
.then(data => post(data));
});
return html\`
<div>
<a href="#/blog">← Back to blog</a>
\${() => post() ? html\`
<article>
<h1>\${post().title}</h1>
<div>\${post().content}</div>
</article>
\` : html\`<div>Loading...</div>\`}
</div>
\`;
};// src/pages/dashboard/index.js
export default () => {
return html\`
<div class="dashboard">
<nav>
<a href="#/dashboard">Overview</a>
<a href="#/dashboard/analytics">Analytics</a>
<a href="#/dashboard/settings">Settings</a>
</nav>
<main>
<h1>Dashboard Overview</h1>
<!-- Overview content -->
</main>
</div>
\`;
};// src/pages/dashboard/analytics.js
export default () => {
return html\`
<div class="dashboard">
<nav>
<a href="#/dashboard">Overview</a>
<a href="#/dashboard/analytics">Analytics</a>
<a href="#/dashboard/settings">Settings</a>
</nav>
<main>
<h1>Analytics</h1>
<!-- Analytics content -->
</main>
</div>
\`;
};// src/pages/products/[category]/[id].js
export default (params) => {
const { category, id } = params;
const product = $(null);
$.effect(() => {
fetch(\`/api/products/\${category}/\${id}\`)
.then(res => res.json())
.then(data => product(data));
});
return html\`
<div class="product-page">
<nav class="breadcrumbs">
<a href="#/products">Products</a> >
<a href="#/products/\${category}">\${category}</a> >
<span>\${id}</span>
</nav>
\${() => product() ? html\`
<div class="product">
<h1>\${product().name}</h1>
<p class="price">$\${product().price}</p>
<p>\${product().description}</p>
<button @click=\${() => addToCart(product())}>
Add to Cart
</button>
</div>
\` : html\`<div>Loading...</div>\`}
</div>
\`;
};The plugin accepts an optional configuration object:
// vite.config.js
import { defineConfig } from 'vite';
import { sigproRouter } from 'sigpro/vite';
export default defineConfig({
plugins: [
sigproRouter({
pagesDir: 'src/pages', // Default: 'src/pages'
extensions: ['.js', '.jsx'], // Default: ['.js', '.jsx']
exclude: ['**/_*', '**/components/**'] // Glob patterns to exclude
})
]
});| Option | Type | Default | Description |
|---|---|---|---|
pagesDir | string | 'src/pages' | Directory containing your pages |
extensions | string[] | ['.js', '.jsx'] | File extensions to include |
exclude | string[] | [] | Glob patterns to exclude |
The plugin automatically sorts routes to ensure correct matching:
Example sorting:
/users/new (static, specific)
/users/[id]/edit (dynamic, deeper)
/users/[id] (dynamic, shallower)
/users/profile (static, shallower)When you import virtual:sigpro-routes, you get:
// Generated module
import Page_0 from '/src/pages/index.js';
import Page_1 from '/src/pages/about.js';
import Page_2 from '/src/pages/blog/index.js';
import Page_3 from '/src/pages/blog/[slug].js';
import Page_4 from '/src/pages/users/[id].js';
import Page_5 from '/src/pages/users/[id]/edit.js';
export const routes = [
{ path: '/', component: Page_0 },
{ path: '/about', component: Page_1 },
{ path: '/blog', component: Page_2 },
{ path: '/blog/:slug', component: Page_3 },
{ path: '/users/:id', component: Page_4 },
{ path: '/users/:id/edit', component: Page_5 },
];// With dynamic imports (automatic with Vite)
const routes = [
{ path: '/', component: () => import('./pages/index.js') },
{ path: '/about', component: () => import('./pages/about.js') },
// ...
];src/pages/
├── dashboard/
│ ├── index.js
│ ├── analytics.js
│ └── settings.js
└── dashboard.js # ❌ Don't mix with folder✅ Good:
pages/blog/index.js → /blog
pages/blog/post.js → /blog/post
❌ Avoid:
pages/blog.js → /blog (conflicts with folder)Prefix with underscore to exclude from routing:
src/pages/
├── index.js
├── about.js
└── _components/ # ❌ Not scanned
└── Header.jsCreate a layout wrapper in your main entry:
// main.js
import { $, html } from 'sigpro';
import { routes } from 'virtual:sigpro-routes';
// Wrap all routes with layout
const routesWithLayout = routes.map(route => ({
...route,
component: (params) => Layout(route.component(params))
}));
const router = $.router(routesWithLayout);
document.body.appendChild(router);Note: This plugin is completely optional. You can always define routes manually if you prefer. The plugin just saves you from writing boilerplate route configurations.
`,65)])])}const o=i(l,[["render",p]]);export{E as __pageData,o as default};Pro Tip: The plugin works great with hot module replacement (HMR) - add a new page and it's instantly available in your dev server without restarting!