Request Store

Server-only access to the current request context — headers, params, and query string — outside of a React component.

getRequestStore() is the server-side counterpart to useRequest(). Where useRequest() is a React hook that can only be called inside a component, getRequestStore() has no such restriction — use it in utility functions, data-fetching helpers, and service layers that are called from server components.

It returns null when called outside an active request scope: in the browser, in tests, or after rendering has finished. Always guard the return value.

Basic usage

app/lib/auth.tstypescript
import { getRequestStore } from 'nukejs'

export async function getCurrentUser() {
    const ctx = getRequestStore()
    if (!ctx) return null

    const token = ctx.headers['authorization']
    if (!token) return null

    return verifyToken(token)
}

Call the helper from any server component without threading props down the tree:

app/pages/dashboard.tsxtypescript
import { getCurrentUser } from '../lib/auth'

export default async function Dashboard() {
    const user = await getCurrentUser()
    if (!user) return <p>Not logged in.</p>

    return <h1>Welcome, {user.name}</h1>
}

The RequestContext object

FieldTypeDescription
urlstringFull URL with query string, e.g. /blog/hello?lang=en
pathnamestringPath only, no query string, e.g. /blog/hello
paramsRecord<string, string | string[]>Dynamic route segments matched by the file-system router
queryRecord<string, string | string[]>Query-string params. Multi-value keys become arrays.
headersRecord<string, string>All incoming request headers including cookie and authorization. Multi-value headers are joined with ', '.

Unlike useRequest() on the client, the server-side store always contains the full set of headers — including cookie, authorization, and x-api-key. These are stripped before the context is embedded in the HTML document so they never reach the browser.

Forwarding auth headers

A common pattern is reading cookie or authorization in a shared fetch helper and forwarding them to an internal service:

app/lib/api.tstypescript
import { getRequestStore } from 'nukejs'

export async function apiFetch(path: string) {
    const ctx = getRequestStore()
    const headers: Record<string, string> = {
        'Content-Type': 'application/json',
    }

    if (ctx?.headers['cookie']) {
        headers['cookie'] = ctx.headers['cookie']
    }

    const res = await fetch(`http://localhost:4000${path}`, { headers })
    if (!res.ok) throw new Error(`API error ${res.status}`)
    return res.json()
}
app/pages/profile.tsxtypescript
import { apiFetch } from '../lib/api'

export default async function Profile() {
    const user = await apiFetch('/me') // cookie forwarded automatically

    return (
        <main>
            <h1>{user.name}</h1>
            <p>{user.email}</p>
        </main>
    )
}

Detecting locale from headers

Reading accept-language in a utility is a clean foundation for i18n without polluting component props:

app/lib/locale.tstypescript
import { getRequestStore } from 'nukejs'

const SUPPORTED = ['en', 'fr', 'de'] as const
type Locale = typeof SUPPORTED[number]

export function getLocale(): Locale {
    const ctx = getRequestStore()

    const fromQuery = ctx?.query.lang as string | undefined
    if (fromQuery && SUPPORTED.includes(fromQuery as Locale)) {
        return fromQuery as Locale
    }

    const header = ctx?.headers['accept-language'] ?? ''
    const tag = header.split(',')[0]?.split('-')[0]?.trim().toLowerCase()
    return (SUPPORTED.includes(tag as Locale) ? tag : 'en') as Locale
}

Null safety

getRequestStore() returns null when called outside an active request — during module initialisation, in tests, or anywhere in client-side code. Use optional chaining or an explicit guard:

app/lib/locale.tstypescript
const ctx = getRequestStore()

// Optional chaining — returns undefined if ctx is null
const locale = ctx?.headers['accept-language'] ?? 'en'

// Explicit guard — return early when outside SSR
if (!ctx) return defaultValue

API reference

APIDescription
getRequestStore()Returns the current RequestContext, or null outside an active SSR request.
normaliseHeaders(raw)Converts Node's IncomingMessage.headers to a flat Record<string, string>. Multi-value headers are joined with ', '.
sanitiseHeaders(raw)Same as normaliseHeaders but strips sensitive headers (cookie, authorization, proxy-authorization, set-cookie, x-api-key) before embedding in the HTML document.