preact-routlet
v1.1.0
Published
simple preact hash routing
Downloads
4
Readme
Preact Routlet
This package contains routing functionalities for preact and, now from 1.0.0 React
applications as well. Instead of using HTML5 history API it uses the oldie /#/what-ever
hash routing (this will change in the future).
This project was created by exploring contextual ways to define routes rather than placing all the routes in a single file.
Usage:
Available imports:
// if you're using React
import { renderOnRoute, navigate, RouterOutlet, PathLookup, routePool, Link } from "preact-routlet/react"
// if you're using Preact
import { renderOnRoute, navigate, RouterOutlet, PathLookup, routePool, Link } from "preact-routlet/preact"
Either from "preact-routlet/preact"
or from "preact-routlet/react"
Place your RouterOutlet element somewhere in your JSX:
<div>
<RouterOutlet />
</div>
Plug renderOnRoute
decorator on some component
@renderOnRoute("/login")
export default class Login extends Component<any, any> {
...
}
Remember to import your class to evaluate your component
import './components/login';
You dont need to instantiate it or declare it. Just import on your app index.
Best practice is to group your components by domain:
For example imagine the following index
file:
import { h, render } from "preact";
import Main from "./common/main";
/* domain */
import "./domain/access";
import "./domain/dashboard";
render(<Main />, document.querySelector("#root"));
Then you have some king of folder structure like this:
src/domain/
├── access
│ ├── index.tsx
│ ├── models
│ ├── pages
│ └── share
└── dashboard
└── index.tsx
on each index you're imporing your components:
$ cat src/domain/access/index.tsx
import "./pages/login-page";
import "./pages/register-page";
import "./pages/forgot-password-page";
So basically you're registering all the components that listen to route changes in your app.
Features:
404 routes: If none of components are listening for some particular route
<div> <RouterOutlet> <ThisComponentWillBeRenderedOtherwise /> </RouterOutlet> </div>
Conditional rendering on route (declarative)
<PathLookup shouldRender={path => predicate}> <ComponentThatWillBeRenderedIfPredicateReturnsTrue /> </PathLookup>
Navigation (code)
... navigate("/somewhere");
Navigation (declarative)
<Link href="/somewhere">Go to somewhere</Link>
Redirect if some condition was not fulfilled
<RouterOutlet redirect="/login" shouldRedirect={path => requireLogin(path) && !AuthService.isLogged()} />
- Lazy loading, Module splitting
By default routes are only loaded if you evaluate classes that contain @renderOnRoute
decorator, so simply by importing it. But you need the plugin syntax-dynamic-import
to dynamically use the import() function with Babel.
...
} else if (User.isAdmin(userSnapshot)) {
import('../admin'); //load admin module
}
// admin/index.js
...
import { navigate } from 'preact-routlet/react'; // import navigate function
import './dashboard'; //load component with @renderOnRoute
import './user-list'; //load component with @renderOnRoute
navigate('/admin-board'); //navigate to this module once routes are loaded
By using @renderOnRoute
you're adding the evaluated component to the route pool