We shipped a component that read a field the Layout Service didn't return. Worked in a mock. Died on the real JSON.
I keep relearning the same headless lessons
Preview isn't prod. Webhooks aren't optional. I still skip a webhook when I'm rushing. Rushing is how last week's promo stays up. Rushing is how a field exists in a mock and not in Layout Service.
We shipped a component that read a field the JSON didn't have. Worked in a fixture from March. Died on live. Contract the JSON. Test against live layout, not a file from a frozen season.
Contracts
If the front end needs a field, put it in the resolver. Don't scrape 'for now.' For now lasted six months on one site. Six months of scrape is a product. Treat it like one or kill it.
Write the contract in a table humans can read. Field. Source. Who breaks if it's empty. If nobody owns empty, empty will ship. Empty shipped. Marketing called it a 'blank hero.' It was a missing field. Call it a missing field.
Webhooks, again, because I skipped one
Publish should ping the front. If it doesn't, people hard-refresh and blame Sitecore. I blamed Sitecore. It was me. The ticket said 'just content.' Content is why the ping exists. Skip the ping and you become the ping. I don't want that job.
Test with a harmless typo. Watch the front. Fix the typo. If nothing moves, your ping is costume jewelry. Looks done. Isn't.
- Live layout test, not March fixture.
- Anonymous user.
- Separate preview and prod keys.
- Publish ping you can see.
Environments
Preview data in prod cache is how you get 'why is that still up' with lawyers in the CC. Separate keys. I mixed them once. Once is a story. Twice is a habit. Don't start the habit.
Hit layout as the site user. Not as admin. Admin sees a kinder world. The public sees empty. Empty is what Google sees. Google doesn't care that admin looked fine.
Front-end discipline
No secret fields in the client 'because GraphQL made it easy.' Easy is how contracts rot. If it's not in the documented JSON, it isn't there. Document. Then code. I coded first. That's why I wrote this.
When a designer wants a new field on Friday, the answer is resolver plus contract plus ping. Not a client patch. Client patches on Friday are Monday's blank hero.
Checklist
Hit layout as anonymous. Confirm fields. Publish. Confirm ping. Confirm cache. Confirm preview isn't leaking. If any confirm fails, you don't add a component. You fix the confirm.
Monday
Run anonymous layout on prod for the homepage. Write down missing fields. That's your backlog. Not a new carousel. The carousel can wait. Missing fields can't. I keep putting carousels first because they're visible. Visible isn't the same as true.
The Miss
A preview token leaked into a bookmark. An unpublished bio shipped to a partner page. I still check referrers like a paranoid person. I am a paranoid person about tokens.
The Hold
Preview tokens don't live in bookmarks. Layout service stays off templates that aren't ready. Cache key includes the published flag. If any of those slip, we treat it like an incident. Because it is.
How We Roll It
One template. One token rotation. One cache check. We don't 'turn on headless' as a phase. Phases are how tokens travel.
What Broke Anyway
A partner asked for a 'preview link that lasts.' Lasting is the bug. I said no. I said it in writing. Writing is the only no that survives a Slack thread.
Checklist
Token rotated. Bookmark gone. Unpublished stays unpublished. Cache knows published. Four. Again. I know. Four works.
If You Only Do One Thing
Rotate the preview token today and ask three people to delete old links. If they argue, that's the meeting. Have the meeting. Don't have a headless town hall.
I keep the old token hash in an incident note. Not to reuse. To remember the day the bio leaked.
What I Won't Do
I won't put GraphQL on every template because a slide said 'omnichannel.' Omnichannel is how drafts walk out the door.
The Bookmark
Preview token in a saved link. Partner opened it. Unpublished bio. Nickname. I rotated the token in the same hour. Then I asked three people to delete old links. Two argued. That's the meeting. We had it. No town hall. A twenty-minute argument with receipts.
I wrote the old hash in the incident note. Not to reuse. To remember. Memory is a control when people want lasting preview links.
Lasting Is The Bug
Partners like lasting. Lasting is how drafts walk. I said no in writing. Slack threads eat spoken nos. Writing survives. I copied the no into the runbook. Runbooks are boring. Boring nos work.
Cache key now includes published. I checked it by publishing a dummy and unpublishing it. Dummy vanished. Dummy is a better test than a slide about omnichannel.
Template By Template
We did not enable headless on the bio template that week. We enabled it on a promo template that was already public. Public is the filter. If it isn't public, GraphQL can wait. Waiting is the hold.
Actionable checklist
- Review the architecture of your headless application.
- Ensure all components are modular and reusable.
- Define and document placeholder contracts clearly.
- Implement caching strategies for Edge capabilities.
- Utilize Layout Service for dynamic content rendering.
- Test API responses with tools like Postman.
- Monitor application performance regularly.
- Collaborate with front-end and back-end teams effectively.