Reprint: Building a Daily Newspaper for My Archive
Why I turned my archive into a daily broadsheet called Reprint, how the edition pipeline and atomic archiving work, and why broadsheet layouts beat infinite feeds for reading old essays.
Over the last few years, I have written dozens of long essays, short development notes, poetry, and quick product updates. Most personal websites organize this material into a reverse chronological list where the newest entry sits at the very top and everything else sinks toward oblivion. That design works fine for a news wire, but it does a disservice to evergreen writing. An article written two years ago about system design or software architecture is often just as useful today as something published yesterday morning, yet a typical blog feed buries it under endless pagination that nobody clicks.
I wanted a different way to experience my own archive. Instead of asking readers to scroll through infinite lists or search through arbitrary category pages, I decided to treat my collection like a real daily broadsheet newspaper. Every morning, a new edition titled Reprint is assembled, printed, and published. It contains twelve stories, drawn from across my essays, dev notes, quick ships, research notes, and Substack dispatches. Once a day ends, that edition is frozen forever into an immutable archive.
The visual design of Reprint came from a desire for contrast and restraint. The rest of my website uses a dark glassmorphic interface with deep charcoal backgrounds, neon emerald accents, and fluid backdrop filters. For Reprint, I stepped away from that language entirely and built a clean white editorial surface that feels like sitting down with a printed morning paper. It uses Playfair Display for dramatic editorial headlines, Georgia for readable body text, and Relative Mono for datelines, volume numbers, and section kickers.
Building a physical newspaper layout on the web usually tempts developers to reach for heavy JavaScript grid libraries like Masonry or Packery. I avoided that complexity altogether. Modern CSS column layout handles multi-column broadsheets natively with column-count and column-gap rules. On desktop monitors, stories flow naturally across three columns with an editorial full-width lead story commanding the top. On tablets, the layout contracts gracefully to two columns, and on phones, it collapses into a single column. Reading order runs down each column cleanly without layout shifts or script execution overhead.
Behind this clean editorial front page sits an automated publication engine that handles aggregation, sanitization, selection, archiving, and distribution. The first challenge was source aggregation. My writings live across multiple data stores: long-form essays are stored as local MDX files and Sanity documents, short updates live in Contentful and Sanity, and syndicated essays publish to Substack. Rather than having the newspaper trigger HTTP requests back to my own website feeds, the ingestion engine imports internal data loaders directly in memory. This eliminates unnecessary round trips and keeps page rendering nearly instantaneous.
External feeds, such as the Substack Atom feed, pass through a strictly hardened XML parser. I configured fast-xml-parser with a six-second timeout, a one-megabyte response limit, and an HTTPS allowlist that prevents arbitrary URL requests. Entity expansions and XML doctype declarations are completely rejected to protect the server from parser exploits. If an external feed fails or responds slowly, the pipeline catches the error and drops that source cleanly without interrupting the rest of the edition.
Incoming stories pass through a normalization pass that standardizes their attributes into a single data shape. This pass strips marketing tracking parameters such as UTM tags, Facebook click identifiers, and Google click parameters. It generates clean excerpt previews, validates publication dates against the edition cutoff, and deduplicates stories using both normalized canonical paths and title hashes.
Once the candidate stories are gathered and cleaned, the selection algorithm builds the day's front page. A naive random picker would feel disjointed, while a pure recency sort would just recreate the exact blog feed I was trying to escape. The selection engine strikes a balance through three rules. First, any work published within the preceding seven days receives a recency score boost, guaranteeing that genuine fresh updates lead the edition. Second, older backlog items receive a deterministic daily score using a hash of the edition date and the story identifier, so the back catalogue rotates evenly every morning without shifting unexpectedly throughout the day. Third, stories are distributed across sections using round-robin balancing so essays, quick ships, and technical notes each get fair representation, capped at exactly twelve stories.
The heart of the newspaper is its concept of persistence. A printed newspaper is permanent: once ink meets paper, the words on that morning broadsheet do not change when the journalist writes a correction next week. I wanted that exact guarantee for Reprint. When a day's edition is generated, the entire front page layout, including headlines, excerpts, ordering, and rendered HTML reading copies, is packaged into an atomic snapshot document and stored in Sanity. The document ID is deterministic, taking the form reprint-edition followed by the date in Indian Standard Time.
By using Sanity createIfNotExists, the system handles concurrent first visits gracefully. If two readers open the newspaper at the exact same second after midnight, both attempt atomic creation, the database elects a single winner, and both readers view the identical frozen snapshot. Once stored, that edition is immutable. If I edit a typo in an essay three months later, the original essay updates, but the historical newspaper edition from September 2026 remains preserved exactly as it was printed. Furthermore, past editions are never fabricated from current feeds: if a date was never printed, the archive refuses to reconstruct it and informs the reader that the edition was not published.
When someone wants to read a story, navigating away to a separate full-page URL would break the immersive feeling of holding a newspaper. Instead, clicking any story opens a native HTML dialog element as an editorial reading sheet. The URL updates using window history pushState with a story fragment, so refreshing the page or sharing the link reopens that exact reading modal. Closing the sheet restores focus to the broadsheet headline and preserves the user previous scroll position without jarring jumps.
To keep the initial front page load lightweight, the newspaper loads only story metadata on initial render. The full sanitized reading HTML is either rendered on demand or retrieved from the cached snapshot. External stories from Substack or other publications provide only an excerpt and an outgoing link, preventing third-party scripts or tracking code from executing inside my site.
Another feature I care deeply about is the PDF export. Many websites implement PDF generation by spinning up headless Chromium instances inside serverless functions. That approach introduces massive cold start delays, inflates cloud infrastructure bills, and regularly crashes due to memory limits. I took the opposite approach and solved it entirely through CSS print style rules.
When a reader clicks Export PDF in the toolbar, the client waits for the web fonts to finish loading and then opens the standard browser print dialog. Because the page is styled with dedicated print rules, the browser immediately renders an A4 document with two clean columns, elegant serif headlines, restrained dividers, and running headers. The server executes zero additional compute, latency is virtually instantaneous, and the reader gets a tangible document they can save or send to an e-reader.
The entire publication cycle is tied together with a daily Vercel cron job that executes at 18:35 UTC, corresponding to 00:05 in India. The endpoint validates a secure bearer token, initiates the day edition build, triggers the atomic Sanity snapshot, and dispatches an editorial morning dispatch email to my inbox through Mailgun. If the cron job ever fails or is delayed, the system falls back safely: the first reader who visits the site in the morning triggers the print run automatically.
Building Reprint gave my writing collection a sense of rhythm and finish that standard blog feeds lack. It values old work alongside new experiments, imposes a healthy limit on daily reading, and delivers an experience that honors the tradition of editorial print while taking advantage of modern web standards.
