Skip to content
brix.v2 stable

Search documentation

70 guides

Documentation menu

Contentful Type Generation

Generate deterministic TypeScript types from published Contentful content models, then use the resulting map to type Delivery queries and rendering adapters.

Generate the model

Provide a Content Management API token through your secret manager. The command accepts exactly --space, --out, and the optional --environment flag:

export CONTENTFUL_CMA_TOKEN=<cma-token>
brix contentful typegen \
  --space <space-id> \
  --environment master \
  --out src/contentful-types.ts

--space and --out are required. --environment defaults to master, and parent directories for --out are created. Typegen reads published content types, so unpublished draft models are excluded. Regenerate after model changes and do not hand-edit the output.

The generated file sorts models deterministically, omits fields marked as omitted, turns Symbol validations into string unions, resolves validated entry links to entry unions, and exports ContentTypeMap:

import { createContentfulClient } from "brix/contentful";
import type { ContentTypeMap } from "#/contentful-types.ts";

const contentful = createContentfulClient<ContentTypeMap>({
  spaceId,
  accessToken,
});

The map types content-type IDs, fields, filters, clients, and adapter definitions. It is compile-time guidance; Delivery responses still receive structural envelope validation rather than runtime validation against every generated field type.

Use resource types

brix/contentful exports Entry<T>, Asset, RichTextDocument, ContentfulCollection<T>, deletion stubs, schema types, query option types, and Contentful system/link metadata. Raw sync results intentionally contain mixed resource kinds. Narrow them with the supplied guards:

import { isAsset, isDeletedAsset, isDeletedEntry, isEntry } from "brix/contentful";

if (isEntry(resource)) {
  console.log(resource.fields);
} else if (isAsset(resource)) {
  console.log(resource.fields.file);
} else if (isDeletedEntry(resource) || isDeletedAsset(resource)) {
  console.log(resource.sys.id);
}

These guards identify the resource shape, not an application-specific entry interface. Use the generated map with typed client methods for model-specific fields.