> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frontic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Client SDK

The Client SDK is generated specifically for your project using the [Frontic CLI](https://docs.frontic.com/reference/frontic-cli.md). Every block, listing, page, and context endpoint your project exposes becomes a typed method on the generated client.

![Client SDK Hero](https://mintcdn.com/frontic/34vlQbUxJTTktEkF/images/hero-sdk.png?fit=max\&auto=format\&n=34vlQbUxJTTktEkF\&q=85\&s=1352b1d7173879da7b0afdc6b2600df9)

> [card] [Generate Client SDK](https://docs.frontic.com/reference/frontic-cli.md)
>
> Run `frontic generate` to produce the typed client for your project - see the CLI reference for the full command.

> [!TIP]
>
> Looking for the raw HTTP surface - for a non-JS backend, a custom proxy, or curl debugging? See the [Fetch API reference](https://docs.frontic.com/reference/fetch-api.md). The SDK is a typed wrapper over those endpoints.

## Initialization

The generated client supports two initialization patterns.

> [!NOTE]
>
> The [Nuxt module](https://docs.frontic.com/reference/nuxt-module.md#typescript) needs a client generated with a current CLI. If it warns at build time that your client is outdated, run `frontic generate` again.

### Direct import

For the simplest case - no proxy, no global config:

```ts theme={"theme":"css-variables"}
import client from "./.frontic/generated-client";

const data = await client.block("ProductCard", "<product-id>");
```

### Factory with configuration

For projects that need a global proxy URL (e.g. browser-side requests routed through your own server to avoid CORS):

```ts theme={"theme":"css-variables"}
import { createClient } from "./.frontic/generated-client";

const client = createClient({
  proxyUrl: "https://www.demo-shop.com/api/frontic",
  // or with relative path (does NOT work on server side):
  proxyUrl: "/api/frontic",
});

const data = await client.block("ProductCard", "<product-id>");
```

### Server-side with a secret

If your project's Fetch API is [protected by a secret](https://docs.frontic.com/reference/fetch-api.md#fetch-api-secrets), pass it to server-side clients. The client sends it as `fs-secret` on every request:

```ts server/frontic.ts theme={"theme":"css-variables"}
import { createClient } from "./.frontic/generated-client";

export const client = createClient({
  secret: process.env.FRONTIC_FETCH_SECRET,
});
```

> [!WARNING]
>
> Only set `secret` in code that runs on your server. A browser client ships the value to every visitor - and it is still sent when `proxyUrl` is set, so a browser client routed through your proxy must not carry it either. Let the proxy add the header instead.

## Configuration

### `createClient(config?)`

Create a configured client instance.

#### Parameters

**config** `object`

Global configuration options.

**Properties**

**proxyUrl** `string`

Proxy URL used for all requests (e.g. `/api/frontic`). The client concatenates this with the original API path. The proxy should forward requests to the URL in the `fs-target-url` header. Useful for preventing browser CORS issues.

**secret** `string`

[Fetch API secret](https://docs.frontic.com/reference/fetch-api.md#fetch-api-secrets), sent as `fs-secret` on every request from this client. No header is sent when unset. **Server-only** - see [Server-side with a secret](#server-side-with-a-secret). A request's own `config.secret` overrides it.

#### Returns

**client** `Client`

A configured client instance with all client methods.

## Methods

Every method below shares the same `config` object as a final argument, used to override per-request behaviour. The shared options are listed once here and referenced from each method.

### Shared `config` object

Every method takes an optional `config` object as its final argument. Not every field applies to every method - the table below in each method's section calls out which ones are honoured.

**config** `object`

Per-request overrides. Optional.

**Properties**

**requestUrl** `string`

Full URL of the page making the request. Drives domain-based [Request Context](https://docs.frontic.com/api-builder/overview.md#request-context) resolution and is also used for tracking. Sent as `fs-request-url`.

**contextKey** `string`

A token that identifies the visitor's persistent context state (region, locale). 36–50 characters. Takes precedence over `contextDomain`. Sent as `fs-context`.

**contextDomain** `string`

The domain whose configured region and locale should resolve the request. A `contextKey` (if set) takes precedence. Sent as `fs-domain`.

**proxyUrl** `string`

Proxy URL used for this request, overriding any global configuration.

**secret** `string`

Fetch API secret for this request, overriding the client's `secret`. Sent as `fs-secret`. **Server-only.**

### `client.block`

Fetch a [Detail Block](https://docs.frontic.com/api-builder/blocks.md) by its key.

#### Parameters

**name** `string` *required*

The block name. Example: `'ProductCard'`.

**key** `string` *required*

The record key. Example: `'sku-12345'`.

**config** `object`

See [shared `config` object](#shared-config-object).

#### Returns

**data** `Block\<ApiName\>`

The block payload, fully typed against the project's API surface.

#### Example

```ts Client SDK theme={"theme":"css-variables"}
const data = await client.block("ProductCard", "<product-id>", {
  requestUrl: "https://demo-shop.com/snowboards",
  contextKey: "<context-key>",
});
```

### `client.listing`

Fetch a [Search Listing](https://docs.frontic.com/api-builder/listings.md) with optional parameters and query options.

#### Parameters

**name** `string` *required*

The listing name. Example: `'CategoryListing'`.

**parameters** `object`

Listing parameters. Shape depends on the listing's parameter definition.
Example: `{ categoryId: '<category-id>' }`.

**config** `object`

Per-request overrides plus listing-specific query options.

**Properties**

**query** `object`

Query options applied to the listing.

**query properties**

**filter** `array | object`

One or more filter expressions, e.g. `{ type: 'equals', field: 'color', value: 'Red' }`.

**sort** `array | object`

Sort expression(s), e.g. `{ field: 'publishedAt', order: 'asc' }`.

**search** `string`

Free-text search query.

**limit** `number`

Maximum number of results.

**page** `number`

Page index for pagination.

**requestUrl** `string`

See [shared `config` object](#shared-config-object).

**contextKey** `string`

See [shared `config` object](#shared-config-object).

**proxyUrl** `string`

See [shared `config` object](#shared-config-object).

#### Returns

**data** `Listing\<ApiName\>`

The listing payload - items, pagination metadata, applied filters, available facets.

#### Example

```ts Client SDK theme={"theme":"css-variables"}
const data = await client.listing(
  "CategoryListing",
  { categoryId: "<category-id>" },
  {
    query: {
      filter: { type: "equals", field: "color", value: "Red" },
      sort: { field: "publishedAt", order: "asc" },
    },
    requestUrl: "https://demo-shop.com/sunglasses",
    contextKey: "<context-key>",
  },
);
```

### `client.tree`

Fetch a [Menu Tree](https://docs.frontic.com/api-builder/trees.md) - a hierarchical collection of records assembled from a Data Storage and rendered through a Detail Block.

#### Parameters

**name** `string` *required*

The tree's API name. Example: `'CategoryNavigation'`.

**config** `object`

Tree-specific query options plus the [shared `config` object](#shared-config-object).

**Properties**

**query** `object`

**query properties**

**key** `string`

Optional starting node. When provided, the response returns the node with this key plus its descendants. Example: `{ key: 'shop' }`.

**depth** `number`

Optional level limit. Controls how many levels of `$items` are included. Example: `{ depth: 2 }`.

#### Returns

**tree** `Tree\<ApiName\>`

An `items` array of root-level nodes, each carrying its subtree on `$items`. Every node's shape (beyond `$items`) is defined by the tree's connected Detail Block.

#### Example

```ts Client SDK theme={"theme":"css-variables"}
// Full tree
const tree = await client.tree("CategoryNavigation");

// Subtree from a specific node, 2 levels deep
const subtree = await client.tree("CategoryNavigation", {
  query: { key: "shop", depth: 2 },
});
```

### `client.page`

Fetch a [Page](https://docs.frontic.com/api-builder/pages.md) by its slug.

#### Parameters

**slug** `string` *required*

The URL slug of the page (without protocol). Example: `demo-shop.com/uk/women/shoes/running`.

**config** `object`

See [shared `config` object](#shared-config-object).

#### Returns

**page** `Frontic.Page`

The page payload - `data`, page `type`, and any alternate `urls`.

#### Example

```ts Client SDK theme={"theme":"css-variables"}
const pageData = await client.page("demo-shop.com/uk/women/shoes", {
  requestUrl: "https://demo-shop.com/uk/women/shoes",
  contextKey: "<context-key>",
});
```

### `client.sitemap`

Fetch a Sitemap. The [Nuxt module](https://docs.frontic.com/reference/nuxt-module.md#sitemap) can serve the sitemap route from your app automatically.

#### Parameters

**domain** `string` *required*

The project domain for which you want the sitemap.

**index** `number`

The index of a nested sitemap (only if the sitemap was split up).

**config** `object`

The [shared `config` object](#shared-config-object).

#### Returns

The XML content of the sitemap.

#### Example

```ts Client SDK theme={"theme":"css-variables"}
const sitemap = await client.sitemap("demo-shop.com/uk");

const nestedSitemap = await client.sitemap("demo-shop.com/uk", 1);
```

### `client.context`

Fetch a context by its token.

#### Parameters

**token** `string` *required*

The `contextKey` to look up. Example: `'ae0d4981-c363-4d5a-a49e-1f053d49f2f7'`.

**config** `object`

See [shared `config` object](#shared-config-object).

#### Returns

**context** `Frontic.Context`

The context - `region`, `locale`, `scope`, `token`.

#### Example

```ts Client SDK theme={"theme":"css-variables"}
const context = await client.context("<context-key>");
```

### `client.contextList`

List the available contexts (region + currency + locales) for the project, optionally filtered by an existing context token.

#### Parameters

**token** `string`

The `contextKey` whose project + scope context variations are returned. Optional.

**config** `object`

See [shared `config` object](#shared-config-object).

#### Returns

**contexts** `Frontic.ContextOption[]`

Array of context options (region, currency, supported locales with URLs).

**token** `string`

The active `contextKey`, returned in the `fs-context` response header.

#### Example

```ts Client SDK theme={"theme":"css-variables"}
const [contexts, token] = await client.contextList("<context-key>");
```

### `client.contextUpdate`

Update an existing context's region and locale on the Frontic server. Subsequent requests using the same `contextKey` reflect the change.

#### Parameters

**context** `object` *required*

The context fields to update.

**Properties**

**region** `string` *required*

The region key, e.g. `eu`.

**locale** `string` *required*

The locale key, e.g. `de-DE`.

**token** `string` *required*

The `contextKey` to update.

**config** `object`

See [shared `config` object](#shared-config-object).

#### Returns

**context** `Frontic.Context`

The updated context.

#### Example

```ts Client SDK theme={"theme":"css-variables"}
await client.contextUpdate(
  { region: "eu", locale: "de-DE" },
  "<context-key>",
);
```

#### Response

```json Response theme={"theme":"css-variables"}
{
  "region": "eu",
  "locale": "de-DE",
  "scope": "public",
  "token": "ae0d4981-c363-4d5a-a49e-1f053d49f2f7"
}
```

## Types

Framework types - pages, context, filters, sorting, pagination - live under the `Frontic` namespace in the generated types, so they never collide with a Data Type of the same name. Your own response types, such as `ProductCard`, are global.

```ts theme={"theme":"css-variables"}
import type { Frontic } from "./.frontic/generated-types";

function renderPage(page: Frontic.Page) {
  // …
}
```

## Error handling

A method rejects when the Fetch API answers with an error status, or when the request fails or times out before a response arrives. The generated client exports `FronticFetchError`, the type of what it rejects with:

```ts theme={"theme":"css-variables"}
import client, { type FronticFetchError } from "./.frontic/generated-client";

try {
  await client.block("ProductCard", "<product-id>");
} catch (e) {
  const error = e as FronticFetchError;
  if (error.data && "code" in error.data && error.data.code === "KEY_NOT_FOUND") {
    // Handle the missing record
  }
}
```

TypeScript types every `catch` variable as `unknown`, so assert the type as shown, or pass it as the error type to a data-fetching library.

The response body is on `error.data`, typed from your project's spec as the [error bodies](https://docs.frontic.com/reference/fetch-api.md#errors) the Fetch API returns: `ApiError` for a deliberate failure and `InternalError` for a server fault. `code` is the discriminant - it is present exactly when the failure was deliberate, so narrowing on it gives you the right shape. Branch on `code`, never on `error`, whose wording is not stable.

Read the body rather than checking `instanceof`: only `data` survives server-side rendering, and the error class is not guaranteed to match across bundles. A failure without a response, such as a timeout, carries no `data`.

> [!NOTE]
>
> Using the Nuxt module? It narrows the body for you - see [Error handling](https://docs.frontic.com/reference/nuxt-module.md#error-handling).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.