Skip to content
2025
  • TypeScript
  • Static Generation
  • Content Modeling
  • Next.js

Data-Driven Content Architecture

Content as typed infrastructure — a schema-first approach where the shape of data drives the shape of every page, component, and metadata output.

A literary site's content isn't just text to display — it's structured data with relationships (books to authors, projects to tags, field notes to categories) that needs to feed UI components, SEO pipelines, static generation parameters, and structured data schemas simultaneously. Without a typed content layer, these four consumers develop independent data assumptions that diverge over time and break silently.

Every content type is defined as a TypeScript interface in a dedicated content file. The interface is the single source of truth — it determines what UI components can render, what pages can be generated, and what structured data can be produced. No content is valid unless it satisfies the type.

  • Colocated content and types: each content domain (books, projects, field notes, languages, network nodes) has its own directory with a types.ts and an index.ts exporting the typed data. Types and data live together rather than in separate /types and /data directories.
  • generateStaticParams driven by content arrays: Next.js static params are generated by mapping over the typed content arrays, so adding a new book or project automatically creates the corresponding static page at build time without any configuration change.
  • Discriminated union patterns: where content varies structurally (e.g., different demo types per project, different language focus levels), discriminated unions enforce completeness — TypeScript will error if a new variant is added without handling it in every consumer.
  • Content utilities as pure functions: buildPersonJsonLd(), buildBookJsonLd(), buildCanonicalUrl() are pure TypeScript functions that transform content types to output types. Pure functions are testable, tree-shakeable, and have no side effects — keeping the content layer clean of framework concerns.

The key architectural discipline is that no component ever constructs content — components only render what they receive via props. The content layer (typed data + utility functions) is entirely framework-agnostic TypeScript. It could be consumed by a different framework without changes. This separation also means the content layer is the right place to add validation, relationships, or computed fields — not inside components or page files, where that logic would be invisible to other consumers.

A codebase where adding a new book, project, or field note is a single typed object addition in a content file — which automatically propagates to static page generation, SEO metadata, UI rendering, and structured data output.

  • 7 typed content domains (books, projects, field notes, languages, network nodes, current work, manuscript fragments)
  • generateStaticParams driven entirely by content arrays
  • Zero untyped content — TypeScript enforces schema compliance
  • Content layer framework-agnostic (pure TypeScript, no React imports)