Migrasi CKEditor Editor.js Laravel yang aman memperlakukan pergantian editor sebagai perubahan format konten, bukan cuma package npm baru. Anda audit HTML lama, tentukan schema block Editor.js, dan validasi payload di server.
Selanjutnya siapkan renderer untuk format lama dan baru. Lalu rollout bertahap dengan backup dan rencana rollback sebelum tim mengganti UI editor di modul produksi.
CKEditor 4 versi open-source reguler sudah End of Life sejak 30 Juni 2023 (pengumuman EOL CKEditor 4). Namun thread komunitas developer (diskusi r/PHP tentang migrasi Laravel) masih mempertanyakan arsitektur aplikasi besar yang wajib pindah ke Editor.js tanpa merusak konten lama—konteks diskusi, bukan spesifikasi resmi framework.
Highlight
Migrasi Editor Konten di Laravel dari CKEditor 4 ke Editor.js: Strategi Bertahap dan Penanganan HTML Lama
- CKEditor 4 umumnya menyimpan HTML; Editor.js `save()` menghasilkan object dengan `blocks`, `time`, dan `version` (dokumentasi penyimpanan Editor.js).
- Validasi client Editor.js tidak menggantikan validasi server—Tool API punya `validate`/`sanitize`, tetapi payload bisa dimanipulasi (Tools API Editor.js).
- Penanda format eksplisit (`html` vs `editorjs`) kerap lebih mudah diaudit daripada menebak isi field.
- Rollback UI editor dan rollback data hasil konversi adalah dua jalur berbeda; feature flag tidak memulihkan database.
- Repository Pattern mengatur persistensi data, bukan otomatis menjadi tempat logic editor atau renderer.
Mengapa CKEditor 4 ke Editor.js Bukan Drop-in?

Tim kerap memakai CKEditor 4 sebagai WYSIWYG yang menulis HTML ke kolom teks. Editor.js menyimpan blok terstruktur. Jadi storage, validasi, dan rendering ikut berubah meski label field di form tetap sama.
Contoh konseptual HTML lama:
<h2>Judul</h2>
<p>Isi artikel...</p>
<ul><li>Item</li></ul>
Contoh bentuk output Editor.js (angka `time` hanya ilustrasi):
{
"time": 1720000000000,
"blocks": [
{ "type": "header", "data": { "text": "Judul", "level": 2 } },
{ "type": "paragraph", "data": { "text": "Isi artikel..." } }
],
"version": "2.28.0"
}
Pergantian ke Editor.js di Laravel gagal cepat bila tim hanya mengganti widget di Blade/Vue/React tanpa kontrak data baru. Namun backend, export, search index, dan feed RSS yang membaca field lama ikut terdampak.
Audit Sebelum Migrasi Editor Laravel
Sebelum commit roadmap, petakan modul yang masih memuat CKEditor, nama field penyimpanan, plugin CKEditor aktif, custom tag/atribut, embed media, serta cara frontend dan API merender HTML.
Agar estimasi realistis, anggap checklist ini contoh—hasil audit nyata bergantung codebase Anda.
Kemudian telusuri apakah sanitasi HTML sudah ada, siapa yang boleh mengedit, dan test otomatis mana yang melindungi save/render. Tanpa inventaris, converter HTML→block akan menebak-nebak markup yang sudah tahunan di produksi.
Langsung “Sikat” atau Migrasi Bertahap?
Langsung mengganti semua modul sekaligus: satu editor setelah cut-over, tetapi blast radius besar dan rollback sulit bila satu modul belum siap. Migrasi bertahap memindahkan modul per modul; scope kecil, namun dua format hidup bersamaan sampai exit criteria jelas.
Untuk banyak aplikasi produksi berukuran besar, rollout bertahap dapat mengecilkan blast radius—kelayakannya tetap bergantung relasi data dan coupling antar modul.
Meski demikian, jangan anggap salah satu strategi selalu benar tanpa audit.
Penanda Format dan Coexistence Data
Aplikasi perlu tahu record ini HTML CKEditor atau JSON Editor.js. Opsi umum: kolom discriminator (`content_format = html | editorjs`), kolom terpisah (`legacy_html` + `editor_content`), atau deteksi heuristik isi field. Metadata eksplisit lebih deterministik untuk query progress migrasi; heuristik JSON vs HTML rapuh pada edge case.
Contoh arsitektur renderer (bukan requirement Laravel): caller memanggil `ContentRenderer` yang mendelegasikan ke `LegacyHtmlRenderer` atau `EditorJsRenderer`. Pola ini memudahkan dual-format selama transisi.
Strategi HTML Lama Tanpa Overwrite Massal
Jangan jalankan `SELECT semua HTML → converter → JSON → overwrite` sebagai langkah pertama. Risikonya markup unsupported, plugin lama, iframe/tabel, HTML malformed, dan semantic loss saat round-trip belum teruji.
Berikut tiga model yang tim sering bandingkan:
- Legacy tetap HTML — tim tidak konversi paksa record lama; record baru memakai Editor.js; renderer pilih format.
- Convert on edit — saat modul baru membuka draft lama, converter jalan sekali; editor mengecek sebelum save.
- Batch migration — setelah mapping stabil, fixture uji, backup, dan rollback path siap.
Model retain HTML + rollout modul baru sering lebih konservatif daripada konversi destruktif massal, tetapi tetap butuh rencana menutup utang format ganda.
Validasi Editor.js, Sanitasi, dan Backend Laravel
Validasi menjawab apakah bentuk data sesuai aturan aplikasi. Sanitasi menjawab elemen HTML mana yang boleh bila aplikasi menerima HTML. Output encoding menjawab bagaimana teks aman di konteks HTML/atribut/URL (OWASP XSS Prevention). Ketiganya berbeda; `strip_tags()` saja atau Blade `{{ }}` saja tidak menutup seluruh permukaan Editor.js.
Payload Editor.js perlu lebih dari “field harus JSON”. Periksa object top-level, `blocks` sebagai array, `type` pada allowlist Tool proyek, bentuk `data` per type, batas jumlah block, dan URL embed/gambar. Laravel mendukung validasi array nested—syntax spesifik mengikuti versi Laravel Anda; lihat dokumentasi validasi Laravel.
Renderer block: `type` → renderer terdaftar → output aman. Jangan render `data.text` sebagai raw HTML tanpa policy. Jangan menerima `type` arbitrer lalu memanggil class dinamis.
Walau frontend SPA ikut merender, server-side rendering tetap relevan untuk SEO, cache, dan keamanan.
Repository Pattern dan Lokasi Logic
Keberadaan repository tidak otomatis menentukan tempat integrasi Editor.js. Validation input cocok di Form Request; transformasi format di service konten; persistensi di repository bila aplikasi memang memakai abstraction itu; rendering di layer presentasi atau view composer—pembagian tanggung jawab, bukan template folder resmi.
Buat service terpisah bila Anda pakai logic format lintas modul: validate schema, normalize block, detect legacy, migrate on read. Bila hanya glue code di satu fitur, lapisan extra belum tentu perlu.
Periode Dual-Editor dan Exit Criteria
Selama CKEditor dan Editor.js coexist, dokumentasikan modul mana memakai editor mana, format save, cara QA, dan tanggal target penonaktifan CKEditor. Transisi bukan arsitektur permanen.
Exit criteria contoh: semua modul edit memakai Editor.js; legacy read-only atau tim sudah konversi record; dependency CKEditor tidak lagi diload; log tidak menunjukkan jalur save HTML lama.
Feature flag mengontrol UI rollout, tetapi flag itu tidak mengembalikan data yang tim overwrite.
Rollback, Backup, dan Pengujian Migrasi Editor Laravel
Backup data sebelum deployment berisiko; jangan drop kolom HTML lama pada rilis pertama; migrasi destruktif paling akhir. Rollback editor UI dan rollback isi database adalah rencana terpisah.
Akhirnya log record yang tim konversi saat batch migration jalan.
Prosedur backup dan export database relevan sebelum fase konversi—bukan cuma untuk WordPress, melainkan prinsip snapshot sebelum schema atau mass update berlaku juga pada aplikasi Laravel custom.
Uji unit: validator block, renderer, deteksi format. Fixture HTML nyata: heading, list, link, gambar, tabel jika modul memakai tabel, HTML malformed, atribut custom.
Kemudian uji integrasi: edit konten lama, save JSON baru, authorization upload gambar Tool Editor.js. Uji keamanan: script tag, URL `javascript:`, atribut event, block type tak dikenal.
Jadi log metrik sederhana—record gagal konversi, block tidak dikenal, payload invalid—membantu memperluas rollout sebelum batch migration. Observability tidak mengganti backup, tetapi memberi sinyal awal saat dual-format masih aktif.
Fase Rollout (Contoh Alur)
Berikut urutan contoh, bukan resep universal:
- Inventaris CKEditor dan sample HTML.
- Definisikan Tool Editor.js + allowlist block + kontrak renderer.
- Compatibility layer baca/render HTML lama dan JSON baru.
- Pilot satu modul risiko terkendali.
- Expand modul lain berdasarkan metrik error dan QA.
- Tangani legacy: retain, convert-on-edit, atau batch terkontrol.
- Decommission CKEditor setelah dependency habis.
Tim yang memakai VSCode atau Cursor tetap perlu review diff schema migration dan test fixture—AI editor tidak mengganti checklist keamanan.
Anti-Pattern Migrasi Editor
Hindari mengganti UI dulu baru mikir format data. Jangan overwrite HTML massal tanpa uji.
Tetap waspada: JSON bukan otomatis aman; validasi client saja tidak cukup; campur HTML dan JSON tanpa discriminator; hapus data legacy sebelum jendela rollback; abaikan plugin CKEditor lama; menaruh seluruh logic Editor.js di repository hanya karena pola itu ada di proyek.
CKEditor 4 LTS komersial masih tersedia untuk pihak yang membeli Extended Support (model Extended Support CKEditor 4)—status instalasi Anda bergantung versi dan lisensi, bukan asumsi “semua instance pasti rentan”.
Penutup: Modernisasi Aplikasi Laravel
Pergantian CKEditor ke Editor.js di Laravel selesai bila format data, keamanan render, dan legacy HTML terkelola, bukan cuma bila npm package terpasang. Perlakukan pekerjaan ini sebagai modernisasi konten sepanjang lifecycle aplikasi, sejalan diskusi ekosistem framework PHP yang menekankan maintenance jangka panjang.
Bila tim internal butuh bantuan audit schema, compatibility layer, atau rollout modul produksi, CodeF melayani pengembangan dan maintenance aplikasi web—mulai dari snapshot database sampai pilot modul—tanpa menjanjikan zero-downtime tanpa tinjauan sistem nyata.