SSGOI

Middleware

Rewrite the path SSGOI matches on, so a locale or tenant prefix does not need its own rules.

Add middleware when the URL carries structure your transition rules should ignore — a locale, a tenant prefix, a rewrite. It rewrites the route ids once, before anything else sees them.

Normalize before matching

Middleware takes the raw from and to ids and returns the logical ids every rule works with.

raw URL        /en/posts/42  →  /en/posts
                       │ middleware removes locale
logical route     /posts/42     →  /posts
                       │
                       └─ one shared rule set
const config = {
  middleware: (from, to) => ({
    from: from.replace(/^\/(en|ko)(?=\/|$)/, ""),
    to: to.replace(/^\/(en|ko)(?=\/|$)/, ""),
  }),
  transitions: [
    {
      on: "/posts/**",
      except: "/posts",
      transition: drill(),
    },
  ],
};

One identity all the way through

The resolved id is what rules match and what scroll positions are filed under.

Above, /en/posts and /ko/posts both become /posts. They match the same rules and share one restored scroll position. If the two locales must keep separate state, do not collapse them onto the same id.

For scroll bookkeeping the middleware is called with the same path on both sides, and only its from result is used. Write it as a plain per-path rewrite: one that branches on from !== to, or rewrites the two sides differently, will file scroll under an id you did not expect.

What not to use it for

Middleware removes incidental URL structure. It should not hide a complicated transition model.

  • Device branching — use transitions({ isMobile }).
  • Persistent layout lifetime — use boundaries and scoped keys.
  • Effect variants — pass props to drill(), sheet() and the rest.

Read next