Skip to main content

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.

The API Builder turns your Data Storages into the exact API surface each part of your experience needs.
API Builder overview showing a list of Detail Blocks and Search Listings
One block per component, one listing per collection, one page per route, one tree per hierarchy — nothing more, nothing less. Your frontend asks for what it needs, and the backend returns exactly that, already scoped to the caller’s request context.
Buddy can create and configure Detail Blocks, Search Listings, and Page URLs for you. Describe what your experience needs and Buddy handles the setup.

The primitives

Detail Blocks

What fields does this component need? An API endpoint that returns the exact data one UI component needs — reusable, parameterized, nestable.

Search Listings

How do I query a collection? Filtering, sorting, full-text search, pagination, and facets — each item shaped like a block.

Page URLs

What renders at this URL? Ties a URL pattern to a Detail Block so your router resolves content in a single request.

Menu Trees (Preview)

What’s the hierarchy? Returns records as a tree — navigation menus, category hierarchies, anything with a parent/child structure.

How they compose

Define Blocks for each UI component

A Detail Block is an API endpoint shaped like a component. For a product hero, you define a ProductHero block with a schema that returns exactly the fields that component renders — image, title, price, badges, CTA text. The block connects to a Data Storage and describes which fields map into its response shape.

Define Listings for collections

A Search Listing returns lists of items, where each item is block-shaped. A ProductList listing might take a category filter parameter and return a list of ProductCard-shaped items, with facets and pagination attached. Listings handle the query layer — filter, sort, search, paginate — and delegate the per-item shape to the block.

Define Pages to wire it all to URLs

A Page URL ties a URL pattern to a single Detail Block. Each URL resolves to exactly one block record. The response includes the page type and the matching data, so your frontend router can pick the right component and render it straight away. The block itself can contain nested listings if the page needs collections.

Request Context

Every Detail Block, Search Listing, and Page URL response is shaped by the caller’s request context. That means one block can serve many markets, many audiences, and many languages from a single definition. Request context is a combination of three values that together tell the backend who’s asking:

Scope

The audience variant — B2B vs. B2C, different brands, wholesale vs. retail.

Region

The geography — which locales are supported, which currency applies.

Locale

The language (en, de, fr) — translatable fields return the matching variant.

Where context comes from

Your project maps domains (or paths) to scope + region + locale combinations in Project Settings → Domains. Pass the domain as contextDomain and Frontic resolves the matching context automatically.
const data = await client.block('CategoryDetail', 'running-shoes', {
  contextDomain: 'www.demo-shop.com/de',
});
// Resolves → German region, de locale, public scope
A typical domain mapping:
DomainScopeRegionLocale
www.demo-shop.compublicUnited States (USD)en
www.demo-shop.com/depublicGermany (EUR)de
b2b.demo-shop.comb2bUnited States (USD)en

Why this matters

  • A ProductList listing in the German domain returns the German product catalog in EUR with German copy — without market-specific code.
  • A ProductCard block in a B2B scope returns B2B-specific images, descriptions, and pricing for the same product — without a separate B2B block.
  • A Page at /products/:slug resolves to different URLs and different records in every domain — without duplicate route definitions.
You write each primitive once. The backend delivers the right variant based on who’s asking.

Handle context keys

Every response includes a contextKey in the fs-context header. This key tracks the session’s context settings — scope, region, locale — and lets overrides survive across requests.
  • No key sent → Frontic generates a new one with the settings from the resolved domain and returns it in the response
  • Your own key sent (any string, 36–50 characters) → Frontic persists it with the current context settings if it doesn’t exist yet, or loads the stored settings if it does
  • Key sent on subsequent requests → Frontic applies the stored settings, even if they differ from the domain default
Store the key from the first response and pass it on every subsequent request. When a visitor switches language or currency, update the key’s settings — all following requests reflect the change without touching the domain mapping.

Updating an existing contextKey

To change a visitor’s active locale or region without minting a new key, update the stored settings on the current contextKey — the Client SDK and the Nuxt module both expose methods for this so you don’t hand-craft the HTTP call. Every subsequent request using the same key reflects the change.
await client.contextUpdate(
  { region: 'eu', locale: 'de-DE' },
  contextKey,
);
Common triggers:
  • A visitor opens a language selector and switches from en to de — update the key with the new locale.
  • A visitor picks a different market from a region dropdown (United States → Rest of Europe) — update the key with the new region; currency follows the region’s setting.
  • A visitor updates their preferences on a profile screen — update whichever settings changed.

Missing or ambiguous context

If a request has no contextDomain or the domain doesn’t match any configured mapping, Frontic falls back to the project’s default region and locale. A missing contextKey is never an error — Frontic creates a new one automatically. An unknown key is treated the same way: persisted as a fresh context with the current domain settings. The only invalid key is one that doesn’t meet the format requirements (36–50 characters).

API Playground

Preview — this feature is being rolled out.
Every Detail Block and Search Listing has a built-in API Playground accessible from its detail page. It lets you send real requests against your backend, inspect responses, and experiment with context, filters, and parameters — without writing code or leaving the admin app. The playground shows the full endpoint URL, lets you configure headers (fs-version, fs-secret, fs-domain, fs-context), and generates ready-to-use code snippets from your current configuration. See Detail Blocks and Search Listings for the full details.
API Playground dialog showing request configuration on the left with parameters, filters, and sorting, and JSON response on the right with status and timing badges

Shipped through Releases

Changes to blocks, listings, and pages flow through Releases alongside Data Storage schema changes, Data Sync changes, and project settings. You don’t ship API changes piecemeal — you bundle everything that changed into a release and roll it out together, with preview and rollback.

Where to go next

Build a Block

Schema, parameters, storage connection, nesting — everything blocks can do.

Build a Listing

Filters, sorts, search, facets, and pagination.

Build a Page

Routing, URL patterns, localization, error handling.