vite-plugin-file-based-react-router
v1.1.4
Published
Vite plugin to generate file-based routes for react-router
Readme
vite-plugin-file-based-react-router
Opinionated vite plugin to generate file-based routes for using with react-router.
Inspired from tanstack.com/router, but without TypeScript.
Breaking changes
- Removed support of react-router loader
- Sub-module landing page redirection is now implemented by the
<Navigate to={subModuleLandingPage} />(previously byredirectin loader function)
- Sub-module landing page redirection is now implemented by the
Features
[x] supports React's lazy import and React Router's lazy route modules
[x] supports
.../*sub-routers[x] supports page metadata as route handle
[x] supports routing to a sub module as a npm package
[x] supports both react-router v6/v7 and @xgent/router-lite (recommended)
Installation
npm i --save-dev vite-plugin-file-based-react-routerConfig
Plugin config in vite.config.js.
import fileBasedReactRouter from 'vite-plugin-file-based-react-router';
//...
export default defineConfig({
plugins: [
fileBasedReactRouter({
enabled, // optional, default as true
root, // optional, default as 'src'
routesDir, // optional, default as 'pages'
runtimePagesDir, // optional, default as 'runtime_modules',
enableSentry, // optional, default as false, set to true to turn on sentry's browser router injection
reactRouterLib, // optional, default as 'react-router-dom', can be @xgent/router-lite for a lightweight router implementation
subRouters: { // optional sub-routers
'/app/editor': {
// load sub-router from ./modules/editor and mount it to /app/editor/*
importPath: './modules/editor', // can be a npm package name
defaultRoute: '/dashboard', // the landing page of this module will be /app/editor/dashboard
isLazy: true,
},
},
}),
//...
]
});File-based convention
- Sample files under
src/pages:
├── _error.jsx or _error.lazy_.jsx : component as errorElement under /
├── _layout.jsx : layout as element under /
├── app
│ ├── [module]
│ │ └── _any.lazy_.jsx : component as element under /app/:module/* with lazy import
│ └── _layout.jsx : layout as element under /app
├── route1
│ └── index.jsx : component as element under /route1
├── login.lazy_.jsx : component as lazy element under /login
└── other-non-lazy.jsx : component as element under /other-non-lazy- Sample files under
src/modules/editor/pagesas sub-router:
├── _layout.jsx : layout as element under /app/editor
├── project.[id].edit.lazy_.jsx : component as element under /app/editor/project/:id/edit with lazy import
├── project.lazy_.jsx : component as element under /app/editor/project with lazy import
└── workspace.jsx : component as element under /app/editor/workspace Route component (as element)
// all pages should have this export, however, the value of handle can be null if there is no special metadata for the page
export const handle = {
//..., usually, crumb: 'Breadcrumb Name'
}; // exposed as handle
export const Component = () => {...}; // as layout or page
Component.displayName = 'ComponentName'; // optional, useful for inspectionData loader (deprecated)
export default ({ params }) => {
const result = do_some_thing_before_rendering_page();
return result; // can be accessed by useLoaderData() in the page component
}Error component (as errorElement)
function ErrorComponent() {
const error = useRouteError();
// ...
};
export default ErrorComponent;Lazy module
export const handle = {
//...
};
export const Component = () => {...}; // as page
Component.displayName = 'ComponentName'; // optional, useful for inspectionRuntime generated files
After running vite dev or vite build, it will generate
- ./src/router.runtime.jsx
- ./src/runtime_modules/editor/sub-routes.runtime.jsx
Note:
- You may add
./src/router.runtime.jsxinto.gitignoreas it's dynamically generated by this plugin. - You may also add
./src/runtime_modulesinto.gitignoreas it's used as a folder for runtime files.
Usage
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import routes, { lazyRouting } from './routes.runtime';
const router = createBrowserRouter(routes, { patchRoutesOnNavigation: lazyRouting });
<RouterProvider router={router} />License
MIT
