Configuration
Headcode CMS projects are structured around entries, sections, and fields.
This configuration defines what content exists, how it’s grouped, and how editors interact with it inside the Headcode Admin.
1. Project Structure
A Headcode CMS project consists of:
Entries: Identified by a namespace and key.
Sections: Each entry can include one or multiple sections.
Fields: Each section defines a set of editable fields.
Entries
An entry represents a piece of content — for example, a page, blog post, navigation menu, or footer.
Entries can be either static or dynamic:
Static entries exist once per project, for example:
namespace: "global", key: "nav" (main navigation)
namespace: "global", key: "footer"
Dynamic entries allow multiple instances within the same namespace, for example
namespace: "blog", key: "post-1", post-2, post-3, etc.
You create dynamic entries directly in the Headcode Admin, while static entries are predefined in the config.
2. The headcode.config.ts File
The configuration of entries and sections lives in headcode.config.ts.
Here’s an example configuration file:
export const headcodeConfig: HeadcodeConfig = { version: 'v02', clone: 'v01', entries: [ { namespace: 'global', key: 'nav', sections: [{ section: navSection, pinned: true }], }, { namespace: 'global', key: 'footer', sections: [{ section: footerSection, pinned: true }], }, { namespace: 'blog', sections: [ { section: metaSection, pinned: true }, { section: heroSection }, { section: textSection }, { section: imageSection }, ], }, ],};Configuration Details
version: The current content version of your project.
clone (optional): Indicates which version this is cloned from (useful for versioning content).
pinned sections: Sections marked as pinned: true are always included in the entry and cannot be deleted in the admin. Useful for required data, like metadata or summaries.
dynamic namespaces: Namespaces without a key (like blog) are dynamic. Their entries are created in the Headcode Admin.
3. Defining Sections
Sections define reusable content blocks, similar to structured components or slices. Each section defines a name, label, and a set of fields that editors can modify.
Here’s a simple example of a heroSection:
export const heroSection = { name: 'hero', label: 'Hero Section', fields: { title: TextField({ label: 'Title', }), subtitle: TextareaField({ label: 'Subtitle', }), primaryButton: LinkField({ label: 'Primary Button', }), } satisfies Fields,};export type HeroData = InferSectionData<typeof heroSection.fields>;4. Rendering a Section Component
To render the content on your site, parse the section data with the Headcode CMS helper and pass it into your component:
export function Hero({ sectionData }: { sectionData: unknown }) { const { data } = parseSectionData(heroSection.fields, sectionData); return ( <div> <h1>{data.title}</h1> <p>{data.subtitle}</p> <Button href={data.primaryButton.url}> {data.primaryButton.title} </Button> </div> );}5. Next Steps
Now that your configuration is set up, you can:
Add or modify entries in headcode.config.ts.
Create or re-use sections from existing themes.
Define custom field types.
Explore how to create themes and section UIs in the next guide.