The Agility Component Content Loading Mistake
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
contentidthat references a content item - The content item needs to be fetched separately using
getContentItem() - The
moduleobject passed to components is "unloaded" - it only contains thecontentid, 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:
- Always fetch content items - Don't assume
module.fieldsexists - Look at working examples - The
RichTextAreacomponent was right there showing the pattern - Pay attention to type names -
UnloadedModulePropsliterally means the module isn't loaded yet! - 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]