Client Middleware

This example demonstrates client-side middleware that runs during client-side navigation. The middleware can set context values that are available to loaders and components.

Data loaded from server!

Navigation Info (from server)

Navigated At:
2026-01-11T20:46:47.806Z
Path:
/features/middleware/client-middleware
Server Time:
2026-01-11T20:46:47.806Z

Live Context (from component props)

Context Available:
No (initial load)

Note

Client middleware only runs during client-side navigations, not during the initial server-side render. The loader can fall back to the server loader when the context is not set.

How it works

  1. Export a middleware array from your route file
  2. Each middleware receives context, request, params, and next
  3. Set context values using context.set()
  4. Call await next() to continue to child routes
  5. Access context in loaders and components via context.get()

Example Code

import { createContext } from "react-router";
import type { MiddlewareFunction } from "@udibo/juniper";

export const myContext = createContext<MyData>();

export const middleware: MiddlewareFunction[] = [
  async ({ context, request }, next) => {
    context.set(myContext, { /* your data */ });
    await next();
  },
];

export function loader({ context }) {
  const data = context.get(myContext);
  return { data };
}

export default function MyRoute({ context }) {
  const data = context.get(myContext);
  return <div>{data}</div>;
}