Route guards

Sometimes you want some of your pages to be available only under certain conditions. Use cases include:

  • Restrict access to a page to authenticated users only
  • Make some pages only available during development
  • Make some pages only available to certain subdomains (e.g. in multi-tenant applications)

Rakkas's solution to such requirements is called route guards. A route guard is a file named *.guard.js (or *.guard.ts) that is placed next to the *.page.jsx (or *.page.tsx) file. It's expected to export a pageGuard function. It can:

  • Return false to prevent the page from rendering.
  • Return { redirect: "/some/url" } to redirect.
  • Return { rewrite: "/new/url" } to render as if the URL was /new/url.
  • Return true to continue as normal.

The rewrite feature is handy, for example, to redirect to a login form while remembering the original URL.

A route guard can also guard all pages under a directory if it's named $guard.js (or .ts). Guards are called starting from the outermost one. All have to return true for the page to render.

Disabling catch-all page routes

Another use case for route guards is to disable catch-all page routes that shadow API routes. For example, /foo/[...slug].page.tsx will match /foo/bar before an API route /foo/bar.api.ts is matched, effectively shadowing it. To prevent this, you can create a guard file foo/[...slug].guard.ts with the following content:

import type { LookupHookResult, PageRouteGuard } from "rakkasjs";

export const pageGuard: PageRouteGuard = (ctx) => {
  // Selectively disable the catch-all page route for /foo/bar
  return ctx.url.pathname !== "/foo/bar";
};