Skip to content
Konsultasi

Membedumkan Pipeline Embed Artikel Buatan Agen

Adityo Guni Waluyo

Pipeline embed artikel kini render token di dalam <pre>/<code> sebagai kode literal, degradasi ke fallback saat payload rusak, dan re-highlight blok Quarto/Pandoc.

Masalah: agen menulis token embed sebagai kode

Blog ini memakai kontrak <pre><code class="language-x"> untuk blok kode, dan token {{ youtube:... }} / {{ mermaid:... }} di prose untuk embed. Masalah muncul saat agen atau generator Markdown (Quarto, Pandoc) menulis contoh token embed di dalam blok kode , misalnya tutorial yang menjelaskan sintaks mermaid. Pipeline lama memindai seluruh HTML dengan satu regex token global, sehingga token di dalam <code> terseret jadi embed sungguhan, bukan teks kode. Parahnya, payload token rusak memicu error saat render server (SSR) dan menjebol halaman jadi 500.

Celah yang diperbaiki

1. Token di dalam <pre>/<code> harus literal

Perbaikan memisahkan HTML menjadi segmen berdasarkan region kode dulu, lalu regex token hanya dijalankan di segmen prose. Sebuah blok <pre>...</pre> atau <code>...</code> di-push utuh sebagai HTML literal , token di dalamnya tidak lagi diculik jadi embed. Tutorial yang menampilkan {{ mermaid:... }} sebagai contoh kini render sebagai kode, bukan diagram.

// sebelum: TOKEN_RE menyapu seluruh html
while ((m = TOKEN_RE.exec(html)) !== null) { ... }

// sesudah: split dulu per region kode
for (const segment of html.split(CODE_REGION_RE)) {
  if (segment.startsWith("<pre") || segment.startsWith("<code")) {
    blocks.push({ type: "html", html: segment });
    continue;
  }
  // token hanya diproses di sisa prose
}

2. Payload rusak tidak lagi 500

Kalau token tidak bisa didekode (base64 salah, JSON rusak), dulu ia melempar exception di SSR. Sekarang jatuh ke blok fallback [embed <kind> tidak valid] , halaman tetap utuh, hanya satu blok yang degradasi. Ini pelajaran umum: di boundary render, validasi input eksternal dan beri fallback daripada biarkan exception merambat ke respons HTTP 500.

3. Blok kode Quarto/Pandoc di-re-highlight

Generator dokumentasi sering memakai bentuk <pre class="sourceCode tsx"><code class="sourceCode tsx"> atau <pre class="tsx"><code>. Pipeline baru membaca bahasa dari atribut class (bukan cuma language-x) lewat langFromAttrs, lalu mengelupas span highlight bawaan Quarto supaya kode mentah di-highlight ulang ke jendela editor kita dengan tombol salin. Ia juga mengenali output Shiki sendiri (data-title / class shiki) dan membiarkannya verbatim , tidak memproses dua kali.

function langFromAttrs(preAttrs: string, codeAttrs: string): string | null {
  const cls = (attrs: string) => /class="([^"]*)"/.exec(attrs)?.[1] ?? "";
  const codeClass = cls(codeAttrs);
  const preClass = cls(preAttrs);
  if (/data-title=/.test(preAttrs) || /(?:^|\s)shiki\b/.test(preClass)) {
    return null;
  }
  for (const c of [codeClass, preClass]) {
    const m = /(?:^|\s)language-([\w-]+)/.exec(c) ?? /(?:^|\s)sourceCode\s+([\w-]+)/.exec(c);
    if (m) return m[1];
  }
  const first = preClass.trim().split(/\s+/)[0];
  return first && first !== "sourceCode" ? first : null;
}

Kenapa ini penting untuk konten otomatis

Semakin banyak artikel ditulis oleh agen, semakin besar kemungkinan agen perlu menunjukkan sintaks yang sedang dijelaskannya. Kontrak kode-yang-literal bukan fitur kecil: ia mencegah artikel rusak saat agen mendemokan embed, dan mencegah satu payload cacat menjatuhkan seluruh halaman. Pola ini sejalan dengan kontrak blok kode kanonik yang sudah dibahas di kontrak code block Shiki: id bahasa pendek, serta cara embed YouTube/Mermaid/Recharts tanpa plugin di-render.

Cara menerapkan di pipeline kamu

Pola ini tidak bergantung pada framework tertentu. Intinya tiga aturan: pertama, pisahkan region kode dari prose sebelum menjalankan parser token apa pun, supaya kode adalah teks suci. Kedua, setiap boundary render harus punya cabang kegagalan — payload rusak kembali ke blok fallback, bukan melempar exception ke HTTP 500. Ketiga, baca metadata blok (atribut class) daripada mengasumsikan satu bentuk penulisan, karena generator dokumentasi seperti Quarto atau Pandoc memakai variasi markup yang berbeda.

Untuk highlight, alat seperti Shiki atau rehype-shiki sudah menangani kasus umum melalui plugin Rehype. Tantangannya justru di batas: saat konten otomatis (agen, pipeline CMS) menyisipkan contoh sintaks yang sama dengan fitur embed. Memperlakukan blok kode sebagai wilayah terlarang untuk parser embed menyelamatkanmu dari satu artikel rusak yang merusak seluruh halaman.

Penutup

Pipeline embed kini memperlakukan blok kode sebagai wilayah suci: apa pun di dalamnya adalah teks, bukan perintah. Embed hanya hidup di prose, payload rusak degradasi ke fallback, dan generator dokumentasi lama tetap kehilangan jendela editor. Untuk penanganan tokenizer tingkat lebih rendah yang sempat race antar-panggilan, lihat race regex stateful lastIndex di Shiki.

Artikel terkait