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. In the meantime, continue using Webpack SSR.

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

LayerWhereFor
Express middlewareServer entry middlewareEach HTTP request / 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 hang off each request entry.

Static handlers accept route-level instrumentations only:

ts
instrumentations?: Pick<ServerInstrumentation, 'route'>[];

Client instrumentations forward into createBrowserRouter:

ts
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