dispatchExecutor(resolver)
Creates an Executor that delegates to another executor chosen at request time.
import { dispatchExecutor } from '@routar/core'
const apiExecutor = dispatchExecutor((opts) => pickExecutor(opts))Parameters
| Parameter | Type | Description |
|---|---|---|
resolver | (opts: ExecuteOptions) => Executor | Called on every request; returns the executor to delegate to |
The resolver receives the full ExecuteOptions — method, URL, headers, body, signal — so it can branch on any runtime condition.
Examples
// Branch by environment
dispatchExecutor(() =>
typeof window === 'undefined' ? serverExecutor : clientExecutor
)
// Branch by URL prefix
dispatchExecutor((opts) =>
opts.url.startsWith('/internal') ? internalExecutor : publicExecutor
)
// Branch by auth context
dispatchExecutor(() =>
isAuthenticated() ? authedExecutor : anonExecutor
)Next.js App Router caveat
typeof window === 'undefined' is reliable in the browser / Pages Router, but behaves unexpectedly in App Router Server Components — Server Components always run on the server, so the check always returns true regardless of rendering context.
If your app uses App Router Server Components, prefer passing the correct executor explicitly rather than relying on the typeof window branch:
// server component — pass the server executor directly
const data = await serverApi.getList({})
// client component — the client executor is used at runtime
const data = await todoApi.getList({})Alternatively, use a dispatchExecutor that branches on a server-side signal (e.g. an async resolver that calls import('next/headers')).
See SSR / CSR Pattern for a complete Next.js setup example.