Series: Building This Site

The Agility Component Content Loading Mistake

Workcodingai

When building the Agility CMS components for this site, I ran into a consistent issue where components weren't loading their content properly. The problem? The AI agent was trying to access module.fields directly, assuming the fields would be available on the module object passed to the component.

The Agility Component Content Loading Mistake

Date: January 6, 2026
Author: Joel Varty (with technical details by Cursor AI Agent)

The Problem

When building the Agility CMS components for this site, I ran into a consistent issue where components weren't loading their content properly. The error was clear: Cannot destructure property 'title' of 'module.fields' as it is undefined.

The problem? The AI agent was trying to access module.fields directly, assuming the fields would be available on the module object passed to the component. But that's not how Agility CMS works.

What I Did Wrong

I created components like this:

const BlogListing = async ({ module, languageCode }: UnloadedModuleProps) => {
  // ❌ WRONG - module.fields is undefined
  const { title, numberOfPosts } = (module as any).fields as BlogListingFields

  // ... rest of component
}

This pattern was used in:

  • BlogListing
  • BlogDetails
  • CareerTimeline
  • UsesSection
  • Hero

All of them failed with the same error.

The Correct Pattern

Looking at the RichTextArea component that was already working, I should have noticed the pattern:

const RichTextArea = async ({ module, languageCode }: UnloadedModuleProps) => {
  // ✅ CORRECT - Fetch the content item first
  const {
    fields: { textblob },
    contentID,
  } = await getContentItem<RichText>({
    contentID: module.contentid,
    languageCode,
  })

  // ... rest of component
}

Why This Happened

The key insight is that in Agility CMS:

  • Module instances on pages have a contentid that references a content item
  • The content item needs to be fetched separately using getContentItem()
  • The module object passed to components is "unloaded" - it only contains the contentid, not the actual fields

The UnloadedModuleProps type name should have been a clue! But I missed it.

Components Fixed

All of these components were updated to use the correct pattern:

  • ✅ BlogListing
  • ✅ BlogDetails
  • ✅ CareerTimeline
  • ✅ UsesSection
  • ✅ Hero
  • ✅ BasicMarkdown (created correctly from the start)

Lesson Learned

When working with Agility CMS components:

  1. Always fetch content items - Don't assume module.fields exists
  2. Look at working examples - The RichTextArea component was right there showing the pattern
  3. Pay attention to type names - UnloadedModuleProps literally means the module isn't loaded yet!
  4. Test early - This would have been caught immediately if I'd tested the components

Joel's Thoughts / Reflections

[Space for Joel to add personal thoughts, reactions, design decisions, or creative direction]