In short: On a custom or headless stack you own the one thing every other platform decides for you: whether a page arrives as text or as a shell that assembles itself.
That makes this the shortest lesson in the course to state and the most expensive to get wrong. If the substance is not in the response, nothing downstream matters, and no amount of content work reaches it.
The fix is ordinary engineering. Server rendering or static generation, chosen per route rather than for the whole application.
The Test, And What It Settles
Fetch the page without executing anything and look for the sentence you want quoted:
curl -s https://example.com/your-page | grep -i "the phrase you want cited"
This is the same command from Optimizing for AI Discovery, and on a custom stack it carries more weight, because a failure here is a thing you can actually fix rather than a platform limit to work around.
Per Route, Not Per Application
The decision is usually framed as a stack choice and is better made a route choice.
Pages that answer questions should be server-rendered or generated at build time: documentation, comparisons, product pages, anything a buyer reads before deciding. Pages behind a login, dashboards and configurators can render in the browser, because nothing is going to cite a dashboard.
Framed that way the work is small. Most teams are arguing about a whole application when the list of routes that matter is under thirty.
Rendering for a crawler and rendering for a person should be the same thing. Serving one version to agents and another to browsers is a maintenance burden that drifts, and the drift is invisible until somebody notices the answer in circulation is a year old. If the two have to differ, the reason should be written down and revisited, not inherited.
What Else You Now Own
Three things that the hosted modules had to treat as fixed.
The head. Titles, canonicals and structured data are yours to emit per route, which makes it possible for them to agree with the page rather than approximate it.
The status codes. A removed page can return 410 rather than a soft 404 that renders a friendly message with a 200 beside it. Systems read the code, and a 200 on a page saying "not found" is a claim that the page exists.
The response itself. Which means you can check a claim about your own site in one command instead of asking a support channel.
The Headless Trap
Content in a headless CMS is not published by being saved.
It is published when a build runs, or when a cache expires, or when somebody triggers a revalidation. Those are three different clocks, and an editor who has hit Save reasonably believes the work is live. A claim that exists in the CMS and not in the response is a claim that does not exist.
So the check after any content change is the same fetch, against the live address. Not the preview, which renders from a different path and is exactly where this failure hides.
Worth knowing before it bites: a cache in front of the application can also serve a stale page to a crawler long after the site looks correct to you, because your browser has a cookie or a session and the crawler does not. Fetch from outside your own network before concluding anything.
Key Takeaways
- On a custom stack you own the property every other platform decides for you, which is whether the substance is in the response.
- Make the rendering decision per route. The pages that answer questions are usually under thirty.
- Serve the same thing to a crawler and to a person, or write down why not and revisit it.
- You also own the head and the status codes, so a removed page can say so properly instead of returning 200 with an apology.
- In a headless setup, saving is not publishing. Check the live response rather than the preview.
Check yourself
Before you move on
Not scored, not recorded, and not part of the certificate. Both answers are settled by a sentence in this lesson, and the reasoning appears whichever option you pick.
- 01
Why is the rendering decision better made per route than for the whole application?
- 02
An editor saves a change in a headless CMS and the page still shows the old text when fetched. What is the likely explanation?