Build1 distinct publisher3 min readUpdated
A dev.to build log mirrors a public REST API into static JSON and ships it to Cloudflare's edge. The failure mode disappears; the request count and the staleness question do not.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
A developer has published a build log for a reference site with 1,025 entries across 8 languages that has no runtime data backend: the public REST API is fetched once at build time, written to static JSON under `/public/api/v2/`, and served from Cloudflare Pages [1][2][3]. The consequence is the interesting part, because a whole class of production failures gets deleted rather than mitigated: according to the author there are no API keys, no rate limits, and no external dependency at request time [6].
The reasoning is stated plainly. Hitting the upstream API on every request would be slow and rate-limited, a conventional backend was overkill for data that is effectively static, and the audience is global so multilingual support was mandatory [4]. The stack is Next.js 15, TypeScript, Tailwind, next-intl and Cloudflare Pages [2]. Per entry the mirror stores core data (stats, types, abilities, moves, dimensions), species data (flavor text, egg groups, habitat, generation), full evolution chains including trigger conditions, and damage relations for all 18 types [5]. That is at least 2,068 JSON files before evolution chains are counted: one entry file and one species file for each of 1,025 records, plus one per type [3]. The payoff beyond latency is auditability - the data sits in version control, so a diff shows exactly what changed upstream [7].
The cost shows up on the client. The author reports that loading all entries at once would freeze the browser, so the grid fetches in batches of 50 with a progressive `setEntries` call after each batch, then uses an Intersection Observer with a 200px root margin to reveal 50 more cards per scroll [9][10][11]. Filtering is all local: 9 generations, 18 types, a base-stat-total range, legendary and shiny toggles, and text search by name or number [8]. At 50 per batch, a full unfiltered pool takes 21 rounds [1], and because each entry is fetched by id through a per-id cache, a cold visit to the index can issue up to 1,025 separate JSON requests [2]. Cheap against a CDN with 300-plus edge locations [6], but a single prebuilt index file carrying id, name, types and stats would do the same job in one request. The grid only needs those four fields [11].
Two things in the write-up are softer than the headline. The detail pages use server-side rendering to fetch entry, species and evolution chain data [12], so "zero backend" means no data backend, not no server-side compute. And the sub-second load time is the author's own figure with no measurement method given [1].
What to watch: rebuild cadence, which the post does not specify. A build-time mirror is only as fresh as its last deploy, and the freshness policy is the thing you are actually buying with this trade. Watch build duration too, since the fetch-once step scales linearly with record count and any locale fan-out. The post describes localized flavor text as a field inside the species data rather than as separate per-locale mirrors [5], so whether 8 locales multiply the file count or not is unresolved in the source. If it does multiply, the same 1,025 records become 8,200 files [4], and the build step becomes the bottleneck the backend used to be.
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The author states the approach works because Next.js serves /public files as static assets, the Cloudflare CDN caches them globally across 300+ edge locations, and there are no API keys, no rate limits and no external dependency at runtime.
The mirrored data is version-controlled, so it is possible to see exactly what changed.
The author states that loading all entries at once would freeze the browser, so the solution is batch loading with progressive rendering.
The loading code uses PAGE_SIZE = 50, slicing the pool into batches of 50, fetching each batch with Promise.all, and calling setEntries after every batch so users see cards appearing.
An Intersection Observer with rootMargin '200px' increments visibleCount by PAGE_SIZE as the user scrolls; the grid retains only id, name, types and stats per loaded entry, and per-entry fetches go through an in-memory cache keyed by id in src/lib/api.ts.
Stack: Next.js 15, TypeScript, Tailwind CSS, next-intl, Cloudflare Pages.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Detailed self-report, no independent verification
The source is unusually specific for a build log — real code paths (src/lib/api.ts), concrete constants (PAGE_SIZE = 50, rootMargin '200px'), an architecture diagram, the SSR detail-page component and the localization lookup — which makes the architecture claims internally checkable and lets several derived figures be computed directly. But it is one self-published post by the builder, with no live URL result, no repository listing, no latency measurement and no second account, so nothing outside the author's narration corroborates the outcomes.
One self-described personal deployment
The only adoption signal is the author's own account of deploying a personal project to Cloudflare Pages. There are no users, traffic figures, repository stars, forks, downstream reuse, or any third-party report of the pattern in the supplied material, so adoption cannot be scored without inventing facts.
Framing outruns the measurements it rests on
'Zero backend' and 'sub-second load times' are stronger than the post's own evidence supports. SSR still runs on Cloudflare Workers, so server-side execution remains in the path; a cold full-index render can issue up to 1,025 separate static JSON requests across 21 awaited batch rounds; and the runtime API dependency has been converted into a build-time one whose refresh cadence, cache invalidation and upstream terms of use are never mentioned. The underlying technique is sound and honestly documented at the code level, which keeps the gap moderate rather than severe.
Self-promotional build log, no disclosed commercial tie
The author is documenting and implicitly showcasing their own project on a developer publishing platform, which favours a clean, successful narrative and a favourable read of the chosen stack — including a bullet praising Cloudflare's free tier and the OpenNext adapter as 'seamless'. No sponsorship, employment relationship or vendor affiliation is disclosed or implied in the supplied material, and the code-level detail is the kind that invites scrutiny, so the incentive to overstate is real but ordinary rather than commercial.
Architecture claims solid, outcomes unverified
Confidence is moderate: the mechanics of the pattern are documented well enough to be reproduced and the derived arithmetic follows directly from stated constants, so the 'how' is reliable. The 'how well' is not — a single self-interested publisher, zero performance measurement and no adoption evidence leave the outcome claims and any generalisation to larger or faster-changing datasets weakly grounded.
build
Two Next.js apps instead of one, because isAdmin is a privilege escalation waiting to happen1 distinct publisher
build
At 70,000 images, next/image is not your optimizer, it is your outage1 distinct publisher
build
Tailwind v4 moves your tokens into CSS. The token name is now the API.1 distinct publisher
build
The third answer: a dead-code tool allowed to say "not traced yet"1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 15, 2026