QUANHEX.
Architecture

Building an Enterprise Content Platform With Contentful and Angular

How we architected a Contentful + Angular system for a major hospitality brand — content modeling decisions, middleware design, and the lessons from handling multi-property content at scale.

· 8 min read

Enterprise CMS implementations are different from startup CMS implementations in kind, not just degree. The stakeholder landscape is complex, the content volume is high, the editorial workflows are established, and the technical debt from legacy systems is real. Here’s what we’ve learned building in that environment.

The Architecture Layer That Changes Everything

The pattern that most enterprise Contentful implementations get wrong: connecting the frontend directly to the Contentful Content Delivery API. It works in development. In production, it creates problems:

  • API key exposure: Client-side Contentful access requires a read-only API key, but that key is visible in the browser
  • No response shaping: Contentful’s response format is designed for flexibility, not your specific UI’s data needs
  • No caching control: You’re dependent on Contentful’s CDN headers
  • Tight coupling: Frontend is coupled to Contentful’s response schema

The solution: a middleware layer. A lightweight .NET Core or Node.js service sits between your Angular app and Contentful. It authenticates with Contentful (server-to-server, key never exposed), fetches and shapes the response, adds caching headers, and returns a clean contract to the frontend.

// Your API returns this
interface HeroSection {
  headline: string;
  subheadline: string;
  ctaText: string;
  ctaUrl: string;
  backgroundImage: ImageAsset;
}

// Not Contentful's raw response format
interface ContentfulEntry<T> {
  sys: { id: string; type: string; ... };
  fields: T;
  metadata: ...;
}

The middleware translates between them. Your Angular components work against your contract, not Contentful’s.

Content Modeling for Multi-Property Brands

A hospitality brand with multiple properties needs content that can be shared (brand values, leadership team, privacy policy) and content that must be property-specific (room types, dining menus, local activities).

The modeling pattern:

  • Global content: Belongs to the brand space, shared across all Angular applications
  • Property content: Belongs to per-property spaces, with references to global content where appropriate
  • Localized content: Locale-specific fields on entries that appear in multiple markets

The mistake to avoid: putting everything in one space and filtering by a “property” field. Content APIs don’t scale well to highly filtered queries on large content sets. Multiple spaces with clear ownership boundaries perform better and are easier to manage.

Editorial Workflow Design

Content modeling decisions have downstream effects on editorial workflows. For each content type, ask: who creates it, who reviews it, and when does it publish?

Contentful’s built-in workflow states (Draft, In Review, Published, Archived) are often insufficient for enterprise needs. Content management platforms like Workflow Master (Contentful app) or custom webhook-driven workflows can add approval steps.

Design the workflow before the content model. The model should support the workflow, not force editors to work around it.

Angular Service Architecture for CMS Content

For Angular applications backed by a CMS, content fetching belongs in services, not components. Components should receive data as inputs, not make HTTP calls.

@Injectable({ providedIn: 'root' })
export class ContentService {
  private cache = new Map<string, Observable<any>>();

  getPage(slug: string): Observable<PageContent> {
    if (!this.cache.has(slug)) {
      this.cache.set(
        slug,
        this.http.get<PageContent>(`/api/content/pages/${slug}`).pipe(
          shareReplay(1)
        )
      );
    }
    return this.cache.get(slug)!;
  }
}

The shareReplay(1) prevents duplicate network requests when multiple components request the same content. The service-level cache prevents re-fetching on route navigation within a session.

The Preview Environment

A CMS without a reliable preview environment is a CMS that editors don’t trust. Contentful’s Preview API returns draft content. Your middleware needs a preview mode that uses the Preview API instead of the Delivery API.

Implement preview mode with a secure token: ?preview=<token> activates it. The token should be short-lived and only valid for users who are authenticated in your CMS editorial interface.

Editors who can reliably preview exactly what will publish make fewer publishing mistakes. The investment pays back immediately.