By Jason Ansell
Publishing Is a State Machine, Not a Button
A post is not finished when a database row says published. It is finished when the reader page, assets, crawler HTML, RSS identity and share previews agree.

- 01Treat publication as a set of independently verifiable states, not a single database change.
- 02A working browser page does not prove that crawler HTML, social metadata, feeds or JavaScript assets are correct.
- 03Stable canonical URLs and RSS GUIDs protect content identity across edits and distribution systems.
- 04Build checks and production checks answer different questions; a reliable workflow needs both.
Builder's Notes: I have stopped treating Publish as a single event. In a modern web application, the button may change one database record while the public result depends on several systems that update on different schedules. My working rule after rebuilding JasonAnsell.ca is simple: a post is not published because one field says so. It is published when every surface that matters agrees about what the item is.
This is a narrower lesson than my earlier article about why website migrations break automation. That piece focused on preserving feeds and workflows during a move. This one is about the release model that emerged afterward: publication behaves like a state machine, with explicit gates and evidence for each state.
What one article revealed
On September 25, 2026, I checked the most recent analysis published on this site. Its browser-rendered reader page showed the full article and its 1200-by-630 artwork. The RSS feed contained one matching item whose link and permalink GUID used the same canonical URL. A standalone share page contained the title, image, canonical link and complete body without depending on the application runtime.
The raw HTML response for the canonical reader URL was different. It had a self-referencing canonical URL, but it still carried a platform fallback rather than the complete article body and article-specific presentation. A reader with JavaScript saw the finished work; a consumer relying only on the first HTML response saw a different state.
That observation is consistent with Base44's current search documentation. It explains that browser-based apps need a crawler-rendered version and that, when a complete rendered page is not ready, the platform may serve a shorter fallback summary. This is useful protection against an empty shell, but it is also a reason to test the actual response instead of assuming that a successful browser view proves crawler readiness.
The six states I now verify
1. The source record is complete
The title, slug, body, excerpt, author, date, canonical URL and image references must exist together. I do not create unfinished public records because a frontend can expose them before an editorial draft is ready. The canonical identity is decided here and should not drift later.
2. The reader experience renders
The public page must show the actual heading, article body, sources, date and artwork on a real browser. An API response does not prove that routing, client queries or layout work. It also does not catch a page that loads but overflows or hides essential controls on mobile.
3. The required assets load
During this rebuild, a successful HTML response once masked missing JavaScript assets, leaving the site unable to start. That changed the release test: I now fetch every referenced production script and stylesheet, confirm a 200 response, verify its MIME type and make sure the file is not empty. A green page request is only the first check.
4. Crawler HTML describes the same page
Google's JavaScript SEO guidance, updated March 4, 2026, separates crawling, rendering and indexing. Google notes that rendering can happen after the initial fetch and recommends server-side rendering or prerendering because not every bot runs JavaScript. It also emphasizes unique titles, descriptions and consistent canonical URLs. That makes raw HTML inspection a separate release gate, not an SEO afterthought.
5. Syndication preserves identity
RSS is not merely another copy of the page. It is an event stream consumed by automations and feed readers. The RSS 2.0 specification says a GUID uniquely identifies an item and may be used by aggregators to decide whether it is new. Keeping the canonical permalink stable as the GUID prevents an ordinary edit from looking like a second publication.
6. Share metadata matches the article
A social platform may never execute the reader application. The Open Graph protocol identifies title, type, image and canonical URL as the basic page properties, and recommends image dimensions and alt text. I verify those fields in generated share HTML rather than assuming that the visible page title will become the preview.
Build success and live success are different
The local build for this site creates canonical HTML and a separate share/import page for each public item. Automated checks confirm one H1, one Open Graph title, the correct canonical, the complete sanitized body and the expected image. Those checks are valuable because they catch deterministic mistakes before release.
They cannot prove that the hosting layer deployed the same files, that its crawler snapshot refreshed, or that a CDN serves every bundle. Production checks answer those questions. The distinction matters because rerunning a build cannot fix a deployment that never reached the edge, and repeatedly editing content cannot fix a crawler snapshot that is still pending.
My opinion: publish should fail closed
A serious publishing workflow should show each state independently: record saved, image public, reader rendered, assets healthy, crawler metadata correct, share page live and feed item stable. If one state is unknown, the system should say so plainly. It should not convert a partial success into a broad green badge.
The checklist will vary by platform. A system that atomically released data, prerendered HTML, feeds, metadata and versioned assets could collapse several steps. Better platform evidence could also reduce manual verification. What would not change is the need to observe external boundaries: search crawlers, feed consumers, social caches and CDNs remain separate systems with their own timing.
That is why I now treat the publish control as the start of verification, not the end of the job.
Disclosure: These Builder's Notes are based on the documented JasonAnsell.ca rebuild and its Base44 implementation. Base44 is named because it is part of the stack; this is not a sponsored endorsement.
Sources
- Base44: Getting your app found in search (accessed September 25, 2026)
- Google Search Central: Understand the JavaScript SEO basics (updated March 4, 2026)
- RSS Advisory Board: RSS 2.0 Specification (current specification, accessed September 25, 2026)
- The Open Graph protocol (accessed September 25, 2026)
Share this page