Skip to Content
ExecutorscreateFetchExecutor

createFetchExecutor(baseURL, options?)@routar/core

Uses the native fetch API. Ideal for SSR where per-request dynamic headers are needed. Built into @routar/core — no additional package required.

import { createFetchExecutor } from '@routar/core' const executor = createFetchExecutor('https://api.example.com')

Options

createFetchExecutor(baseURL, { defaultHeaders: async () => { const token = await getServerToken() return token ? { Authorization: `Bearer ${token}` } : {} }, plugins: [logger()], retry: 2, timeout: 5_000, })
OptionTypeDescription
defaultHeaders() => Promise<Record<string, string>> | Record<string, string>Applied to every request. Evaluated per-request, so safe for SSR token injection.
pluginsExecutorPlugin[]Plugins applied before the fetch call
retrynumber | { count, shouldRetry? }Number of retries on failure
timeoutnumberPer-attempt timeout in milliseconds — throws TimeoutError on expiry

Empty responses

Responses with status 204, 205, or 304 resolve to null. A 200 response with an empty body also resolves to null instead of throwing a SyntaxError.

HttpError

Non-2xx responses throw HttpError. The parsed JSON error payload is available on .body (or null if the body was empty or not JSON):

import { HttpError } from '@routar/core' try { await todoApi.getDetail({ path: { id: 999 } }) } catch (err) { if (err instanceof HttpError) { console.log(err.status) // 404 console.log(err.statusText) // 'Not Found' console.log(err.body) // { message: 'Not found' } | null } }

Query parameter serialization

Arrays are serialized as repeated keys: ids=1&ids=2. This differs from Axios’s default (ids[]=1&ids[]=2). If you switch executors and use array query params, verify your server-side parsing is compatible.

SSR usage (Next.js)

import { createFetchExecutor } from '@routar/core' export const serverExecutor = createFetchExecutor(process.env.API_BASE_URL!, { defaultHeaders: async () => { const { cookies } = await import('next/headers') const token = (await cookies()).get('access_token')?.value return token ? { Authorization: `Bearer ${token}` } : {} }, timeout: 10_000, })

defaultHeaders is called on every request, so it picks up the current request’s cookies in Server Components and Route Handlers.

Last updated on