Your frontend remains your code. Gradial ACI (Agentic Content Infrastructure) connects to it through a small, explicit contract that defines where content belongs, which props each component accepts, and which runtime component renders each block. That boundary gives content teams flexibility without asking the CMS to understand framework internals. It also gives developers a reliable place to enforce component and layout rules.

The contract at a glance

Site configuration

.aci.yaml identifies the framework, source directories, contract registries, and CMS-managed route.

Component contracts

Zod schemas define stable component IDs and the props content may supply.

Layout contracts

Layouts define the regions a page can fill and optional fragment defaults.

Runtime registry

The registry pairs each component contract with the Astro or React component that renders it.

Configure the site

The .aci.yaml file lives at the project root. A generated Astro project starts with this shape:
The generated starter owns the framework integration around this file. In most projects, you only need to change the site identity, domain, source paths, or registry paths.
Keep siteId stable after the project is connected to an ACI site. Coordinate a change with your Gradial team so local configuration and hosted resources remain aligned.

Define a component contract

A component contract gives a content block a stable ID and validates its props. Keep the schema in a contract file that does not import your runtime component.
Use IDs that describe the component’s role and keep them stable. Content documents refer to home_hero directly, so renaming the ID is a content migration rather than a cosmetic code change. Export the contract from the component contract registry:

Keep contracts and runtime code separate

Contract extraction runs without loading your application runtime. That makes validation predictable across local development, preview, and publish. This separation does not duplicate your prop model. Export the inferred TypeScript type from the contract and use it in the runtime component.

Register the runtime component

The runtime registry pairs each contract with its implementation:
The contract registry and runtime registry serve different jobs:
  • src/cms/contracts/components/index.ts exposes schemas for compilation and validation.
  • src/cms/registry.ts tells the framework which component to render after content has passed validation.

Define a layout contract

Layouts name the regions available to a page. Mark a slot as required by passing true as the second argument to slot.
Here, every page must provide a main region. If a page does not provide header or footer, ACI uses the named fragments as defaults.

Author content against the contract

A page names the layout, then places registered component blocks in its regions:
During compilation, ACI checks that:
  • the layout exists;
  • region names match layout slots;
  • required regions are present;
  • component IDs exist in the contract registry;
  • props satisfy the component’s Zod schema; and
  • referenced fragments and assets can be resolved.
Run the same checks locally:

Evolve a contract safely

Adding an optional prop is usually backward compatible. Making a field required, narrowing allowed values, or renaming a component ID can invalidate existing content. For a breaking change:
  1. Update the contract and runtime component together.
  2. Update every affected page, fragment, and overlay.
  3. Compile the full content tree.
  4. Run the project’s type and conformance checks.
  5. Preview the change before it is approved and published.
This keeps the frontend contract useful as a release boundary, not just a TypeScript convenience.
Next: Framework guides →