# Uniform SDK for Next.js App Router Reference

> The entry points, exports and types of the Uniform SDK for Next.js App Router.

Source: https://docs.uniform.app/docs/sdk/nextjs-app-router/reference

> **Developer Preview:**
>
> This reference documents version `20.81.1-alpha.25.sha-f076f9b857`. The entry points `@uniformdev/next-app-router/edge` and `@uniformdev/next-app-router/vercel` are new in the developer preview.

## SDK Reference

### Package requirements

| Package | Peer dependencies |
| --- | --- |
| `@uniformdev/next-app-router` | `next` 16.0.7 or later, `react` and `react-dom` 18.2 or 19, `@vercel/functions` 3 or later (optional) |
| `@uniformdev/next-app-router-client` | `next` 16.0.7 or later, `react` and `react-dom` 18.2 or 19 |
| `@uniformdev/next-app-router-shared` | `next` 16.0.7 or later, `react` and `react-dom` 18.2 or 19 |

All three packages require Node.js 20.9 or later.

### @uniformdev/next-app-router

Server-only exports. The entry point imports `server-only`.

| Export | Description |
| --- | --- |
| `UniformComposition` | Resolves the route from a `[code]` and renders the composition in `UniformContext`. |
| `UniformResolvedComposition` | Renders the components of a resolver result. Renders nothing for a redirect or a not-found result. |
| `UniformContext` | Starts the browser Context, and adds the visual editing script and the edge state script. Render it one time on each page. |
| `UniformPlayground` | Renders a pattern from a `code` or a `result`. Draft mode only. |
| `resolveRouteFromCode` | Resolves the route in a code with the Route API. |
| `resolveRouteFromPath` | Resolves a path with the Route API. |
| `resolveCompositionById` | Gets a composition by ID with the Composition API. |
| `resolveCompositionBySlug` | Gets a composition by slug with the Composition API. |
| `resolvePlaygroundRoute` | Gets the pattern of a playground code. |
| `requireComposition` | Returns the composition, or calls `redirect()`, `permanentRedirect()` or `notFound()`. |
| `resolveRedirectHref` | Returns the target URL of a redirect result. |
| `deserializePageState` | Changes a code into a `PageState`. |
| `createUniformStaticParams` | Makes the codes for `generateStaticParams` of the `[code]` route. |
| `createUniformPlaygroundStaticParams` | Makes the codes for `generateStaticParams` of the playground route. |
| `createCompositionCache` | Makes a composition cache. |
| `serverContext` | Makes a getter and a setter for a value of one server request. |
| `findRouteMatch` | Matches a path to `:name` patterns. |
| `getCompositionDeliveryClient` | Composition API client with cache tags. |
| `getCanvasClient` | Deprecated. Use `getCompositionDeliveryClient`. |
| `getRouteClient` | [Route API client](https://docs.uniform.app/docs/sdk/route-client) with cache tags. |
| `getProjectMapClient` | [Project Map API client](https://docs.uniform.app/docs/sdk/project-map-client). |
| `getManifest` / `getManifestClient` | Context manifest access. |

Types: `UniformCompositionProps`, `UniformResolvedCompositionProps`, `UniformContextProps`, `UniformPlaygroundProps`, `UniformPageParameters`, `AwaitedUniformPageParameters`, `PlaygroundParameters`, `ResolveComponentFunction`, `ResolveComponentResult`, `ResolveRouteFunction`, `ResolveRouteFromCodeOptions`, `ResolveRouteFromPathOptions`, `ResolveCompositionByIdOptions`, `ResolveCompositionBySlugOptions`, `ResolveRedirectHrefOptions`, `PageStateSource`, `ResolvedRouteResult`, `ResolvedComposition`, `ResolvedCompositionResult`, `ResolvedRedirect`, `ResolvedNotFound`, `CreateStaticParamsOptions`, `CompositionCache`, `CustomRoute`, `RouteMatch`.

### @uniformdev/next-app-router/component

Component utilities for server and client components:

| Export | Description |
| --- | --- |
| `UniformSlot` | Renders the components of a slot. |
| `getUniformSlot` | Returns the rendered slot items as a `ReactNode` array. |
| `UniformText` | Renders a text parameter, with in-page editing in Canvas. |
| `UniformRichText` | Renders a rich text parameter. |
| `useUniformContext` | Hook: the browser Context instance. |
| `useQuirks` | Hook: the quirks of the visitor. |
| `useScores` | Hook: the scores of the visitor. |
| `createClientUniformContext` | Makes a browser Context. |
| `useInitUniformContext` | Hook: starts the browser Context. |

Types: `ComponentProps`, `ComponentParameter`, `ComponentContext`, `ClientContextComponent`, `UniformSlotProps`, `UniformTextProps`.

### @uniformdev/next-app-router/middleware

| Export | Description |
| --- | --- |
| `uniformMiddleware` | Returns a lite mode middleware. |
| `handleUniformRoute` | Handles one request in lite mode. |
| `resolveUniformRequest` | Returns the code, the destination and the headers for a request, for custom middleware. For a playground request, it can return a response. |
| `determinePreviewMode` | Returns `"editor"`, `"preview"` or `undefined` from the query strings and draft mode. |

Types: `HandleOptions`, `RewriteOptions`, `RewriteRequestPathOptions`, `ResolveUniformRequestOptions`, `ResolveUniformRequestResult`.

### @uniformdev/next-app-router/edge

| Export | Description |
| --- | --- |
| `uniformEdgeMiddleware` | Returns an edge mode middleware. |
| `handleUniformEdgeRoute` | Handles one request in edge mode. |
| `UNIFORM_EDGE_ORIGIN_HEADER` | `"x-uniform-edge-origin"`, the header of the origin fetch. |
| `learnedEdgeRouteFilter` | Skips the pages that the store recorded without placements. |
| `createStaticEdgeRouteFilter` | Processes only the paths that you list. |
| `createEdgeRouteStore` | Makes a store for edge route records. |
| `createCachedManifestProvider` | Makes a manifest provider that keeps the manifest in memory and in a shared cache. |

Types: `UniformEdgeMiddlewareOptions`, `EdgeRouteFilter`, `EdgeRouteFilterOptions`, `CreateStaticEdgeRouteFilterOptions`, `EdgeRouteStore`, `EdgeRouteStoreCache`, `EdgeRouteRecord`, `EdgeRoutePage`, `CreateEdgeRouteStoreOptions`, `RecordedPlacement`, `RecordedPersonalizationOptions`, `RecordedTestOptions`, `ManifestProvider`, `ManifestProviderOptions`, `ManifestCache`, `CreateCachedManifestProviderOptions`.

### @uniformdev/next-app-router/vercel

Install `@vercel/functions` for this entry point.

| Export | Description |
| --- | --- |
| `vercelUniformEdgeMiddleware` | Returns an edge mode middleware with the Vercel defaults. |
| `vercelManifestProvider` | A manifest provider that uses the Vercel runtime cache. |
| `vercelEdgeRouteStore` | An edge route store that uses the Vercel runtime cache. |
| `expireVercelRuntimeCacheTags` | Expires tags in the Vercel runtime cache. Give it to `onRevalidateTags`. |

Types: `VercelUniformEdgeMiddlewareOptions`.

### @uniformdev/next-app-router/cache

The resolvers with `'use cache'`, for [Cache Components](https://docs.uniform.app/docs/sdk/nextjs-app-router/caching#cache-components): `resolveRouteFromCode`, `resolveRouteFromPath`, `resolveCompositionById`, `resolveCompositionBySlug`.

### @uniformdev/next-app-router/config

| Export | Description |
| --- | --- |
| `withUniformConfig` | Wraps the Next.js configuration, and connects `uniform.server.config`. |
| `UniformServerConfig` | Type of the server configuration. |

### @uniformdev/next-app-router/handler

| Export | Description |
| --- | --- |
| `createPreviewGETRouteHandler` | GET handler: starts a Canvas preview. Options: `resolveFullPath`, `processPlaygroundPath`. |
| `createPreviewPOSTRouteHandler` | POST handler: receives Uniform webhooks. Option: `onRevalidateTags`. |
| `createPreviewOPTIONSRouteHandler` | OPTIONS handler: answers CORS preflight requests. |

Types: `CreatePreviewPOSTRouteHandlerOptions`.

### @uniformdev/next-app-router/compat

| Export | Description |
| --- | --- |
| `createAdapterResolveComponentFunction` | Makes a component resolver for adapted components. |
| `isAdaptedResolveComponentResultWithType` | Returns `true` for an adapted mapping. |
| `UniformText` | `UniformText` that takes `parameterId`. |

Types: `ComponentProps`, `ComponentContext`, `ResolveComponentResultWithType`, `AdaptedResolveComponentResultWithType`, `NonAdaptedResolveComponentResultWithType`, `UniformTextProps`.

### @uniformdev/next-app-router-client

Client-only exports. Use them for a custom client context.

| Export | Description |
| --- | --- |
| `createClientUniformContext` | Makes a browser Context. |
| `useInitUniformContext` | Hook: starts the browser Context, and updates it on each navigation. |
| `DefaultUniformClientContext` | The default client context component. |
| `useUniformContext`, `useQuirks`, `useScores` | The same hooks as in `/component`. |
| `EdgePlacement` | Renders a personalization or test in edge mode. The SDK uses it. |

Types: `ClientContextComponent`, `ClientContextComponentProps`.

### @uniformdev/next-app-router-shared

Types that the other packages use. The other entry points do not export these types.

| Export | Description |
| --- | --- |
| `PageState` | The values in a code. Refer to [PageState](#page-state). |
| `CompositionContext` | The composition data that each component gets in `context`. |
| `SlotDefinition` | A slot that each component gets in `slots`. |
| `RewriteRequestPathResult` | The return value of `rewriteRequestPath`. |
| `CacheMode`, `CanvasCacheMode`, `ManifestCacheMode`, `ProjectMapCacheMode` | The `cache` option of the server clients. |
| `PersonalizeProps`, `TestProps` | Props of the SDK placement components. |
| `UNIFORM_MIDDLEWARE_QUIRK_COOKIE_NAME` | `"ufqc"`, the cookie that sends quirks from the middleware to the browser. |

Install this package with the same version as `@uniformdev/next-app-router` if you import these types.

### @uniformdev/canvas

| Export | Description |
| --- | --- |
| `flattenValues` | Gets the values of asset parameters. |
| `AssetParamValue` | Type for asset parameter values |
| `LinkParamValue` | Type for link parameter values. It includes the optional `attributes` with the [custom link attributes](https://docs.uniform.app/docs/guides/models/components/parameters#link) of the author. |
| `RichTextParamValue` | Type for rich text parameter values |

### @uniformdev/canvas-react

| Export | Description |
| --- | --- |
| `linkParamValueToAnchorProps` | Changes a `LinkParamValue` into React anchor props. It makes the `href` (with anchors and the `mailto:` and `tel:` prefixes), adds the sanitized custom link attributes, and changes `class` to `className`. |

### @uniformdev/richtext

| Export | Description |
| --- | --- |
| `linkParamValueToHref` | Changes a `LinkParamValue` into an `href` string. |
| `linkParamValueToHtmlAttributes` | Changes a `LinkParamValue` into sanitized HTML attributes, for output that is not React. |

---

## Request types

The behavior of the SDK depends on the type of the request:

| Request | How the SDK finds it | What the middleware does | Composition state | Cached by Next.js | Who chooses the variants | Added for Canvas |
| --- | --- | --- | --- | --- | --- | --- |
| Published, lite mode | No draft mode. `uniformMiddleware`. | Rewrites to `/uniform/[code]`. | `64` | Yes | The browser, after hydration. The server renders the defaults. | Nothing |
| Published, edge mode, document | No draft mode. An edge middleware. A GET request for an HTML document. | Fetches the cached page with `x-uniform-edge-origin: 1`, and keeps the variants of the visitor. | `64`, with `edgeMode` | The origin page, yes. The response is `private`. | The edge middleware | Nothing |
| Published, edge mode, client navigation or prefetch | The `rsc` or `next-router-prefetch` header, or `Sec-Fetch-Dest: empty` | Rewrites only. | `64`, with `edgeMode` | Yes | The browser, before the new page paints | Nothing |
| Published, edge mode, skipped by the filter | The edge route filter answers `false`. | Rewrites only. | `64` | Yes | The browser, after hydration | Nothing |
| Origin fetch of the edge | The `x-uniform-edge-origin` header | Nothing. The matcher skips the request. | Same as the code | Yes | The edge middleware, after the fetch | Nothing |
| Draft (preview) | Draft mode is on. | Rewrites to `/uniform/[code]`. | `0` | No | The browser | The visual editing script |
| Editor (visual editing) | Draft mode is on, and the URL has `is_incontext_editing_mode`. | Rewrites to `/uniform/[code]`. | `63`, else `0` when there is no editor state | No | The browser | The visual editing script and the editing markers |
| Playground (pattern preview) | Draft mode is on, the path is `playgroundPath`, and the URL has `id`. | Rewrites to `${playgroundPath}/[code]`. Without `id`, it answers `400`. | `63`, else `0` | No | The browser | The visual editing script and the editing markers |

In the draft and editor states, the Route API ignores Uniform redirects. Visibility rules run in the browser for all request types.

## Type definitions

### ComponentProps

```ts
type ComponentProps<
  TParameters extends Record<string, ComponentParameter> | unknown = Record<string, ComponentParameter>,
  TSlotNames extends string = string,
> = {
  type: string;
  variant: string | undefined;
  slots: Record<TSlotNames, SlotDefinition>;
  parameters: TParameters;
  component: ComponentContext;
  context: CompositionContext;
};
```

### ComponentContext

```ts
type ComponentContext = {
  _id: string;
  _parentId: string | null;
  slotName: string | undefined;
  slotIndex: number | undefined;
};
```

### CompositionContext

```ts
type CompositionContext = {
  _id: string;
  type: string;
  state: number;
  isContextualEditing: boolean;
  matchedRoute: string;
  dynamicInputs: Record<string, string>;
  pageState: PageState;
};
```

### SlotDefinition

```ts
type SlotDefinition = {
  name: string;
  items: ({
    _id: string;
    $pzCrit: VariantMatchCriteria | undefined;
    variantId: string | undefined;
    component: ReactNode;
  } | null)[];
};
```

### ComponentParameter

```ts
type ComponentParameter<TValue = unknown> = BaseComponentParameter<TValue> & {
  parameterId: string;
  _contextualEditing?: { isEditable: boolean };
};
```

### PageState

```ts
type PageState = {
  compositionState: number; // 64 published, 0 draft, 63 editor
  routePath: string;
  keys: Record<string, string> | undefined;
  releaseId: string | undefined;
  defaultConsent: boolean;
  previewMode: "editor" | "preview" | undefined;
  locale: string | undefined;
  edgeMode?: boolean;
};
```

The code has the format `3~{state}~{route}~{keys}~{flags}~{releaseId}~{locale}`. The SDK removes empty fields at the end. Codes from version 20.81 (`2~…`) are not supported.

### ResolvedRouteResult

```ts
type ResolvedRouteResult =
  | { pageState: PageState; route: RouteGetResponseEdgehancedComposition }
  | { pageState: PageState; route: RouteGetResponseRedirect }
  | { pageState: PageState; route: undefined };
```

### ResolveComponentResult

```ts
type ResolveComponentResult = {
  component: ComponentType<ComponentProps<any, any>> | null;
  suspense?: {
    fallback: ComponentType<any> | undefined;
  };
};
```

### UniformServerConfig

```ts
type UniformServerConfig = {
  defaultConsent?: boolean;
  playgroundPath?: string;
  context?: {
    disableDevTools?: boolean;
    personalizationSelectionAlgorithms?: ContextPlugin["personalizationSelectionAlgorithms"];
  };
  quirkSerialization?: boolean;
};
```

### HandleOptions

```ts
type HandleOptions = {
  rewriteRequestPath?: (options: { url: URL; request: Request }) => Promise<{ path: string; keys?: Record<string, string> } | undefined>;
  rewriteDestinationPath?: (options: { source: "route" | "playground"; code: string; pageState: PageState }) => Promise<string>;
  queryStrings?: Record<string, string[]>;
  release?: { id: string };
  quirks?: Quirks;
  defaultConsent?: boolean;
  locale?: string;
};
```

### UniformEdgeMiddlewareOptions

```ts
type UniformEdgeMiddlewareOptions = HandleOptions & {
  manifest: ManifestV2 | ManifestProvider;
  onError?: (details: { error: unknown; chunk?: string }) => void;
  filter?: EdgeRouteFilter;
  store?: EdgeRouteStore;
  etags?: boolean;
};
```

### EdgeRouteFilter

```ts
type EdgeRouteFilter = {
  shouldProcess: (options: {
    pageState: PageState;
    waitUntil: (promise: Promise<unknown>) => void;
    getRecord: () => Promise<EdgeRouteRecord | undefined>;
  }) => boolean | Promise<boolean>;
};
```

### CreateStaticParamsOptions

```ts
type CreateStaticParamsOptions = {
  paths: string[];
  rewrite?: (options: { path: string }) => Promise<{ path: string; keys?: Record<string, string> } | undefined>;
  locale?: string;
  edgeMode?: boolean | EdgeRouteFilter | (boolean | EdgeRouteFilter)[];
  defaultConsent?: boolean | boolean[];
};
```

### CacheMode

The cache option of the [server clients](https://docs.uniform.app/docs/sdk/nextjs-app-router/server-clients):

```ts
type CacheMode =
  | { type: RequestInit["cache"] }               // "force-cache", "no-cache", "no-store" and so on
  | { type: "revalidate"; interval: number };    // revalidate after the interval, in seconds
```
