Skip to content

Guards & Middleware ​

Route Middleware ​

Middleware runs on every navigation. It can continue, redirect, or block:

ts
router.use(async (to, from, next) => {
  analytics.page(to.fullPath);
  return next();
});

Route Guards ​

Guards are observational — they can redirect but cannot block silently:

ts
router.beforeEach((to, from, context) => {
  if (to.meta.requiresAuth && !context.mesh.getState().auth.token) {
    throw redirect("/login", { search: { returnTo: to.fullPath } });
  }
});

redirect ​

ts
import { redirect } from "statemesh-core/router";

// In a guard
throw redirect("/login");

// With search params
throw redirect("/login", { search: { returnTo: "/checkout" } });

// With replace
throw redirect("/dashboard", { replace: true });

Guard vs Middleware ​

GuardsMiddleware
Registrationrouter.beforeEach()router.use()
Can redirectYes (throw redirect())Yes (throw redirect())
Can blockNoYes (return without next())
RunsBefore middlewareAfter guards
Use caseAuth checks, redirectsLogging, analytics, validation

Important Notes ​

TIP

Guards run before middleware. Both run before loaders. This ensures auth checks happen before data fetching.

Next Steps ​

Released under the MIT License.