Opinionated vite plugin to generate file-based routes for using with react-router.
Inspired from tanstack.com/router
, but without TypeScript.
- Removed support of react-router loader
- Sub-module landing page redirection is now implemented by the
<Navigate to={subModuleLandingPage} />
(previously byredirect
in loader function)
- Sub-module landing page redirection is now implemented by the
-
supports React's lazy import and React Router's lazy route modules
-
supports
.../*
sub-routers -
supports page metadata as route handle
-
supports routing to a sub module as a npm package
-
supports both react-router v6/v7 and @xgent/router-lite (recommended)
npm i --save-dev vite-plugin-file-based-react-router
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,
},
},
}),
//...
]
});
- 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/pages
as 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
// 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 inspection
export default ({ params }) => {
const result = do_some_thing_before_rendering_page();
return result; // can be accessed by useLoaderData() in the page component
}
function ErrorComponent() {
const error = useRouteError();
// ...
};
export default ErrorComponent;
export const handle = {
//...
};
export const Component = () => {...}; // as page
Component.displayName = 'ComponentName'; // optional, useful for inspection
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.jsx
into.gitignore
as it's dynamically generated by this plugin. - You may also add
./src/runtime_modules
into.gitignore
as it's used as a folder for runtime files.
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import routes, { lazyRouting } from './routes.runtime';
const router = createBrowserRouter(routes, { patchRoutesOnNavigation: lazyRouting });
<RouterProvider router={router} />
MIT