Skip to content
Konsultasi

Pindah ke Grid, Pola Show More, dan Satu Trade-off SEO

Adityo Guni Waluyo

Refactor halaman services: kolom panjang jadi grid 3 kolom dengan pola Show More. Ada trade-off SEO yang baru disadari setelah cek view source.

Gue lagi ngerapiin halaman services klien, buka browser di mode mobile. Isinya 9 section "service detail" yang tadinya gue render sebagai satu kolom panjang kartu bernomor. Tiap kartu accordion, yang pertama otomatis kebuka pas load. Jujur keliatan rapi, tapi panjangnya ngeras banget di layar HP. Scroll terus nggak habis-habis, jempol gue capai. Accordion lama itu awalnya masuk akal buat mobile, satu kartu kebuka biar layar nggak penuh. Masalahnya muncul pas gue pengen layout yang lebih padat di desktop: kolom tunggal di monitor lebar itu mubazir, separuh layar cuma ruang kosong.

Keputusan awal simpel: pindah ke grid. Gue tambahin class Tailwind grid-cols-1 md:grid-cols-2 lg:grid-cols-3 biar di desktop kepenggal jadi tiga kolom. Kartu dibikin compact, tiap section dapet ikon dari iconMap yang key-nya pakai judul Indonesia. Training programs juga gue samain polanya, limit 6 poin, kartu disamain tinggi pakai items-stretch plus h-full.

Pas bikin grid, pola accordion lama langsung jadi aneh. Kode lama punya useState(index === 0) buat buka kartu pertama. Di grid, baris pertama langsung nampilin tiga kartu kebuka sekaligus. Berisik banget, mata langsung lari ke tiga blok teks panjang. Gue putusin tanpa ampun: semua kartu tertutup, daftar poin dipotong, kasih tombol Show More.

Grid dan batas server-client

Page page.tsx tetep Server Component, dia cuma ambil data JSON terus terusin ke komponen kartu. State Show More kan butuh interaktivitas, jadi gue taruh "use client" cuma di komponen kartu, bukan di page. Penjelasan soal pembagian ini gue ambil dari [dokumentasi Next.js untuk server dan client components](https://nextjs.org/docs/app/getting-started/server-and-client-components). Directive resminya bisa dilihat di [referensi use client directive](https://nextjs.org/docs/app/api-reference/directives/use-client). Kalau "use client" ditaruh di page, seluruh isi halaman ikut ke bundle browser. Ditaruh di kartu, yang kebundel cuma logika buka-tutup itu, datanya tetap di server.

"use client";
import { useState } from "react";
export function ServiceCard({ points }: { points: string[] }) {
  const [open, setOpen] = useState(false);
  const shown = open ? points : points.slice(0, 5);
  return (
    <div>
      {shown.map(p => <li key={p}>{p}</li>)}
      {!open && <button onClick={() => setOpen(true)}>Show More</button>}
    </div>
  );
}

Komponen di atas nurutin pola [conditional rendering dari React](https://react.dev/learn/conditional-rendering) — list yang ke-render bergantung state open. Pas tertutup, cuma points.slice(0, 5) yang muncul. Tombol klik bakal balikin seluruh array.

Trade-off sama SEO yang gue sadar telat

Pas testing, gue cek view source. Poin ke-6 dst emang nggak ada di HTML awal. Dia cuma muncul setelah klik. Buat halaman marketing klien, ini bikin gue mikir ulang. Google pakai [mobile-first indexing](https://developers.google.com/search/docs/crawling-indexing/mobile/mobile-sites-mobile-first-indexing) — yang di-index adalah konten versi mobile yang dirender, bukan semua yang ada di JS. Kalau poin tersembunyi nggak ada di DOM awal, ya nyaris nggak ada buat crawler.

Gue pribadi pilih slice + Show More buat kebersihan visual. Layar klien jadi adem, nggak ada tembok teks. Tapi opini gue tegas: kalau poin yang disembunyiin itu kata kunci jualan penting, mending render semua di server terus sembunyiin pakai CSS display:none atau max-height. Jangan di-slice di client. Konten tetep ada di HTML, SEO aman, interaksi tetep halus. Bonus kecil kalau ambil jalan CSS: tombolnya bisa dikasih aria-expanded biar screen reader tahu daftar itu bisa dibentang, dan crawler yang ngerender JS pun tetap nemuin teksnya tanpa perlu ngeklik apa-apa.

Training programs gue batasi 6 karena poin di situ lebih pendek, tapi prinsipnya sama. Angka 5 dan 6 itu bukan angka sakti, cuma hasil ngecek: di ukuran kartu grid, lima poin itu batas sebelum kartu kepanjangan dan jadi nggak seragam sama tetangganya. Kartu sama tinggi biar grid nggak bergoyang pas Show More diklik.

Gue sih tetep pakai slice buat situs ini karena audit kata kunci klien nunjukin poin nomor 6 ke atas nggak pernah dicari orang. Tapi kalau bulan depan ada campaign baru, gue bakal ubah ke render penuh plus CSS toggle. Keputusan itu murah gue ambil sekarang, dan kode kartu udah siap dipreteli kapan aja.

Kalau ini topik yang relevan, baca juga badge sertifikasi tanpa gambar yang bikin next/image crash dan kenapa tipe TypeScript nggak ikut ke JSON.

Artikel terkait