I fixed 9 things on fieldnotes-ai.com in an hour. Half of them didn't need a single line of code.
Lists weren't rendering. Social links were hardcoded. The nav had a page nobody needed. Claude Code fixed the code. Contentful fixed the rest. Total cost: $6.82.
Today was a cleanup day. The site was live but rough. Field Note #002 had bullet lists that rendered as flat paragraphs, social links pointed to generic URLs, and the navigation included an About page that added nothing. Nine issues on the fix list.
An hour later, everything was done. The interesting part: almost half the fixes required zero code changes. That's the real story of this entry.
Here's the full list.
What broke in the Rich Text renderer
The Contentful Rich Text renderer (https://github.com/contentful/rich-text/tree/master/packages/rich-text-react-renderer) had the node types defined but completely unstyled. BLOCKS.UL_LIST and BLOCKS.OL_LIST existed in the code but had no CSS classes. Lists rendered as flat text, completely indistinguishable from regular paragraphs.
The fix was adding Tailwind classes for list styling and overriding the paragraph margins that Contentful injects inside list items. Contentful wraps every list item's text in a <p> tag, and those paragraph margins were stacking on top of the list spacing. Without the override, lists looked double-spaced. Once you know that's how Contentful Rich Text works, the fix is obvious. Before you know, you're staring at broken lists wondering what's wrong with your CSS.
Horizontal rules got styled to match the aged paper aesthetic. Embedded assets got a full handler pulling the image URL and title from the entry data, rendering inside a <figure> with lazy loading and a caption.
Social links: one bug, three locations
The footer social links were reading from Contentful correctly but the AboutStrip component was using hardcoded labels. The header had no social links at all. Fixed all three locations to pull dynamically from the same Contentful socialLink entries. Added inline SVG icons for LinkedIn, X, and GitHub in the header. No icon library dependency, just raw SVGs at 18px with a crimson hover state.
One debugging detour worth mentioning: the X icon wasn't rendering because the socialIcons map used "X" as the key but the fallback defaults still said "Twitter". Added "Twitter" as an alias mapping to the same SVG. The kind of bug that takes 30 seconds to fix and 20 minutes to find.
Favicon from scratch
The site had no favicon. Just the default Next.js icon. Designed a field journal icon: notebook with ruled lines and a crimson bookmark ribbon on a dark background. Generated it as SVG, then produced PNGs at every size you need (16, 32, 180 for Apple touch, 192, 512) using Sharp. Updated the root layout metadata and created a web manifest for PWA support.
Now the part that matters more: the content fixes
This is where it gets interesting. Five of the nine fixes required zero code. No PRs. No deploys. No code review. Just Contentful.
Removed About from navigation. Unpublished the "About" navigation item in Contentful. The nav immediately dropped to two items: Field Notes and My Tools. That's it. One click in the Contentful UI. The site updated on the next request.
Added five new tools. Vercel (Infrastructure), Claude Code (AI Model), Claude (AI Model), v0 (UI Builder), and Contentful MCP Server (AI Framework). Created the entries in Contentful, published them, and they appeared on the site within seconds.
Published globalSettings. This was the root cause of multiple bugs and the most satisfying fix of the day. The globalSettings content type existed. The navigation items existed. The social links existed. But globalSettings itself had never been published, so the app fell back to hardcoded defaults with generic URLs and stale labels. Publishing one entry fixed the navigation, social links, copyright text, and SEO metadata simultaneously. Four bugs, one publish button.
Configured SEO metadata. Set up the OG title, description, image, sitemap inclusion, and robots directives. All from Contentful. The site now has proper social share previews when someone links to it on X or LinkedIn.
Why the content fixes are the real story
Seven PRs merged today for the code fixes. But the content fixes, the ones that required zero PRs, were the most satisfying.
I've been on the implementation side of Contentful for a while now. Before that I was a Contentful customer at TELUS. The whole value of a headless CMS is that content and code move independently. I've explained this in partner workshops probably hundreds of times.
Today I experienced it from the practitioner side and it actually hit different.
The About page removal is the clearest example. In a traditional setup, removing a nav item means: open the codebase, find the nav component, delete the link, commit, push, wait for CI, deploy. In Contentful with a properly structured content model (https://www.contentful.com/help/content-modeling-patterns/), it's one step: unpublish the entry. Done.
The keyword there is "properly structured." The globalSettings issue proves this. The content model was designed correctly from day one. Navigation items as referenced entries, social links as their own content type, SEO as a standalone reference. The architecture was right. But because the singleton entry was never published, all that architecture was invisible. The code fell back to hardcoded defaults, and nothing looked broken enough to investigate.
A content model is only as good as its published state. That's the line I keep coming back to.
Security audit
Before touching any code, ran a full security scan: checked git history for leaked secrets, verified .env.local is gitignored, ran npm audit (zero vulnerabilities). Enabled Dependabot, secret scanning, and code scanning in the GitHub repo settings. Two minutes of setup for ongoing protection.
This is the kind of thing nobody writes about because it's not interesting. But if you're building in public with AI tools that move fast, it's worth the habit.
MCP setup (partial)
Configured the Contentful MCP server (https://github.com/contentful/mcp-server) for Claude Code. Added .claude/mcp.json with the CMA token, gitignored the config directory. The MCP tools didn't load in the session (needs debugging), but Claude Code improvised by querying the Contentful Management API (https://www.contentful.com/developers/docs/references/content-management-api/) directly via curl. Good enough to diagnose the globalSettings issue.
Full MCP integration is next session's problem.
The numbers
An hour of work. Claude Code sessions across all days so far:
Contentful space setup: $1.72 Website fixes and features: $4.85 Subagent tasks: $0.25 Total: $6.82
Seven merged PRs. Five new Contentful entries. One published globalSettings entry that fixed four bugs at once. One favicon designed from scratch. Zero dependencies added.
What I'd do differently
Publish globalSettings before writing any code. If I'd checked the CMS state first, I would have realized half the "bugs" were just missing content. The code was fine. The content model was fine. The entries were fine. They just weren't published.
When something looks broken in a headless CMS architecture, check the content before the code. I'll be saying that in workshops from now on.
What's next
The site is live, the obvious bugs are squashed, and I have a proper favicon. Tomorrow: SEO. The kind of invisible infrastructure that nobody sees but everything depends on.
Field Note #004 will cover what I find.