Halusinasi DOM: 5 Bug Struktur Liar dari AI
Ringkasan Lingkup: Contoh di bawah menggunakan React dan Next.js App Router (SSR), tetapi masalah struktural ini berlaku untuk kerangka kerja modern apa pun yang menangani hidrasi DOM dan payload HTML.
Cursor dan Copilot dapat membangun komponen kompleks dalam hitungan detik. Struktur logis terlihat teratur, kompiler TypeScript tidak memiliki keluhan, dan kelas utilitas Tailwind terlihat sempurna. Namun, saat dideploy ke staging, Anda mungkin melihat konsol membuang kesalahan hidrasi React (hydration error), tata letak rusak secara tidak terduga di Safari, atau pembaca layar (screen reader) secara agresif melewati blok konten. Selamat datang di dunia halusinasi pohon DOM yang membuat frustrasi.
Asisten kode AI unggul dalam menghasilkan markup yang lengkap secara visual, tetapi mereka rutin mengabaikan spesifikasi DOM HTML5. Saat melakukan vibe-coding melalui fitur-fitur MVP, mudah untuk memercayai struktur AI karena terlihat benar secara visual. Namun, kesalahan pemetaan DOM yang senyap ini jarang memicu peringatan sintaksis atau kegagalan ESLint standar. Mereka bersembunyi di basis kode sampai mesin parsing browser modern mencoba memperbaikinya, sehingga menghasilkan pergeseran tata letak yang kacau dan ketidakcocokan hidrasi (hydration mismatch).
Berikut adalah 5 bug struktur teratas yang kemungkinan besar ditulis oleh generator AI Anda saat ini, dan alasan mengapa mengandalkan linting sederhana tidak akan menangkapnya.
Bom Hidrasi Paragraf
Critical - Ketidakcocokan status aplikasi - React Hydration Failure
Asisten AI mengelompokkan teks dan elemen secara logis untuk membangun komponen visual. Saat diminta untuk menata paragraf yang kompleks dengan kutipan blok atau kotak bergaya di dalamnya, mereka sering kali menumpuk elemen tingkat blok (block-level) <div> di dalam tag inline <p>.
Bad AI Code:
<p>
Here is the main text of the article.
<div className="highlight-box">Ini adalah kotak callout yang penting.</div>
Melanjutkan teks...
</p>
Kenyataannya: Spesifikasi HTML5 tidak mengizinkan elemen tingkat blok (<div>) berada di dalam elemen konten frasa (<p>). Saat HTML ini tiba dari server Anda melalui SSR, browser mencoba memperbaiki DOM yang tidak valid secara otomatis dengan menutup tag <p> sebelum <div> dimulai.
Saat React mencoba melakukan hidrasi pada klien, ia mencari <p> yang berisi <div>. Sebaliknya, ia menemukan node saudara (sibling nodes) yang benar-benar terpisah. Ketidakcocokan ini memicu kesalahan hidrasi React yang kritis, yang dapat menjatuhkan interaktivitas sisi klien untuk seluruh sub-pohon komponen tersebut.
Fixed Code:
<div>
<p>Here is the main text of the article.</p>
<div className="highlight-box">Ini adalah kotak callout yang penting.</div>
<p>Melanjutkan teks...</p>
</div>
WebValid menganalisis pelanggaran semantik HTML yang sangat dalam ini segera pada halaman yang dirender, sehingga Anda dapat menemukan bom hidrasi jauh sebelum mencapai produksi.
Insepsi Interaktivitas
High - Konteks navigasi rusak - Pelanggaran Standar HTML5
Jika Anda meminta “komponen kartu yang dapat diklik dengan tombol tindakan internal”, refleks AI segera membungkus seluruh kartu visual dalam tag <a> atau <Link>, dan kemudian menumpuk tombol interaktif langsung di dalam tautan tersebut.
Bad AI Code:
<a href="/dashboard/metrics">
<div className="card">
<h3>Monthly Metrics</h3>
<p>Lihat statistik Anda</p>
<button onClick={handleExport}>Ekspor Data</button>
</div>
</a>
Standar HTML melarang keras penumpukan elemen interaktif di dalam elemen interaktif lainnya (seperti <button> di dalam <a>). Meskipun sering kali dirender secara visual dengan benar, hal ini secara mendasar merusak teknologi asistif, membingungkan pembaca layar tentang cara mengumumkan tindakan tersebut. Selain itu, bubbling acara klik menjadi kacau; mengeklik tombol ekspor Anda mungkin mengeksekusi pengunduhan dan secara instan mendorong browser ke halaman berikutnya.
Untuk wawasan lebih lanjut tentang bagaimana output LLM generik menurunkan semantik, jelajahi panduan kami tentang kesalahan aksesibilitas AI.
Perang Klon Pengidentifikasi
High - Selektor CSS rusak dan anchor routing - Keunikan ID DOM
Ketika AI membangun blok iterasi (.map()) untuk merender daftar atau kisi, ia sering kali melakukan hardcode pada atribut yang seharusnya merupakan instansi unik. Target yang paling umum adalah atribut id.
Bad AI Code:
{
items.map((item) => (
<article
id="feature-card"
key={item.id}
>
<h2>{item.name}</h2>
</article>
));
}
Jika array data menampung 10 item, kode tersebut membangun 10 elemen berbeda dengan id="feature-card". Akibatnya, logika apa pun yang menggunakan document.getElementById gagal atau hanya mengembalikan node pertama. Perilaku dependen — seperti pemosisian jangkar (anchor positioning) CSS, perutean hash halaman internal, atau pengikatan aria-controls — akan retak. Pengklonan ID sangat sulit ditangkap dalam tinjauan PR karena snippet komponen yang terisolasi tampak benar.
Mutasi Anak Daftar
Medium - Kerusakan struktur semantik - Spek DOM HTML5
Saat Anda memperkenalkan React Fragments bersama logika perutean kondisional, model AI sering kali merusak struktur daftar asli. Asisten yang mencoba menyisipkan pembagi visual secara asli memasukkannya sebagai elemen saudara langsung di dalam daftar.
Bad AI Code:
<ul>
{messages.map((msg, index) => (
<React.Fragment key={msg.id}>
<li>{msg.text}</li>
{index !== messages.length - 1 && <div className="divider" />}
</React.Fragment>
))}
</ul>
Induk <ul> mengharapkan pembungkus <li> secara ketat untuk elemen pohon visual. Memasukkan <div> acak langsung sebagai anak akan membongkar perhitungan pohon aksesibilitas. Browser juga mungkin mencoba perbaikan DOM untuk membungkus saudara yang tidak valid, yang menyebabkan lompatan tata letak kecil saat proses paint.
Resolusi memerlukan penataan pembagi di dalam elemen <li> atau membuang struktur <ul> demi tata letak kisi (grid) CSS semantik menggunakan <div>.
Fantom Badan Tabel yang Hilang
Critical - Reflow tata letak paksa dan kegagalan hidrasi - DOM Construction
Tabel memiliki perilaku parsing yang ditentukan secara ketat yang sering dilewati oleh generator AI demi singkatnya kode. Pola yang sering terjadi melibatkan pembuatan baris tabel langsung di bawah pembungkus tabel inti.
Bad AI Code:
<table>
<tr>
<td>Status</td>
<td>Active</td>
</tr>
</table>
Menurut Standar HTML, penulis diizinkan untuk menghilangkan tag <tbody> dalam HTML mentah tanpa gaya. Namun, ketika browser modern memproses <tr> tanpa induk body, ia secara otomatis mengubah DOM dengan menyuntikkan blok <tbody> untuk mengelompokkan baris-baris tersebut dengan aman.
Saat menghasilkan UI Anda dengan React di server, markup-nya sama persis dengan outputnya: <table><tr>. Namun saat browser klien menerimanya, parser menyuntikkan body: <table><tbody><tr>. React segera menandai perbedaan struktural, meruntuhkan node yang dirender server, dan memaksa siklus paint sisi klien yang lebih berat.
Jika Anda mengira batas struktural yang hilang itu buruk, pertimbangkan bagaimana AI Anda juga bisa membocorkan kunci API di dalam bundel dinamis dengan melintasi batas logika server-klien.
Cek Fakta: Apakah Linter Menangkap Ini?
Opini: “Jika saya menggunakan konfigurasi ESLint yang ketat, kesalahan pemetaan AI akan segera tertangkap.”
Bukti: Salah. Paket linter utama (seperti eslint-plugin-react) secara asli menganalisis AST JavaScript dan jalur kode. Mereka tidak sepenuhnya mensimulasikan mutasi pohon browser atau penyesuaian struktural paska hidrasi. Meskipun alat seperti eslint-plugin-jsx-a11y melakukan pekerjaan yang sangat baik dalam menemukan pelanggaran statis (seperti menumpuk <button> di dalam <a> pada tingkat sumber), mereka tidak dapat memprediksi bagaimana komposisi komponen yang tidak lengkap atau injeksi fragmen dinamis akan menghasilkan struktur DOM akhir. Memvalidasi tata letak struktural halaman Anda secara nyata menuntut penilaian DOM akhir yang dieksekusi, persis seperti yang dibangun oleh mesin render.
Berhenti Menebak, Mulai Memvalidasi
Kopilot AI Anda adalah pengetik yang sangat baik, tetapi terkadang bermain-main dengan arsitektur HTML.
| Tipe Bug | Tertangkap oleh AI Generatif/Linter? | Tertangkap oleh WebValid DOM Scan? |
|---|---|---|
Ketidakcocokan hidrasi (<div> di <p>) | ❌ Jarang | ✅ Ya |
Atribut id kloning dalam array map | ❌ Tidak | ✅ Ya |
| Elemen interaktif bertumpuk | ⚠️ Hanya cek statis | ✅ Ya |
Elemen struktural tidak valid (<tbody>) | ❌ Tidak | ✅ Ya |
Tinjauan kode statis tidak dapat melacak secara akurat bagaimana Safari atau Chrome memperbaiki elemen ilegal secara otomatis. Keyakinan struktural yang nyata membutuhkan evaluasi tata letak yang terhidrasi secara aktual.
Checklist QA Struktural Anda
Validasi implementasi AI terhadap aturan dasar ini:
- Pastikan tidak ada komponen tingkat blok yang berada langsung di dalam tag teks inline (
p,span). - Pisahkan logika navigasi eksternal dari tombol tindakan komponen internal.
- Validasi loop iterasi yang memetakan nilai
idunik secara dinamis. - Tetapkan aturan
<tbody>eksplisit di semua konfigurasi tabel.
Alat AI dapat menulis kode yang sangat mumpuni — mereka hanya kesulitan memvisualisasikan regresi struktural. Berikan agen Anda peta kesalahan yang tepat, dan ia akan memperbaiki semuanya sendiri.
Mulai audit lingkungan lokal dan staging Anda secara gratis dan tangkap halusinasi DOM sebelum mencapai produksi.