Blog Engineering Guide

How an article gets published on this blog

Find creators, get their email, run the campaign.

Start a 3-day trial

The steps from a request to a live page on virev.ai, who does each one, and how long the build takes (median 65 seconds over 156 builds). Compared with WordPress, Ghost, Substack, Notion and MDX sites.

Illustration: an article folder with en.md, ko.md, ja.md, components and data goes through git push and appears about 65 seconds later as a live page at virev.ai/blog in English, Korean and Japanese.

This blog has no editor screen and no publish button. An article is a folder of text files in our code repository. It goes live when that folder reaches the sieun/dev branch on GitHub, and Vercel rebuilds the site. Over the 156 production builds between 1 and 8 October, the build took a median of 65 seconds.

Most articles here are written by an agent. A person asks for the article in chat, reads the preview and approves it. The agent runs the git commands. The person never opens a terminal, but a git push is still what publishes every page.

Posting an article, step by step

Here is the whole path for one new article, with who does each step. The person does three of the eight steps, and a second agent can do the approval.

  1. 1 You

    Ask for the article

    One message in chat: the topic, the reader, the languages.

  2. 2 Agent

    Create the folder

    Makes content/<slug>/en.md with draft: true.

    pnpm new <slug>
  3. 3 Agent

    Write it

    Prose in en.md, ko.md and ja.md. Components and data go in the same folder.

  4. 4 You

    Read the preview

    The dev server on port 5179 shows the page as readers will see it.

    pnpm dev

    updates in under 0.5 s after a save

  5. 5 You

    Approve

    A reviewer, a person or a second agent, sets draft: false.

  6. 6 Agent Publishes

    Commit and push

    commit.mjs takes only the files named, then one push.

    git push origin sieun/dev
  7. 7 Vercel

    Build the whole blog

    Every article in every language, rendered to static HTML.

    median 65 s

  8. 8 Vercel

    Live

    /blog/<slug>, /ko/blog/<slug> and /ja/blog/<slug> on virev.ai.

Step 6 is the publish button. Before it, the article exists only on one computer. After it, Vercel takes over.

The draft flag does most of the work in this flow. A file with draft: true still renders, so the preview is the real page with the real layout. It is kept out of the home page, the collection hubs, the sitemap and the feed, and it carries a noindex tag. The reviewer flips the flag in the same commit that publishes the article.

The person also never deals with the language switch. A language is published when its file exists and is not a draft. That one rule feeds the language menu, the hreflang links and the sitemap, so adding ja.md later is the whole job of adding Japanese.

What is inside the folder

This article is a folder too. Everything it needs is in it:

Text
apps/blog/content/how-virev-blog-works/
├── en.md
├── ko.md
├── ja.md
├── components/
│   ├── PostingFlow.svelte
│   └── BuildTimes.svelte
└── data/
    └── builds.csv

The step diagram above is PostingFlow.svelte, written for this page only. The three language files import it and pass it their own text. No other article loads it, and no shared template had to change to add it.

The chart below is the second component. It reads data/builds.csv, 156 rows taken from the Vercel API. The numbers are parsed when the site builds, so the chart shows the data in the commit that published it.

How long the build takes

Production builds of the blog, 1 to 8 October 2026, grouped by duration in seconds. 156 builds.

Half of the builds took between 61 and 71 seconds. The slowest took 169 seconds. Each build renders all 345 English articles, 14 Korean and 12 Japanese editions, drafts included, because the site is rebuilt from scratch every time.

The build is not the only wait. The blog shares the sieun/dev branch with the rest of our code, and every push to it starts a blog build, whatever the push changed. In the week measured, 113 of the 156 builds came from a push whose newest commit did not touch the blog. Another 170 builds were canceled while still queued, and a newer build took their place.

Articles also wait for the branch. On 5 October three article commits were live 1.2 to 1.5 minutes after they were made. On 7 and 8 October two batches of articles were committed but not pushed for 4.4 and 5.6 hours, while pushes to the shared branch were paused until other changes passed their checks.

How other blog systems handle the same post

Take one article with one custom interactive chart, and compare what each system asks of the person writing it.

SystemHow you publishA custom interactive chart
WordPress.comPublish button in the editorScripts need a plugin-enabled plan
GhostPublish button in the editorHTML card plus code injection for the post
SubstackPublish button, web or emailNot supported
Notion SitesPublish the page with one clickHost it elsewhere, embed the URL
Next.js or Astro (MDX)Commit and push, the host buildsImport a component into the .mdx file
This blogCommit and push, Vercel buildsA Svelte file in the article folder

The first four are content management systems. The writer logs in, clicks a button and the page is live at once, with no build. Custom code is the hard part. On WordPress.com, a script in a Custom HTML block runs only on a plugin-enabled plan with hosting features turned on. Ghost takes custom code in an HTML card and in the post's own code injection field, so the chart's code is stored inside the post, outside any code repository. Substack does not support custom HTML, CSS or iframe code in the post editor. Notion embeds content from more than 1,900 sites through Iframely, so the chart has to live on a site Notion can embed.

The last two keep articles as files in git. Astro and Next.js both let an MDX file import a component, and our blog does the same with mdsvex, the Svelte version of MDX. A chart is ordinary code in the repository. A component that fails to compile or to render fails the build, before any reader sees it. The cost is the build and someone who can run git.

Our blog sits in the git group. The agent takes the git part, so the person keeps the steps of a content management system: ask, read, approve.

What an article can hold

A folder can hold any Svelte component, so an article can have its own animation, interaction or layout without a change to the site. Next to that, every article can use the shared blocks:

  • Chart draws an ECharts chart and keeps an HTML table of the same rows for readers without JavaScript, crawlers and screen readers.
  • Callout, Figure and Sidenote cover asides, images with captions and notes in the margin. Markdown footnotes become margin notes at build time.
  • Embed puts a piece of one-off HTML in a sandboxed frame.
  • import rows from './data/file.csv' gives a component the rows of a CSV file.
  • style.css in the folder styles that article only, when every selector starts with .article-<slug>.

The limits come from the same design. A one-word fix takes the same path as a new article: a commit, a push and a full build. There is no scheduled publishing, because nothing flips draft on a date. And a new component reaches readers only after a build that passes.

When something goes wrong

A broken article fails the build, and a failed build is never served. The previous build stays live and the build log names the file. Two production builds failed on 1 October, and readers kept the build before them.

To take a published article down or undo a change, there are two ways:

  1. Revert the commit on sieun/dev and push. The next build no longer has the change.
  2. Promote the previous deployment in the Vercel dashboard. That takes effect at once and needs no commit. Revert the commit afterwards, so the repository matches what is live.

Sources

  1. Add code to your site WordPress.com Supportaccessed Oct 8, 2026
  2. How to use Code Injection in Ghost Ghostaccessed Oct 8, 2026
  3. Cards Ghost Help Centeraccessed Oct 8, 2026
  4. Publishing and scheduling Ghost Help Centeraccessed Oct 8, 2026
  5. Can I edit the CSS or HTML on Substack? Substack Supportaccessed Oct 8, 2026
  6. Embeds, bookmarks & link mentions Notion Help Centeraccessed Oct 8, 2026
  7. Publish a website with Notion Sites Notion Help Centeraccessed Oct 8, 2026
  8. @astrojs/mdx Astro Docsaccessed Oct 8, 2026
  9. How to use markdown and MDX in Next.js Next.js Docsaccessed Oct 8, 2026