Schema-Validated Structured Content

design

Part of Statically generated sites

Site content needs to stay reusable and trustworthy across many contexts, not just look right on the one page that renders it.

Applies when

  • the content has recurring structure that more than one template or service reads
  • authors need comprehensible validation feedback
  • the team can agree what each field means and commit to maintaining a schema as content evolves

Summary

Treat content as data with an explicit structure, validated against a schema and independent of how it is presented. This pattern is for HASS research software engineers, researchers who code, and content authors who maintain research sites and data packages. The goal is for the content to stay usable after the site that published it is gone.

The Static websites pattern separates website content from its presentation, but not all implementations include content validation. In a typical implementation of a document-based website, the content is a set of markdown files in a source tree, each with a metadata block at the top in YAML format. Where a file sits in the tree, together with its YAML metadata, determines how the static HTML pages are formatted and linked together. In Jekyll, for example, blog posts in /_posts appear with the most recent date at the top, while other content follows the needs of the particular website.

A static site engine usually fails to build only if the metadata block is malformed, leaving authors to check that the generated site makes sense. For example, omitting a metadata field can leave a page unlinked from every site menu, and it is up to the author to debug this.

This pattern keeps content consistent by giving each type its own schema and validating against it automatically at build time.

A schema here is an explicit, machine-readable description of what a piece of content must contain: which fields it holds, what type of value each takes, and which of them are required. The same idea underlies a database schema, a TEI ODD customisation, and a JSON Schema document, whatever the syntax each uses to express it.

RecommendationWhy?
Divide content into collections, stored together in a directory (which is very typical of static site designs anyway), or via a metadata fieldEach kind of content can then carry its own schema, so a tighter rule on one collection does not constrain the rest
Optionally, align collection schemas with shared schemas such as schema.org or domain schemas and profilesTo make content, particularly research data, available for reuse through interoperable metadata, without having to transform it
Design schemas for the metadata in each collection specifying which fields are required and optional, and what data types should be presentTo ensure that content can be reused in other contexts
Consider publishing local schemas for reuse by a communityTo enable data reuse via interoperable metadata
Configure the build process to issue errors and warnings when content does not meet the schema constraintsAn author who can read the error can fix it unaided, instead of debugging a page that rendered but is wrong
Make schemas only as rich as the content’s known uses require, and grow them deliberatelyAn over-specified schema burdens every author and makes it hard to add new types of content

Context

This pattern suits any site whose navigation or search is driven by metadata or data held in the site, including the typical blog-post versus web-page distinction described above. It matters most where content is reused in downstream services, as in the Collection-centred static website pattern, where the content is research data that may be read again long after the site that first presented it has gone.

These conditions are social as much as technical. The people who write research content range from software engineers to researchers who do not code. A researcher-author needs an error they can read, not a stack trace, before they can fix anything. Agreeing what each field means is a shared-vocabulary problem before it is a software one.

Do not apply the pattern to one-off prose pages that have no recurring structure and no consumer beyond the page itself, where a schema is pure overhead. It also does not suit content whose shape cannot be anticipated.

Usage

Model each content type as a collection and decide what kinds of schema it needs:

  • Metadata validation: which fields are required, and what values they may take, checked against the metadata block in a source file such as markdown. Use a validator such as Zod, or a profile system such as RO-Crate Machine Actionable Schemas and Profiles

  • Document validation: the structure of the content itself, expressed in a standard document schema. Collections of encoded text are validated against a TEI schema generated from an ODD customisation, usually as RELAX NG

  • Site-specific validation: a custom check for a local rule, for example a script that verifies the heading structure of a markdown file

Whatever the mechanism, make the schema visible while the author writes, and make failures legible. An editor that reads the schema can offer completion and flag an error in place, and a rule that carries its own message, as a Schematron assertion does, can name which field in which item is wrong and why. An author who can read the error can fix it unaided.

Model relationships explicitly. Where one item refers to another, for example a pattern to its siblings or a dataset to its authors, express that as a typed reference between collections rather than a loose string, so the link can be validated rather than left to rot silently.

Publish machine-readable structure for the consumers that need it. Where discovery or interchange matters, use a recognised vocabulary (for example schema.org expressed as JSON-LD). Search services, aggregators, and archives can then consume the content, either by adopting the relevant schema directly or crosswalking to it at build time.

Treat schemas as versioned specifications. Change them through review, and migrate existing content when it changes, so the contract between authors and consumers remains accurate.

Enforce the schema when the site is built. Build and validate every proposed change before it reaches a reader. Publish what conforms, and return what does not to its author with the reason it failed. Validate every item on every build, not only the items that changed, so that revising a schema cannot leave older content silently non-conforming.

One content source, validated once against an explicit schema, feeds four peer consumers, and the rendered page is one of them.
One content source, validated once against an explicit schema, feeds four peer consumers, and the rendered page is one of them.

Implementations

The Astro framework implements this pattern via content collections. A collection declares its metadata schema as a Zod object, every item is validated at build, and templates receive typed content with editor autocompletion.

The Content Layer adds typed references between collections, and loads content from files or external sources. One collection can then drive a detail page, a listing or RSS feed, a search index, and a JSON-LD block for crawlers: the same content, validated once, feeding four peer consumers. See the content collections reference for the API.

The RSE-CEP pattern catalogue, built with Astro, runs on this pattern: each pattern is a typed content collection whose frontmatter is defined by a schema, validated at build, with typed references between related patterns.

The shape is not web-specific. RO-Crate applies the same idea to research-data packaging: schema-validated metadata as JSON-LD, held apart from an optional human-readable rendering. RO-Crate is already used in Australian research infrastructure such as the Language Data Commons of Australia.

References

Standards

  • JSON Schema: the general approach to validating structured documents across ecosystems.
  • schema.org: the common vocabulary for machine-readable structured content, typically expressed as JSON-LD for discovery.
  • TEI Guidelines: the encoding standard for scholarly text, whose ODD customisations generate the schema a collection is checked against.
  • Schematron: the rule-based validation standard (ISO/IEC 19757-3) whose assertions carry their own human-readable failure messages.

Libraries

Acknowledgments

This pattern responds to concerns raised by participants in the HASS and Indigenous RDC Community Data Lab co-design workshop. Participants noted that software development too often prioritises features over long-term access to well-described data, leaving outputs unsustainable. It draws on the structured-metadata conventions of the RO-Crate and schema.org communities rather than reinventing them.

Principle alignments

  • Interoperable FAIR AI-suggested

    Typed references between collections and projecting content into a recognised vocabulary, e.g. schema.org as JSON-LD, give every consumer a stable, shared shape to read against. Making the data combinable and reliably readable by independent consumers is a core design move here, not a side effect.

  • Reusable FAIR AI-suggested

    The pattern exists so the content itself, not its rendered appearance, is the durable asset: an explicit schema and the separation of content from presentation keep each item reusable and citable long after the site that first presented it. Reuse is the limb of FAIR the pattern names as its own reason for being.

Reviewed 12 June 2026

Related patterns

Credits

AuthorsMat Bettinson (ANU), Peter Sefton (ANU / UQ)

Technical editorJames Smithies