ブログ エンジニアリング ガイド

このブログに記事が公開されるまで

クリエイターを見つけ、メールを取得し、キャンペーンを運用。

3日間トライアルを始める

依頼ひとつから virev.ai の公開ページまでの手順、各手順の担当、ビルドにかかる時間(156回のビルドの中央値で65秒)をまとめました。WordPress、Ghost、Substack、Notion、MDX サイトとも比べます。

イラスト:en.md、ko.md、ja.md、components、data を含む記事フォルダが git push を経て、約65秒後に virev.ai/blog で英語、韓国語、日本語のページとして公開される様子。

このブログには編集画面も公開ボタンもありません。記事1本は、私たちのコードリポジトリにあるテキストファイルのフォルダひとつです。そのフォルダが GitHub の sieun/dev ブランチに入ると、Vercel がサイトをビルドし直し、記事が公開されます。10月1日から8日までの本番ビルド156回では、所要時間の中央値は65秒でした。

このブログの記事の多くはエージェントが書いています。人はチャットで記事を依頼し、プレビューを読み、承認します。git のコマンドはエージェントが実行します。人がターミナルを開くことはありませんが、すべてのページを公開しているのは今も git push です。

記事1本を公開する手順

新しい記事1本がたどる経路の全体と、各手順の担当です。8つの手順のうち、人が行うのは3つで、承認は別のエージェントが担当することもできます。

  1. 1 人

    記事を依頼する

    チャットのメッセージひとつで、テーマ、読者、言語を伝えます。

  2. 2 エージェント

    フォルダを作る

    draft: true の状態で content/<slug>/en.md を作ります。

    pnpm new <slug>
  3. 3 エージェント

    書く

    en.md、ko.md、ja.md に本文を書き、コンポーネントとデータも同じフォルダに置きます。

  4. 4 人

    プレビューを読む

    ポート5179の開発サーバーが、読者が見るとおりのページを表示します。

    pnpm dev

    保存から0.5秒以内に反映

  5. 5 人

    承認する

    人でも別のエージェントでも、レビュー担当が draft: false にします。

  6. 6 エージェント ここで公開

    コミットしてプッシュする

    commit.mjs は指定したファイルだけをコミットし、プッシュは1回です。

    git push origin sieun/dev
  7. 7 Vercel

    ブログ全体をビルドする

    すべての言語のすべての記事を静的 HTML にします。

    中央値65秒

  8. 8 Vercel

    公開

    virev.ai の /blog/<slug>、/ko/blog/<slug>、/ja/blog/<slug>。

6番目の手順が公開ボタンにあたります。それまで記事は1台のコンピューターにしかありません。その後は Vercel が引き継ぎます。

この流れでいちばん多くの仕事をしているのは draft フラグです。draft: true のファイルもページとして描画されるので、プレビューは実際のレイアウトを備えた実際のページです。ただしホーム、コレクションのハブ、サイトマップ、フィードには載らず、noindex タグが付きます。レビュー担当は、記事を公開するコミットでこのフラグを切り替えます。

言語の切り替えも人が気にする必要はありません。言語ごとのファイルがあり、draft でなければ、その言語が公開されます。この1つのルールが言語メニュー、hreflang リンク、サイトマップを決めます。あとから日本語を加える作業は、ja.md を置くことだけです。

フォルダの中身

この記事もフォルダひとつです。必要なものはすべてその中にあります。

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

上の手順図は、このページのためだけに書いた PostingFlow.svelte です。3つの言語ファイルがそれぞれこれを読み込み、自分の言語の文言を渡しています。ほかの記事はこれを読み込まず、追加するために共通テンプレートを変える必要もありませんでした。

下のグラフが2つ目のコンポーネントです。Vercel API から取得した156行の data/builds.csv を読みます。数値はサイトのビルド時に解析されるので、グラフは記事を公開したコミットに含まれていたデータを表示します。

ビルドにかかる時間

2026年10月1日から8日までのブログ本番ビルド156回を、所要時間(秒)ごとにまとめました。

ビルドの半数は61秒から71秒で終わりました。最も長かったのは169秒です。サイトを毎回ゼロから作り直すので、ビルドのたびに英語記事345本と韓国語版14本、日本語版12本を、下書きも含めてすべて描画します。

待ち時間はビルドだけではありません。ブログは sieun/dev ブランチをほかのコードと共有しており、このブランチへのプッシュがあると、何を変えたかに関係なくブログのビルドが始まります。計測した1週間では、156回のうち113回が、最新のコミットがブログに触れていないプッシュから始まっていました。ほかに170回のビルドが待機中に取り消され、より新しいビルドに置き換わりました。

記事もブランチを待ちます。10月5日には記事のコミット3件が、コミットから1.2分から1.5分で公開されました。10月7日と8日には記事のまとまり2つが、コミットされたまま4.4時間と5.6時間プッシュされませんでした。ほかの変更がチェックを通るまで、共有ブランチへのプッシュが止められていたためです。

ほかのブログシステムでは同じ記事をどう公開するか

自作のインタラクティブなグラフを1つ含む記事1本を例に、各システムが記事を書く人に何を求めるかを比べました。

システム公開の方法自作のインタラクティブなグラフ
WordPress.comエディターの公開ボタンスクリプトはプラグイン対応プランのみ
Ghostエディターの公開ボタンHTML カードと記事ごとのコード挿入
Substack公開ボタン、Web かメール非対応
Notion Sitesクリック1回でページを公開別の場所に置き、URL を埋め込む
Next.js、Astro(MDX)コミットとプッシュ、ホストがビルド.mdx ファイルにコンポーネントを import
このブログコミットとプッシュ、Vercel がビルド記事フォルダ内の Svelte ファイル

最初の4つはコンテンツ管理システムです。ログインしてボタンを押せば、ビルドなしですぐに公開されます。難しいのは自作のコードです。WordPress.com では、Custom HTML ブロックのスクリプトは、プラグインを使えるプランでホスティング機能を有効にした場合にだけ動きます。Ghost は HTML カードと、記事ごとのコード挿入欄で自作のコードを受け付けます。そのためグラフのコードは、コードリポジトリの外、記事の中に保存されます。Substack は投稿エディターでの自作の HTML、CSS、iframe コードに対応していません。Notion は Iframely を通じて1,900以上のサイトのコンテンツを埋め込めるので、グラフは Notion が埋め込めるサイトに別に置く必要があります。

残りの2つは、記事を git の中のファイルとして扱います。Astro も Next.js も MDX ファイルからコンポーネントを読み込めます。私たちのブログは、MDX の Svelte 版である mdsvex で同じことをしています。グラフはリポジトリの中の普通のコードです。コンパイルや描画に失敗するコンポーネントはビルドを失敗させるので、読者の目に触れる前に止まります。代わりに必要なのは、ビルドの時間と、git を扱える人です。

私たちのブログは git の側にあります。git の作業はエージェントが受け持つので、人に残るのはコンテンツ管理システムと同じ手順です。依頼し、読み、承認することです。

記事に入れられるもの

フォルダにはどんな Svelte コンポーネントでも置けます。そのため、サイトを変えずに、記事ごとに独自のアニメーション、インタラクション、レイアウトを持てます。あわせて、どの記事も共通ブロックを使えます。

  • Chart は ECharts のグラフを描き、JavaScript なしで読む読者、クローラー、スクリーンリーダーのために、同じ行の HTML の表も持っています。
  • Callout、Figure、Sidenote は補足、キャプション付きの画像、余白のメモを受け持ちます。Markdown の脚注はビルド時に余白のメモになります。
  • Embed は一度きりの HTML をサンドボックス化したフレームに入れます。
  • import rows from './data/file.csv' で、コンポーネントに CSV ファイルの行を渡せます。
  • フォルダ内の style.css は、すべてのセレクターを .article-<slug> で始めれば、その記事だけに適用されます。

制約も同じ設計から生まれます。1語の修正でも、新しい記事と同じ道をたどります。コミット、プッシュ、全体のビルドです。予約公開はありません。日付に合わせて draft を切り替える仕組みがないからです。新しいコンポーネントも、ビルドを通過して初めて読者に届きます。

問題が起きたとき

記事が壊れているとビルドが失敗し、失敗したビルドが配信されることはありません。前のビルドが公開されたまま残り、ビルドログに問題のファイルが表示されます。10月1日には本番ビルドが2回失敗し、読者はその前のビルドを見続けました。

公開した記事を取り下げる、または変更を元に戻す方法は2つです。

  1. sieun/dev でコミットを revert してプッシュします。次のビルドにはその変更が含まれません。
  2. Vercel のダッシュボードで前のデプロイを本番に昇格させます。コミットなしですぐに反映されます。そのあとでコミットを revert し、リポジトリと公開中のサイトをそろえます。

出典

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