Skip to content

Latest commit

 

History

History
181 lines (138 loc) · 5.51 KB

router.md

File metadata and controls

181 lines (138 loc) · 5.51 KB

🦉 Router 🦉

Content

Overview

It is often useful to organize an application around urls. If the application is a single page application, then we need a way to manage those urls in the browser. This is why there are many different routers for different frameworks. A generic router can do the job just fine, but a specialized router for Owl can give a better developer experience.

The Owl router support the following features:

  • history or hash mode
  • declarative routes
  • route redirection
  • navigation guards
  • parameterized routes
  • a <Link/> component
  • a <RouteComponent/> component

Note that it is still in early stage of developments, and there are probably still some issues.

Example

To use the Owl router, there are some steps that needs to be done:

  • declare some routes
  • create a router
  • add it to the environment
async function protectRoute({ env, to }) {
  if (!env.session.authUser) {
    env.session.setNextRoute(to.name);
    return { to: "SIGN_IN" };
  }
  return true;
}

export const ROUTES = [
  { name: "LANDING", path: "/", component: Landing },
  { name: "TASK", path: "/tasks/{{id}}", component: Task },
  { name: "SIGN_UP", path: "/signup", component: SignUp },
  { name: "SIGN_IN", path: "/signin", component: SignIn },
  { name: "ADMIN", path: "/admin", component: Admin, beforeRouteEnter: protectRoute },
  { name: "ACCOUNT", path: "/account", component: Account, beforeRouteEnter: protectRoute },
  { name: "UNKNOWN", path: "*", redirect: { to: "LANDING" } }
];

function makeEnvironment() {
    ...
    const env = { qweb };
    env.session = new Session(env);
    env.router = new owl.router.Router(env, ROUTES);
    await env.router.start();
    return env;
}

App.env = makeEnvironment();
// create root component here

Notice that the router needs to be started. This is an asynchronous operation because it needs to apply the potential navigation guards on the current route (which may or may not mean that the application is redirected to another route).

Reference

Route definition

A route need to be defined as an object with the following keys:

  • name (optional): a (unique) string useful to identify the current route. If not given, it will be assigned an automatic name,
  • path: a string describing the url. It can be static: /admin or dynamic: /users/{{id}}. It also can be *, to catch all remaining routes.
  • component (optional): an Owl component that will be used by the t-routecomponent directive if the route is active
  • redirect (optional): should be destination object (with optional keys path, to and params) if given, the application will be redirected to the destination whenever we match this route
  • beforeRouteEnter: defines a navigation guard.

Router

The Router constructor takes three arguments:

  • env: a valid environment,
  • a list of routes,
  • an optional object (with the only key mode which can be history (default value) or hash).

history will use the browser History API as the mechanism to manage URL.
Example: https://yourdomain.tld/my_custom_route.
For this mechanism to work, you need a way to configure your web server accordingly.

hash will manipulate the hash of the URL.
Example: https://yourdomain.tld/index.html#/my_custom_route.

const ROUTES = [...];
const router = new owl.router.Router(env, ROUTES, {mode: 'history'});

Note that the route are defined in a list, and the order matters: the router tries to find a match by going down the list.

The router needs to be added to the environment in the router sub key.

Once a router is created, it needs to be started. This is necessary to initialize its current state to the current URL (and also, to potentially apply any navigation guards and/or redirecting).

await router.start();

Once started, the router will keep track of the current url and reflect its value in two keys:

  • router.currentRoute
  • router.currentParams

The router also has a navigate method, useful to programmatically change the application to another state (and the url):

router.navigate({ to: "USER", params: { id: 51 } });

Navigation Guards

Navigation guards are very useful to be able to execute some business logic/ perform some actions or redirect to other routes whenever the application is entering a new route. For example, the following guard checks if there is an authenticated user, and if it is not the case, redirect to the sign in route.

async function protectRoute({ env, to }) {
  if (!env.session.authUser) {
    env.session.setNextRoute(to.name);
    return { to: "SIGN_IN" };
  }
  return true;
}

A navigation guard is a function that returns a promise, which either resolves to true (the navigation is accepted), or to another destination object.

RouteComponent

The RouteComponent component directs Owl to render the component associated to the currently active route (if any):

<div t-name="App">
    <NavBar />
    <RouteComponent />
</div>

Link

The Link component is a Owl component which render as a <a> tag with any content. It will compute the proper href from its props, and allow Owl to properly navigate to a given url if clicked on it.

<Link to="'HOME'">Home</Link>