No engineering background. I built ThinkingAI a custom CMS anyway
Blog and news lived in one mixed type with no real publishing workflow, the sitemap was wrong, slugs were broken. I designed and hand-coded the replacement solo on Sanity: a content model that demand generation, a publishing calendar and syndication can all run on. It gave the content manager a defined path per piece, with AI assist on the drafting so their hours go to the review that has to happen before anything ships. Piloted on the US site, and it is the template the other regions migrate to.
The old site blocked demand generation on every axis
One team runs four sites here: Japan, Korea, China and English. The sites themselves shipped fast, built with web coding and AI assistance, and underneath them there was no CMS. Every piece of content lived in a single blog tab.
- One tab held four different things. PR articles, news, product updates and blog posts all filed as the same content type, so the signal a visitor got was mixed at the source and governance had nothing to hold on to.
- No funnel layers. No top, middle, or bottom-funnel content structure, and no modules to carry any of it.
- Broken plumbing. The sitemap was wrong and static, and slugs were broken. Both are direct SEO and routing liabilities.
- Bare-bones UX. The whole front end was basic enough that it undercut the brand it was supposed to sell.
I had seen most of this before my first day, which is its own story.
I ran my own tool on the company before the interview
Everyone researches a company before an interview. I ran TechSpy on them, the competitor tech-stack tool I had already built for exactly this kind of question. It read their public technical footprint: the stack behind the sites, DNS records, email sending setup, what was serving the content, and what the technical SEO looked like from the outside.
From that I could infer the shape of the problem before anyone described it to me: how content was probably being managed, where the workflow was likely to hurt, and which parts of the marketing site were quietly costing them. So in the interview I was talking about their actual situation instead of asking to hear about it. Six rounds were scheduled. The offer came after four.
The diagnosis in the next section is the same one I walked in with, confirmed from the insideFive modules, one platform
A headless Sanity CMS feeding a statically-exported Next.js 16 site, content at build time only. Nine content types, a reusable block system, a self-owned lead-capture stack, and a hand-built Studio editing experience.
From one mixed blog to six editorial programs
Before, blog posts and PR announcements shared one content type. A visit told you nothing, because the signal was mixed at the source. I rebuilt it as six separate programs, each with its own funnel stage, its own strategy, and its own conversion action: blog, newsroom and product updates work top-of-funnel toward newsletter signup; ebooks and webinars sit mid-funnel behind an email gate; customer stories carry bottom-funnel proof toward the demo.
The separation does two jobs at once. Navigation gets honest: each section is one kind of content with one purpose. And a product-led journey gets fed properly: a customer moving from first touch to using the product needs different content at every step, and the model now has a typed home for each of them.
newsroom absorbs external press via a newsType radio, so media mentions don't need a fake blog postEvery form feeds attribution into the CRM
Every CMS form validates in two layers before a lead ever exists: a work-email check that prompts on public domains, and inline hints when an address is mistyped. Behind that, a Cloudflare Turnstile + Worker proxy does the server-side bot check on the demo form, layered with a honeypot and a blocklist.
The part that matters most is invisible: every form carries hidden fields recording the landing page, the full UTM set and the ad IDs (gclid, li_fat_id). I capture that on arrival, hold it in sessionStorage for the browsing session, then replay it at submit through HubSpot's Forms API into the CRM. There the automations pick the lead up for routing, workflows and source attribution, and the mechanism answers which page converted and which campaign paid for it.
Attribution survives the whole journey, from landing page to whichever page the visitor converts onRestyle the site's top line with no deploy
A CMS-controlled bar pinned above the nav. Marketers toggle it, edit the message, and restyle it from 15 curated themes, 2 sizes, and 3 button styles. No deploy. A custom Studio input shows a live WYSIWYG preview before publishing.
One --banner-offset token, inlined on <html> during SSR, re-flows the whole layout with no first-paint jumpArticles went from plain text to composed pages
The old body field was text and not much else. Now every type renders through a typed block palette (inline CTAs, embedded video, tables, FAQs, pull quotes, stat highlights), and long-form pages carry a sticky right column with anchor navigation, so a reader can jump the article instead of scrolling it. Every block is a governed React component; there is no WYSIWYG blob anywhere in the system.
caseStudy carries a structured metrics[] array plus a customer quote. BOFU proof is a field type
Build-time GROQ, static export, secret-free
A read-only, token-less Sanity client runs GROQ at build time inside server components; the projection does the shaping, so React gets flat, ready-to-render objects. Static export emits plain HTML: fast, secret-free, deployable to any static host including China. The sitemap and robots are CMS-fed and dynamic, fixing the old broken one. Deployment and the publish webhook sit with the China dev team. The rest of the system is mine end to end.
A toSanityLang() bridge maps next-intl locales to Studio languages; one Sanity project per region keeps each editor's Studio isolated
Every content type has a production line behind it
A CMS is a container. The reason one person can keep four sites and six editorial programs fed is that each type has its own multi-agent workflow standing behind it, and the workflow runs from research through to the published page.
I open a piece at roughly 85% draft and finish it
For a blog post the chain runs competitor research, keyword research, brainstorm, outline, draft, then the visual and UX pass, with on-page and technical SEO handled as their own steps inside the same run rather than bolted on afterward. Each stage is a different agent with its own brief. Feature image and banner are generated in the run too.
That gets a piece to roughly 85% by my estimate. What is left is the part that has to be human: taking the AI flavor out of the language, and pushing the depth up to where it holds in front of a domain-expert audience. Two content types run further than that. News and product updates are close to fully automated, around 99%, because the source material is factual and the format is fixed.
Both percentages are my own working estimates. I have run no formal measurement, and the human step is a required stage in the workflowProduce, publish, then turn one piece into the next three
Production and publishing are paired per content type: the workflow that makes a blog post has a matching workflow that files it into the CMS with its fields, its blocks, its SEO and its attribution already set. From there the same piece converts onward into a social post and a newsletter feature, so one production run feeds several channels instead of starting three separate jobs.
Attribution is attached at the content layer rather than added later, so every type can be traced through to the CRM. Across the six programs it adds up to one multi-stage, multi-layer system: research, production, publishing, distribution. The content manager left a month after I joined, so the editorial side has been mine since; this is what lets one person keep it fed.
Six programs, each with a paired production and publish workflow, all attributed back to the CRMSix calls behind the platform
A funnel dropdown would have been the easy call. Instead, each type carries the fields its role demands: TOFU types have no gate, MOFU types share a leadGate object, BOFU lives in caseStudy's metrics and quote.
webinar.status moves from upcoming to gated replay to public replay, with conditional fields and cross-field validation. The content's funnel role shifts as it ages, without splitting into three types.
Editors pick from 15 named presets, each pre-paired with a safe-contrast text color. Nobody touches hex, so the bar is on-brand and accessible by construction.
Most sites only get attribution when UTMs survive to the form page. I store them on landing and replay them at submit, with the hubspotutk cookie passed alongside.
Build-time GROQ plus static export: no server, no secrets in the bundle, no production CMS calls. The tradeoff (content ships on rebuild) is named and handled by the publish webhook.
Unique-slug validation on every type, soft-delete via an archived flag, protected singletons, and one Sanity project per region, so each region's editor owns exactly their own language in an isolated Studio.
The numbers so far
The architecture is recent and not yet fully live on production, so these are the base and the trend it's feeding. They are real and screenshot-backed, but not a clean “I lifted X%” story.
What the content team got
HubSpot holds 5,749 contacts, roughly 2,002 of them added in the last ninety days. Most of that window predates me and predates this system; what the capture + UTM layer instruments is the flow from here on, with the Turnstile/Worker gate guarding quality.
Search footprint
Q2 organic impressions went 1,253 in April to 24,847 in June. That is the window I inherited, not one I can claim. It is the baseline the new structure builds on. The same widening pulls average position from 4.6 to ~14.6, which is what a broader query set does.
What I can't claim yet
I started mid-June 2026 and many factors are in play, so the movement has more than one cause. Spam reduction and attribution coverage are still to be measured.
Sanity · GROQ
Next.js 16
React
TypeScript
HubSpot Forms API
Tailwind
Static export
Need a CMS your marketing team can run without engineering?
Content ops, automation, campaigns, attribution. All built on this foundation.
