Easy-React-Router
is an implementation of a file based Router for React.
(It also works with Preact.)
This project also includes Lazy-Component-Loader
which automatically changes the import of components to lazy imports only by renaming the file with a .lazy.tsx
extension.
- fully typed
- file based routing
- dynamic routes (with optional and mandatory parameters)
- automatic not found page
- route layout
- accessors for:
- route parameters (optional and mandatory)
- route path
- route visibility
- route loading state
- route specialization
- route link component
- optional use of document transition API
- manual route loading
- local router instance (see example in src/routes/about.tsx)
This table shows the equivalence between routes and their respective path.
/
in File path
is routes
directory.
File path | Route Path | Example |
---|---|---|
/ index.tsx |
layout for / |
/ |
/ index.index.tsx |
// |
(hidden path) |
/ index$id.tsx |
:id (id is optional) |
/?id=abc , /?id=123 , / |
/ index.$id.tsx |
/:id (id is mandatory) |
/abc , /123 |
/ $id.tsx |
/:id (id is mandatory) |
/abc , /123 |
/ 404.tsx |
not found at / |
(automatic path) |
/ (ignored-path).about.tsx |
/about |
/about |
/ (ignored-path)/ about.tsx |
/about |
/about |
/ posts.tsx |
layout for /posts |
/posts |
/ posts/ index.tsx |
layout for /posts |
/posts |
/ posts/ index.index.tsx |
/posts// |
(hidden path) |
/ posts$id.tsx |
/posts:id (id is optional) |
/posts?id=abc , /posts |
/ posts.$id.tsx |
/posts/:id (id is mandatory) |
/posts/abc , /posts/123 |
/ posts/ $id.tsx |
/posts/:id (id is mandatory) |
/posts/abc , /posts/123 |
/ posts.3.tsx |
/posts/3 |
/posts/3 |
/ posts/ 404.tsx |
not found at /posts |
(automatic path) |
/ (ignored-file).tsx |
(no path) | (no path) |
If you weirdly need /404
in your path, create a folder named 404
. Same for index
.
Download vite-plugin-watch-0.4.0.tgz and easy-react-router-1.0.0.tgz.
bun install easy-react-router-1.0.0.tgz
Add routerPlugin
to vite.config.ts
:
import react from "@vitejs/plugin-react";
import { routerPlugin } from "easy-react-router/plugin";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [react(), routerPlugin()], // some parameters can be passed to routerPlugin
});
Add genHtml
to package.json
:
{
"scripts": {
"genHtml": "bun run ./node_modules/easy-react-router/build/plugin/_genRoutes.ts --html dist/index.html"
}
}
If routes
folder does not exist, the plugin will create it with some example files.
And then, you can update the content of index.tsx
file to render the MainLayout
component:
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { MainLayout } from "./routes";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<MainLayout />
</StrictMode>
);
For building, execute:
bun run genHtml
(command to manually add to package.json
that can be customized)
Alternative
Alternatively, you can create a typescript file with the following content:
import { genHtmlRoutes } from "easy-react-router/plugin";
await genHtmlRoutes({ htmlFile: "dist/index.html" }); // the html file is copied to generate the static routes
Other functions are available in the plugin...
import { genLazyComponent, genRouterInstance } from "easy-react-router/plugin";
await genRouterInstance(); // generate the router instance
await genLazyComponent(); // generate the lazy components
-
_genRoutes.ts generates the Router Instance according to the file structure (c.f File based routing).
-
Only changes in
src/routes
are watched. -
A path is generated only when there is at least one export.
-
All routes are lazy loaded.
-
More...
- if many exports, add
// @routeExport
comment to specify the export to use for the route. - use
--json
to additionally generate a JSON file with the result of the parsing - use
--force
to force the regeneration of the router instance
Note: The Main Layout Component is generally lazy exported since it is imported in the root file (to avoid a build warning). In this case, the
// @routeExport
comment is needed. - if many exports, add
-
RouterRender
: Component that renders the current route. ParametersubPath
is used to specify the layout to use (and the routes to render). -
navigateToRouteFn
: Function to navigate to a route, using the current useTransition setting. -
getRouteParams
: Function to get the current route parameters. -
currentRoute
: Getter to get the current route. -
RouterPathType
: Type of the path of the routes (only the public ones). -
RouterParamsType
: Type of the parameters of a route. -
useRoutes
: Hook to force the re-render of a component that renders depending on the current route or loading state. -
setRouterBaseRoute
: Function to set the base route of the router (useful in production when the app is not at the root of the domain). -
More...
isRouteLoaded
,isRouteLoading
,isRouteVisible
: Functions to check the state of a route.notFoundRoute
: Route that is rendered when no route is found.loadRouteFn
: Function to trigger the loading of a route (could be use on hover for example).RouteLink
: Component to create a link to a route.navigateToCustomRouteFn
: Function to navigate to a custom url and update the current route.RouteCustomLink
: Component to create a link to a custom url.setUseRouteTransition
: Function to set the use of the document transition API.updateCurrentRoute
: Function that updates the current route according to the current url.buildRouteLink
: Function to build a link to a route.
After building the project, execute bun run genHtml
(with the correct path to the index.html
file).
This will generate a staticRoutes.yaml
file that will be used to generate copies of the index.html
file with the correct paths.
You can manually edit the staticRoutes.yaml
file to add more routes.
By default, the staticRoutes.yaml
file is not overwritten. Use the --overwrite
flag to overwrite it
(like this: bun run genHtml -- --overwrite
). (The --
is needed to pass the flag to the script.)
Lazy-Component-Loader
is a tool that automatically changes the import of components to lazy imports only by renaming the file with a .lazy.tsx
extension.
- fully typed
- automatic update of imports
- loading state
- manual loading
- Export only components from the file.
- Rename the file with
.lazy.tsx
extension. - That's it!
Notes: Be careful to not export load
or loadingState
as they are used by the loader.