Migrasi Daftar Klien dari Gambar ke Data-Driven di Next.js
242 nama klien tadinya cuma hidup di dalam gambar. Kini mereka keindeks mesin pencari, kebaca screen reader, dan totalnya dihitung dari datanya.
Ringkasan
Dulu daftar 242 klien cuma nempel di satu gambar gede jadi nggak bisa dicopy atau keindeks Google. Akhirnya semua nama dipindah ke kode TypeScript jadi teks asli yang kebaca mesin pencari dan screen reader. Gambar logo tetap dipajang buat visual tapi sekarang ada transkrip teksnya biar tetap sesuai aturan WCAG.
Saya buka tab Elements di browser, sorot bagian daftar klien di halaman profil perusahaan, dan yang keluar cuma satu tag gambar. Dulu, 242 nama perusahaan itu hidup di dalam satu file raster besar. Nggak bisa di-copy, nggak kebaca screen reader, dan nggak keindeks sebagai konten nyata sama sekali.
Awalnya saya pikir solusi tercepat adalah ngasih atribut alt panjang banget berisi semua nama di dalam gambar itu. Tapi setelah cek ulang dokumentasi, itu bukan jalan keluar yang berkelanjutan. Google memang ngindeks gambar lewat elemen img standar dengan atribut src, tapi teks yang tersusun di dalam pixel tetap nggak kebaca sebagai konten yang bisa dicari [1]. Atribut alt juga nggak dipangku buat ini: dia bagus guna mendeskripsikan gambar, bukan menyembunyikan artikel di dalamnya. Background image malah lebih parah lagi, Google menyebutnya langsung: gambar yang dirender lewat CSS nggak diindeks [1].
Halaman kelihatan mewah, tapi isinya yang paling penting nggak bisa dicari siapa pun.
Membangun Satu Sumber Kebenaran
Saya putuskan pindahkan semua data itu ke dalam kode. Sumbernya PDF company profile: 242 nama saya kelompokkan jadi 21 grup sektor, satu modul TypeScript bersama bernama client-names.ts, nge-export array yang tiap elemennya punya properti sector buat nama industri dan names buat daftar nama perusahaan. Nama ditulis verbatim dari dokumennya, termasuk format titik dan koma yang nggak seragam, karena ini daftar bukti, bukan daftar yang rapi-rapi.
interface SectorGroup {
sector: string;
names: string[];
}
export const clientGroups: SectorGroup[] = [
{
sector: "Energi",
names: ["PT. Contoh Energi", "PT. Contoh Power Indonesia"]
},
{
sector: "Perbankan",
names: ["PT. Contoh Bank Sejahtera", "Bank Contoh Digital"]
}
];
export const totalClients = clientGroups.reduce(
(acc, group) => acc + group.names.length,
0
);
Total 242 perusahaan sekarang dihitung langsung pakai reduce dari panjang datanya. Angka di halaman jadi nggak mungkin telat update, karena dia lahir dari data yang sama. Halamannya pakai Next.js App Router, jadi komponen ini otomatis jalan sebagai Server Component: data didekatin di tempat sumbernya ada, dan JavaScript yang dikirim ke browser pun lebih ringan [3].
Cara mastiin hasilnya gampang. Buka view-source halaman client, cari nama salah satu klien. Muncul sebagai teks di HTML? Berarti dia resmi jadi konten. Dulu pas namanya cuma tinggal di dalam gambar, pencarian itu selalu nihil.
Gambarnya Tetap Dipertahankan, Ini Alasannya
Lalu, kalau teksnya udah lengkap, kenapa gambar logo wall nggak dibuang aja biar bersih? WCAG 2.2 punya kriteria spesifik soal ini, Success Criterion 1.4.5 Images of Text level AA: kalo presentasi visual yang sama bisa dicapai pakai teks asli, ya pakai teks asli. Ada dua pengecualian, dan salah satunya presentasi yang essential kayak logotype atau nama merek [2]. Aturan ini justru membolehkan kombinasi yang saya pakai: gambar berisi teks yang disertai informasi sama dalam bentuk teks asli di sebelahnya tetap dianggap conforming [2].
Makanya gambar tetap saya taruh di bagian atas sebagai bukti visual, persis pola poster plus transkrip di dokumentasinya. Yang nggak berubah: brand harus tampil sebagai brand. Yang berubah: bagian yang ngomong ke mesin pencari dan screen reader sekarang teks murni, bukan pixel.
Trade-off yang Saya Terima
Jadikan konten sebagai kode berarti tiap ada klien baru, saya harus commit dan deploy ulang. Ada juga risiko salah ketik pas mindahin data dari PDF ke array, dan nggak ada gate SEO yang nangkep typo nama perusahaan.
Dua-duanya nyata, dan saya tetap memilih jalan ini.
Soalnya perubahan daftar klien itu frekuensinya jarang banget. Untung dari struktur begini, datanya gampang di-query, gampang difilter per sektor, dan ramah aksesibilitas, jauh lebih besar dibanding ribetnya update sesekali.
Sekarang angka total yang tampil di halaman selalu sinkron dengan data aktual. Nggak ada lagi tebak-tebakan, dan tiap nama punya tempat yang bisa dicari, dibaca, dan dikutip.
Sumber: