Short answer
The content model is the only part of a headless build that is expensive to change later. Front ends get rewritten in weeks; a content model with three thousand entries in it becomes a migration project. Model what content is, keep presentation out of it, and use references rather than duplicated strings.
Contentstack gives you content types, modular blocks, global fields, references and locales. The tooling is good. Almost every problem teams hit later traces back to modelling decisions made in the first fortnight.
Model meaning, not layout
The pressure to mirror the current design is strong, because the design is what everyone can see. It produces fields like hero_left_heading and cta_button_colour, and the moment the design changes those fields are either wrong or meaningless.
| Presentation-coupled | Meaning-based | Why it matters |
|---|---|---|
hero_left_text |
summary |
Survives moving the hero |
sidebar_items |
related_articles |
Reusable in any layout |
button_colour |
emphasis (enum) |
Front end owns colour |
image_desktop / image_mobile |
image + focal point |
Responsive is a rendering concern |
The test: if a field’s value would need to change because the CSS changed, it is in the wrong system.
Modular blocks are for composition
Modular blocks let an editor assemble a page from an ordered list of typed sections, which is the right shape for landing pages and long-form articles. Two failure modes are common.
Too few block types produces a “generic section” block with twenty optional fields, where the meaning depends on which combination happens to be filled in. Nobody can render it reliably and nobody can tell what a given entry will look like.
Too many block types produces forty near-identical blocks that differ only in spacing, each requiring a component, tests and documentation.
Aim for a curated set — typically eight to fifteen — where each block answers a distinct content question. Use enum fields inside a block for presentational variants rather than creating a new block type.
References over duplication
An author’s name typed into every article is a string that will drift: someone updates one, misspells another, and there is no way to fix them in bulk. An author reference is a single entity with one canonical value.
Use references for anything that is genuinely an entity — authors, products, locations, categories, reusable calls to action. Use global fields for repeated groups of fields that are not entities, such as an SEO block, so the shape stays consistent across content types without duplicating field definitions.
The trade-off is fetch depth. Deeply nested references mean either multiple round trips or an expensive single query. Keep reference chains shallow — two levels is comfortable, four is a performance problem — and denormalise deliberately where a value is genuinely immutable.
Localisation is a modelling decision
Contentstack’s locale fallback means a field left empty in fr-fr inherits from the master locale. That is convenient and it is also how a half-translated page reaches production looking finished.
Decide per field which behaviour you want, and mark fields non-localisable when they genuinely should not vary — a product SKU, an ISO date, a reference to a shared entity. Marking everything localisable creates translation work that will never be completed and cannot be distinguished from work that is simply pending.
Validation belongs in the model
Every constraint you can express in the content type is a class of bug the front end never has to handle:
- Required fields — so a component never receives
undefinedfor something it must render. - Character limits on titles and summaries, matched to what the design can actually display.
- Enums rather than free text for anything the front end switches on. A typo in a free-text variant field is a silently broken component.
- Regex validation on slugs and identifiers.
- Minimum and maximum counts on multiple fields, so a carousel gets between three and eight items rather than one or forty.
Version the model like code
Content types are configuration and belong in version control. Export them as JSON, commit them, and promote changes through environments rather than editing production directly. Contentstack’s CLI supports this, and it is the difference between a reviewable change and someone adding a required field at 4pm and breaking every unpublished entry.
Adding an optional field is safe. Making a field required, changing its type, or deleting it are migrations — they need a plan for existing entries, and the plan should exist before the change.
A model that holds up
For a typical content site:
- Entity types — Author, Category, Product. Referenced, never duplicated.
- Page types — Article, Landing Page. Composed from modular blocks.
- Global fields — SEO metadata, Open Graph, analytics identifiers. Attached to every page type.
- Block library — a curated set of section types with enum-based variants.
- Settings singleton — navigation, footer, site-wide defaults, in one entry.
Wiring this into a front end, including live preview and webhook-driven revalidation, is covered in Contentstack and Next.js. The general trade-offs of decoupling are in Building Scalable Headless CMS & Gutenberg Architectures.
Questions people actually ask
- Modular blocks or separate content types for page sections?
- Modular blocks when sections are composed inline and belong to one page. Separate content types with references when a section is genuinely reusable across pages and should be edited in one place. Using references for one-off sections adds navigation overhead for editors with no benefit.
- How many content types is too many?
- There is no fixed number, but if two types differ by one optional field they should probably be one type with an enum. Conversely, if a single type needs conditional logic in the front end to work out what it represents, it should be split. Optimise for editors being able to predict what they will get.
- Can I change a field type after launch?
- Not safely in place. Add a new field, migrate existing entries with the CLI or Management API, update the front end to read the new field with a fallback, then remove the old one once nothing references it. Treat it as a migration with a rollback path, not a settings change.
- How deep should reference chains go?
- Two levels comfortably, three with care. Beyond that you are paying for expensive nested resolution on every request, and a change anywhere in the chain invalidates a large amount of cached content. If you need more depth, fetch in stages and cache each stage separately.
- Should SEO metadata be a global field?
- Yes. A single SEO global field attached to every page type keeps title, description, canonical and social image consistent, gives the front end one shape to render, and means adding a new metadata field is one change rather than one per content type.