Skip to content

Logging / Observability ​

CAUTION

Experimental — not for production. Managed Data Mode SSR is available for evaluation and testing. Do not use it in production yet. The API and behaviour may change. Until then, continue using Webpack SSR.

Your app controls logging. Wire it where the event happens:

LayerWhereFor
Express middlewareServer entry middlewareEach HTTP request and response
Server instrumentationsServer entryServer-side loaders, actions, and route middleware
Client instrumentationsClient entryClient navigations, fetches, and loaders
onListenServer entryServer start (bound port, readiness)

For whole-request access logs, use Express middleware.

React Router instrumentations ​

Optional React Router instrumentations are callbacks that wrap route work such as loaders. They attach to each request entry.

Static handlers accept route-level instrumentations only:

ts
type ServerEntry = {
  instrumentations?: Array<Pick<ServerInstrumentation, 'route'>>;
};

Client instrumentations forward into createBrowserRouter:

ts
type ClientEntry = {
  instrumentations?: ClientInstrumentation[];
};

Minimal server example that logs loader failures:

tsx
// src/server.tsx
import type { ServerInstrumentation } from 'react-router';
import { defineServerEntry } from 'sku/runtime';

const routeInstrumentation: Pick<ServerInstrumentation, 'route'> = {
  route(route) {
    route.instrument({
      async loader(callLoader, info) {
        const { status, error } = await callLoader();
        if (status === 'error') {
          console.error('loader failed', {
            routeId: route.id,
            pattern: info.pattern,
            message: error?.message,
          });
        }
      },
    });
  },
};

const server = defineServerEntry({
  instrumentations: [routeInstrumentation],
  onListen({ port }) {
    console.log(`listening on ${port}`);
  },
});

export default server;

See React Router’s instrumentation guide for client shapes and fuller examples.

See also ​