Pure Frontend Blog Decoupling: A Complete Guide to SSG, RSS, and the 404 Problem

Achieving static blog frontend-backend separation using Cloudflare Workers, query parameter routing, and custom 404 fallbacks.
This article details a pure frontend approach to decoupling blog content from code deployment using Cloudflare Workers as a bridge layer. It covers the cascading challenges that arise — from RSS subscription path mismatches, to Next.js SSG's inherent 404 problem with dynamic content, to Giscus comment anchoring failures — and presents practical solutions including query parameter routing and intelligent 404 redirects.
Should Blog Content Live in Your Source Code? The Pain of Frontend-Backend Coupling
For many developers building static blogs with frameworks like Next.js or Hugo, there's an unavoidable question: Should article content be coupled with your website's source code?
In the traditional approach, blog posts are stored as Markdown files directly in the project repository, built and deployed alongside the code. This creates an obvious pain point — every time you add or modify an article, you have to trigger a full frontend rebuild and redeployment. When your article count reaches two or three hundred, this "butterfly effect" model becomes incredibly cumbersome.
The "build" here refers to the Static Site Generation (SSG) process. SSG is one of the core build strategies in modern frontend frameworks (like Next.js, Gatsby, and Hugo) — it pre-renders all pages into pure HTML files during the build phase, requiring no server-side computation after deployment as static files are served directly via CDN. This delivers exceptional loading speed and security, but the trade-off is that content becomes tightly bound to the build process. This stands in stark contrast to traditional CMS platforms (like WordPress) that use a "database-driven, on-demand rendering" model — while slightly less performant, content updates are completely independent of code deployment.
This article is based on a practical sharing by a Bilibili content creator, documenting how he achieved complete blog frontend-backend separation using a pure frontend approach (without modifying server-side core logic), while simultaneously solving a series of cascading problems including RSS subscriptions, comment anchoring, and legacy link redirects.
Core Architecture: Frontend as Shell, Cloudflare Worker as Bridge
The core idea behind the separation approach is crystal clear: The frontend is merely a "shell" that doesn't store actual article content.
This can be verified through browser F12 network inspection — article body content is actually stored on the backend (under a path the author refers to as "row"). The bridge between frontend and backend is a Cloudflare Worker.

Cloudflare Worker is an edge computing service based on the V8 engine, running on Cloudflare's edge nodes across more than 300 data centers worldwide. It allows developers to execute JavaScript/TypeScript code on the node closest to the user before requests reach the origin server. Workers can intercept and modify HTTP requests/responses, perform route rewrites, generate dynamic content, and typically have cold start times under 5 milliseconds. Compared to traditional Lambda/cloud function solutions, Workers' advantage lies in requiring no region specification and responding from the nearest global location, making them ideal as an "intelligent middleware layer" for static sites.
Its responsibility is: pre-building article indexes. When the frontend renders article lists, it only needs an article index (host.json), not the entire body content bundled in. This index is generated by the Cloudflare Worker during the pre-build phase, and the frontend fetches the corresponding body content after receiving the index.
In theory, when the backend updates content, the frontend can display it by fetching the updated index without redeployment. But this only "appears to solve the problem without fully solving it" — the real trouble lurks in several cascading issues that follow.
Three Twists in Fixing RSS Subscriptions
What seemed like the simplest part — RSS generation — turned out to be the most troublesome step in the entire process.
RSS (Really Simple Syndication) is an XML-based content distribution protocol that allows users to aggregate website updates through feed readers (like Feedly, Inoreader, etc.) without visiting each site individually. A standard RSS file contains a channel (feed information) and multiple items (article entries), with each item typically including title, link, description, pubDate, and other fields. Feed readers periodically poll RSS addresses, comparing existing entries to discover new content and push it to users. In a frontend-backend separated architecture, the accuracy of the link field in RSS becomes particularly critical — it determines the target page users land on after clicking. If frontend and backend paths are inconsistent, the subscription experience completely breaks down.
Problem One: Incorrect RSS Content Paths
The author's idea was to have the Cloudflare Worker generate an RSS file according to rules during the pre-build phase. But after generation, the subscription tool (follow) reported it couldn't find the content. The reason was that the generated RSS defaulted to pointing to incorrect paths. The fix was straightforward — hardcode the correct row paths into the RSS.
Problem Two: Inconsistent Subscription Paths
The second problem was more subtle. The RSS address users subscribe to is 2x.z/rss.xml, but the backend actually generates row-post.2x.z/rss.xml. The mismatch naturally breaks the subscription.
The author's solution was to write a routing rule in the Worker that correctly routes requests to 2x.z/rss.xml to the backend's RSS file. Meanwhile, while the link fields in the RSS point to frontend display pages, the content is served by the backend — this approach makes third-party feed readers treat it as a complete, normal article where images load correctly without redirecting to raw backend links.

The Next.js SSG 404 Problem: A Fundamental Contradiction of Static Site Generation
After resolving RSS, a more fundamental contradiction surfaced.
In SSG (Static Site Generation) mode, Next.js requires every path to have a corresponding pre-generated HTML file. For example, the path /post/micro-blog-servers must have a corresponding .html file, otherwise it returns a 404.
Here it's important to understand the essential differences between SSG and other rendering modes: SSG generates HTML at build time, SSR (Server-Side Rendering) has the server dynamically generate HTML on each request, while CSR (Client-Side Rendering) relies entirely on browser-side JavaScript to render pages. Each has its trade-offs — SSG offers optimal performance but least flexibility, SSR balances SEO and dynamism but requires server resources, and CSR provides development flexibility but suffers from slow initial loads and poor search engine friendliness. This fundamental contradiction is SSG's inherent limitation: paths are locked at build time and cannot respond to content added after the build.
Why wasn't this a problem before? Because during frontend builds, the system pulls backend JSON, sees how many articles exist, and generates that many routes (say, 200+). But once separated — when the backend adds new articles without frontend redeployment, the HTML for new articles doesn't exist, and accessing them returns 404. This circles right back to "backend updates require frontend redeployment," contradicting the entire purpose of separation.
The author outlined three solution approaches:
Approach One: Pre-building (Treats Symptoms, Not the Cause)
This is the current method, but its drawback is that the frontend still needs to be deployed after backend updates, essentially not solving the fundamental contradiction.
Approach Two: 404 Fallback with Client-Side Rendering
Using Cloudflare's custom 404 page to catch all paths without generated HTML, then having that page do client-side parsing — similar to the old "pseudo-static" approach. This essentially degrades SSG to CSR, similar to using hash routing or history API fallback in SPAs (Single Page Applications).

But the drawback is fatal: existing articles are server-rendered, and switching to SPA client-side rendering requires massive code rewrites, making the cost too high. This approach was ultimately abandoned. Additionally, CSR mode means search engine crawlers may not correctly index page content (although Googlebot supports JavaScript rendering, latency and reliability issues persist), causing irreversible damage to existing SEO rankings.
Approach Three: Query Parameter Routing (Final Choice)
The ultimately chosen solution was the most elegant — replacing paths with query parameters (?slug=xxx). This way, only a single posts.html file needs to exist, and article content is dynamically queried through the slug parameter after the question mark, completely breaking free from the constraint of "one article, one HTML file."
The brilliance of this approach lies in: it only requires one pre-built entry HTML file that uses JavaScript to read query parameters from the URL, dynamically requests the corresponding article body data from the backend, and renders it. From the browser's perspective, all articles share the same HTML "container," with content differentiation handled entirely by client-side logic.
Cascading Effects: Comment Anchoring and Legacy Link Redirects
While Approach Three works well, it spawned two new problems — a textbook case of "whack-a-mole" in system refactoring.
Giscus Comment Anchoring Failure
The blog uses Giscus as its comment system, which by default anchors each article's comments via pathname (the URL path). Once all article paths become a uniform posts, comments from different articles all get mixed up.
Giscus is an open-source comment system based on GitHub Discussions that maps blog comments to Discussion posts in a GitHub repository. The anchoring (mapping) mechanism determines "which article corresponds to which Discussion." Giscus supports multiple mapping methods: pathname (match by URL path), URL (match by full URL), title (match by page title), og:title (match by Open Graph title meta tag), specific term (match by custom keyword), and more. The Open Graph protocol is a metadata standard introduced by Facebook in 2010 that defines structured information like page title, description, and images through specific <meta> tags in the HTML <head>, widely used for social media share previews.
The author's fix was: changing the Giscus configuration's anchoring method from pathname to og:title, and setting the og:title value to the article's old path format. This way, even with URL changes, each article can still precisely anchor its own comment section through a unique og:title.
Legacy Link 301 Redirects
Finally, ensuring old users can still access legacy paths without failure. While Cloudflare Worker or edge server-side redirects could be used, since the blog is deployed on two platforms, the author chose Next.js's redirect mechanism for consistency.

The most ingenious step was: placing the redirect logic inside 404.html. Since accessing old paths inevitably triggers a 404, Cloudflare returns the custom 404 redirect page at that point. A script within the page determines whether it's a legacy article link, and if so, redirects to the new query parameter address — the entire flow is seamless. This approach leverages a Cloudflare Pages feature: when a requested path has no corresponding static file, it returns the 404.html from the project root, and this HTML file can contain arbitrary JavaScript logic, effectively providing a free "catch-all routing layer."
Summary: Engineering Trade-offs in Static Blog Frontend-Backend Separation
Broken down step by step, this entire solution revolves around one core goal: completely decoupling content updates from code deployment.
The key takeaways are:
- Frontend-backend separation is equally valid for static blog scenarios; the key is finding the right boundary between content and views;
- "Edge computing" tools like Cloudflare Workers, custom 404 pages, and query parameter routing provide tremendous flexibility for pure frontend solutions;
- Any architectural change triggers cascading effects (RSS, comments, SEO, legacy links) — systematic thinking matters more than point solutions.
It's worth noting that this solution is not particularly SEO-friendly — query parameter URLs are generally less favorable for search engine indexing compared to static paths. Search engines typically treat query parameters as different "versions" of the same page rather than independent pages, and Google's crawler may deduplicate, ignore, or delay indexing URLs with parameters. In contrast, "clean URLs" like /post/article-name are treated by search engines as independent, meaningful paths, benefiting PageRank distribution and semantic understanding. This is the price paid for "elegant decoupling" and a trade-off each developer must weigh during technology selection.
It's worth mentioning that the industry has other solutions for this type of problem: Next.js's ISR (Incremental Static Regeneration) allows updating individual pages without rebuilding the entire site; Headless CMS platforms (like Contentful, Strapi) trigger on-demand builds via Webhooks; and emerging frameworks like Astro offer hybrid rendering modes, allowing some pages in the same project to use SSG while others use SSR. The pure Worker approach presented in this article is better suited for individual developers who don't want to introduce additional service dependencies and prefer zero-cost operations.
Related articles

OpenAI Tests Ads in Europe: A Critical Turning Point for Free AI Monetization
OpenAI plans to launch ads in Europe, turning free users into revenue. Analysis of its strategy, trust challenges, and implications for AI industry monetization.

Mermail: Registration, Email, and Payment Infrastructure for AI Agents
Mermail provides AI agents with identity registration, email verification, and autonomous payment infrastructure via MCP, Skills, and CLI, enabling agents to act independently online.

GLM-5.3 Released: How Post-Training Scaling Is Reshaping AI Coding Capabilities
Z.ai releases GLM-5.3, achieving open-source SOTA in agentic coding through post-training scaling on the same base model, with emergent capabilities in vulnerability discovery and cyber defense.