# Server Runtime APIs

Server-only APIs for accessing the current request, route and search parameters, and cookies.

```ts
import { headers, routeParams, searchParam } from "@rebask/core/request"
import { cookies } from "@rebask/core/cookies"
```

## `headers()`

Read the incoming request headers. Internal routing headers are removed from the returned copy:

```ts
const requestHeaders = await headers()
const auth = requestHeaders.get("authorization")
```

Components that read `headers()` can't be included in the [shell](./rendering/ppr.md#suspense-and-dynamic-work),
so Rebask resumes them at runtime. Changing the returned headers does not modify the incoming
request.

> `headers()` is available in Server Components, [route handlers](./routing/route-handlers.md), and
> [Server Functions](./server-functions.md). It is not available inside
> [`"use cache"`](./caching/server-components.md#use-cache).

## `searchParam(name)`

Read a query parameter by name. The result is `null` when absent, a string for one value, or an array
for repeated values:

```ts
const query = await searchParam("q")
```

Rebask tracks which query parameters each segment reads so the
[client cache](./caching/segment-caching.md) can reuse content only when those values match. Like
`headers()`, this read is postponed during [shell capture](./rendering/ppr.md#suspense-and-dynamic-work).

`searchParam()` is not available in Server Functions or
[`"use cache"`](./caching/server-components.md#use-cache) functions.

## `routeParams()`

Read values from [dynamic route segments](./routing/introduction.md#dynamic-segments) during request handling:

```ts
const { id } = await routeParams<{ id: string }>()
const { slug } = await routeParams<{ slug: string[] }>()
```

> `routeParams()` is only available during request handling. It is not available in Server Functions
> or `"use cache"`.

Read route params under `<Suspense>` so Rebask can capture a
[shell](./rendering/ppr.md#suspense-and-dynamic-work) during build prerendering for paths whose
params are not resolved yet:

```tsx
import { Suspense } from "react"
import { routeParams } from "@rebask/core/request"

export default function ProductPage() {
  return (
    <Suspense fallback={<p>Loading…</p>}>
      <ProductTitle />
    </Suspense>
  )
}

async function ProductTitle() {
  const { id } = await routeParams<{ id: string }>()
  return <h1>Product {id}</h1>
}
```

Suspense is not needed when Rebask resolves every param before rendering. For example,
[`prerenderParams`](./routing/introduction.md#prerenderparams) with `allowExtraParams: false`
limits the route to its returned paths, so those paths have resolved params and every other path
is a 404.

## `cookies()`

Reads and writes cookies. The arguments decide what it reads and writes:

- `cookies(request)` reads incoming request cookies.
- `cookies(response)` reads and writes cookies on a `Response`.
- `await cookies()` reads incoming cookies and writes response cookies.

Use `await cookies()` in [Server Components](./rendering/components.md#server-components) and
[Server Functions](./server-functions.md), where no request or response object is available:

```ts
import { cookies } from "@rebask/core/cookies"

const cookieStore = await cookies()
const session = cookieStore.get("session")

// Write response cookies
cookieStore.set("session", token, {
  httpOnly: true,
  path: "/",
  maxAge: 60 * 60 * 24 * 7,
  sameSite: "lax",
  secure: true,
})
cookieStore.delete("session", { path: "/" })
```

`await cookies()` requires a response being rendered. It is not available in
[`"use cache"`](./caching/server-components.md#use-cache), and
[route handlers](./routing/route-handlers.md) and [proxies](./routing/proxy.md) should use
`cookies(request)` or `cookies(response)`.

Components that call `await cookies()` can't be baked into the
[shell](./rendering/ppr.md#suspense-and-dynamic-work), so Rebask resumes them at runtime. Changes are visible across stores obtained through `await cookies()` during the same
request.

`cookies(request)` returns a read-only store with `get`, `has`, and `getAll`. `cookies(response)`
and `await cookies()` also expose `set` and `delete`. `getAll()` returns a plain object keyed by name.

The `set()` method takes the following options:

| Option     | Type                          |
| ---------- | ----------------------------- |
| `path`     | `string`                      |
| `domain`   | `string`                      |
| `maxAge`   | `number` (seconds)            |
| `expires`  | `Date`                        |
| `httpOnly` | `boolean`                     |
| `secure`   | `boolean`                     |
| `sameSite` | `"strict" \| "lax" \| "none"` |

`delete()` accepts only `path` and `domain`.
