Architecture & Governance
Content Modeling for CMS: Entities, Relationships, and Reusable Blocks for SaaS
A practical, CMS-agnostic standard for modeling content that scales. Define entities and fields, map relationships, design reusable blocks, plan localization and versions, and publish clean APIs that support websites, docs, product, and AI retrieval.
Objective and scope
This standard creates an entity-first content model for SaaS. It covers inventory, fields, relationships, reusable blocks, localization, versioning, API contracts, schema alignment, workflow, migration, and performance. The outcome is simple: a model that ships pages faster, keeps names and data consistent, and works for web, docs, sales, and AI retrieval.
Keep it CMS-agnostic. The shapes here map to most headless and traditional CMSs. Use vendor features only when they do not lock your data or URLs.
Modeling principles
One concept per content type
Define types for Feature, Solution, Integration, Case Study, Guide, FAQ, and Glossary Term. Do not overload a single type with unrelated fields.
Few, well named fields
Prefer clear, atomic fields to giant rich text blobs. Use rich text only where you truly need mixed content.
Explicit relationships
Relate entities with fields like features, solutions, integrations. Avoid free form linking in body text for navigation-critical paths.
Stable IDs and slugs
Use UUIDs for entries and human slugs for URLs. Keep slugs stable. If a slug must change, log a redirect.
Reusable blocks
Use components for testimonials, stats, CTAs, product callouts, and FAQs. Consistency improves speed and measurement.
Separation of content and presentation
Keep design choices in code or theme tokens. Store only semantic data and intent in the CMS.
Entity inventory
Start by listing the core entities you publish and how they connect.
Core marketing
- Feature
- Solution
- Pricing Plan
- Case Study
- Resource (guide, template, tool)
Product and ecosystem
- Integration
- Release Note
- API Endpoint or Doc Page
- Glossary Term
Support and trust
- Security Policy
- Status Update
- Compliance Artifact
- Changelog Item
Example high level model
{
"Feature": { "fields": ["name","slug","summary","benefits[]","proof","cta","relatedFeatures[]"] },
"Solution": { "fields": ["name","slug","audience","pains[]","outcomes[]","features[]","caseStudies[]","cta"] },
"Integration": { "fields": ["vendor","slug","summary","useCases[]","setupSteps[]","docsUrl","relatedFeatures[]"] },
"CaseStudy": { "fields": ["company","slug","industry","problem","solution","metrics[]","quote","assets[]","relatedFeatures[]"] },
"Guide": { "fields": ["title","slug","intro","sections[]","faq[]","relatedGuides[]"] },
"Glossary": { "fields": ["term","slug","definition","aliases[]","relatedTerms[]"] }
}Field standards
Field names and types should be boring and predictable. Validation rules save hours later.
| Field | Type | Validation | Notes |
|---|---|---|---|
| name, title, term | text | max 80 chars | Display name in H1 |
| slug | text | lowercase, hyphens, unique | URL segment |
| summary, intro | text | max 200 chars | Meta description seed |
| body | rich text | headings allowed | Use sparingly |
| benefits, outcomes, pains | list | 3 to 7 items | Short bullets |
| metrics | list of objects | value, unit, context | Use for case studies |
| assets | media | images, pdf | Alt text required |
| related* | reference | min 0 max n | Typed relationships |
Use short, consistent labels. Keep enumerations documented so teams do not invent new values on the fly.
Relationship rules
Relationships connect the model. Define cardinality, ownership, and how links render in navigation.
Cardinality
- Solution has many Features
- Feature has many Case Studies
- Integration has many Features and Guides
- Glossary Term has many related Terms
Ownership
- The child decides visibility on the parent or vice versa. Pick one rule and stick to it
- If a Case Study tags a Feature, render the Case Study on that Feature
- Avoid circular dependencies that require double edits
Rendering rules
- Limit related lists to 3 to 6 items with curated order
- Use descriptive anchors that match target H2s
- Expose relationships in the API to power hubs and TOCs
Reusable blocks and components
Components reduce duplication and make pages consistent. Store them as separate content types or embedded objects.
Common components
- Testimonial (quote, name, title, company, logo)
- Stat (value, unit, label, sourceUrl)
- CTA (label, href, style, trackingId)
- FAQ (question, answer)
Placement rules
- Top CTA and end CTA per page
- Stats near proof sections
- FAQ near objections
Measurement fields
- trackingId on CTAs
- sourceUrl on Stats
- evidenceId for Case Study metrics
Component shape example
{
"component": "cta",
"label": "Start a free trial",
"href": "/trial/",
"style": "primary",
"trackingId": "cta_trial_article_top"
}Localization and variants
Plan locale strategy in the model. Keep relationships intact across locales.
Locale model
- Store a locale code per entry version
- Mirror relationships per locale
- Fallback rules for missing fields
Copy rules
- Translate slugs or use stable IDs with localized titles
- Keep product names and metrics consistent
- Do not auto translate legal or pricing without review
Implement hreflang on the site level. See Google guidance on localized versions for reciprocal links and x default.
Versioning and environments
Docs and APIs often require versioned content. Marketing sometimes needs drafts and release toggles.
Docs version
- Use a version field and path like /docs/v2/
- Keep one default version
- Forward users to latest when context allows
Release toggles
- Boolean flags like isPublic or date based publishAt
- Hide incomplete features behind flags until GA
Environments
- Separate content spaces for dev, staging, prod
- Automated promotion with validation checks
API contracts and queries
Your model is only useful if it is easy to query. Define a stable contract so front ends and tools do not break when fields are added.
REST shape
GET /api/features/{slug}
{
"id": "uuid",
"name": "Role-based Access",
"slug": "role-based-access",
"summary": "Control access by role.",
"benefits": ["Fewer errors","Faster onboarding"],
"relatedFeatures": [{"name":"SSO","slug":"sso"}]
}GraphQL example
query Feature($slug:String!) {
feature(where:{slug:$slug}) {
id name slug summary
benefits
relatedFeatures { name slug }
}
}Contract rules
- Never remove fields. Deprecate and add a new one
- Provide pagination and filtering for lists
- Expose relationships in both directions where useful
Schema and knowledge alignment
Map content types to schema.org where it fits. Do not mark up anything that is not visible on the page.
Article and FAQ
Use on guides and Q and A sections. Follow Google’s structured data policies and validate before release.
Product and SoftwareApplication
Use on feature or plan pages when you describe sellable modules. Include only accurate offers and properties.
Breadcrumb and Organization
Breadcrumbs clarify hierarchy. Organization defines publisher and social profiles.
JSON LD example
<script type="application/ld+json">
{
"@context":"https://schema.org",
"@type":"Article",
"headline":"Content Modeling for CMS: Entities, Relationships, and Reusable Blocks for SaaS",
"description":"Entity-first model with relationships, components, and API contracts.",
"author":{"@type":"Organization","name":"Accord Content"},
"publisher":{"@type":"Organization","name":"Accord Content"},
"image":"https://accordcontent.com/og/content-modeling-for-cms.png",
"mainEntityOfPage":{"@type":"WebPage","@id":"https://accordcontent.com/resources/content-modeling-for-cms/"}
}
</script>Learn more in Google’s structured data overview and policy pages. Keep markup aligned with what readers see.
Workflow and governance
A strong model needs simple rules to keep it tidy as teams grow.
States and roles
- States: Draft, In Review, Approved, Scheduled, Published, Archived
- Roles: Author, Editor, Approver, Publisher
- Rules: only Approver can move to Published
Naming and ownership
- Canonical names for entities and fields in a shared glossary
- Owner per content type and per high value entry
- Quarterly review for ROT: redundant, outdated, trivial
Editorial acceptance criteria
- Every entry has a unique slug and meta description seed
- Required relationships are set. For example Feature relates to at least one Solution
- CTA exists with a trackingId
- Accessibility checks pass for alt text and link purpose
Migration and QA
If you are moving from a different CMS, freeze the model before content import and create a predictable map.
Mapping sheet
- Old type and field → New type and field
- Slug policy and redirect list
- Relationship resolution and edge cases
QA plan
- Sample 10 percent of entries per type
- Validate required fields and relationships
- Test routes, breadcrumbs, and schema validation
Redirect snippet
# Example rules
/resources/guides/* /resources/:splat 301
/blog/what-is-x /resources/glossary/x 301Performance and caching
A good model helps performance because fields are predictable and responses are cache friendly.
Image policy
- Use WebP or AVIF where supported
- Provide multiple sizes with srcset
- Lazy load below the fold
API caching
- Cache by URL and query params
- Stale while revalidate for busy pages
- Invalidate by tag on publish
Core Web Vitals
Fast LCP, stable CLS, and responsive INP make long guides usable. Benchmarks are available on web.dev.
Measurement and ownership
Instrument the model so you can report impact by content type and component.
Taxonomy dimension
Create a GA4 custom dimension like content_group and set it per template: Feature, Solution, Integration, CaseStudy, Guide, Glossary.
CTA event fields
- Event name: cta_click
- Params: label, href, trackingId, location
- Mark key events as conversions
Use Search Console for coverage and queries, and GA4 for engagement and conversions. Keep a governance sheet listing owners and review dates.
Implementation checklist
- List entities and pick content types
- Define fields with validation and help text
- Map relationships and decide ownership rules
- Create reusable components and placement rules
- Decide locale strategy and fallback rules
- Plan versioning where needed
- Publish API contract and sample queries
- Add schema mappings for each template
- Set workflow states and roles in the CMS
- Prepare migration map and redirect plan
- Configure caching, images, and vitals checks
- Instrument GA4 dimensions and events
- Document ownership and review cadence
FAQ
Should I store CTAs in the CMS or code
Store the CTA content in the CMS with a trackingId. Style lives in code. This lets you update copy without redeploys and still keep design consistent.
How many content types are too many
If editors cannot tell which type to use, you have too many. Combine where fields are identical and the purpose is shared.
Do I need a separate type for every page
No. Use a small set of types plus components. For example, one Guide type can handle playbooks, standards, and templates with section blocks.
How do I avoid model drift
Lock the model quarterly. All new fields require an owner, a help text, and an example. Remove or deprecate fields that are not used.
