Website Bisnis

Cara Marketer Indonesia Pasang HTML Dialog Element di Next.js untuk Modal Aksesibel Tanpa Library 2026

Vito Atmo
Vito Atmo·26 Mei 2026·0 kali dibaca·3 min baca
Cara Marketer Indonesia Pasang HTML Dialog Element di Next.js untuk Modal Aksesibel Tanpa Library 2026

TL;DR: HTML <dialog> adalah modal native yang sudah didukung evergreen browser sejak 2022. Di Next.js, pasang lewat client component dengan ref ke showModal() dan close(). Hasilnya: focus trap otomatis, Escape key bawaan, backdrop native, dan ukuran bundle yang lebih ringan dibanding solusi library.

Dalam beberapa audit aksesibilitas yang saya lakukan di proyek personal branding klien, modal custom adalah sumber temuan WCAG paling sering: fokus lolos keluar modal, Escape tidak menutup, atau screen reader tidak mengumumkan judul. Migrasi ke <dialog> menyelesaikan sebagian besar temuan itu sekaligus memangkas baris JavaScript modal sekitar 60-80 persen.

Artikel ini menunjukkan pola pemasangan yang saya pakai di Next.js 15 dengan App Router, termasuk kapan tetap memilih library dan kapan native sudah cukup.

Kenapa <dialog> Native, Bukan Library

Library modal seperti Radix Dialog atau Headless UI menambah 6-15 KB gzipped, sementara <dialog> adalah elemen HTML yang sudah ada di browser. Untuk situs marketing dengan target Core Web Vitals ketat, setiap KB JavaScript di first load berpengaruh ke INP dan TBT. Pelajari dasarnya di HTML Dialog Element.

Browser menyediakan tiga kemampuan gratis: focus trap otomatis saat showModal() dipanggil, Escape key handler, dan pseudo-element ::backdrop untuk lapisan gelap. Library hanya unggul untuk skenario kompleks seperti nested dialog atau portal kustom.

Pola Implementasi di Next.js

tsx
'use client';
import { useRef } from 'react';

export function ConfirmDialog() {
  const ref = useRef<HTMLDialogElement>(null);
  return (
    <>
      <button onClick={() => ref.current?.showModal()}>Buka</button>
      <dialog ref={ref} aria-labelledby="dlg-title">
        <form method="dialog">
          <h2 id="dlg-title">Konfirmasi</h2>
          <p>Yakin ingin menghapus draft ini?</p>
          <button value="cancel">Batal</button>
          <button value="confirm">Hapus</button>
        </form>
      </dialog>
    </>
  );
}

Tiga hal penting: 'use client' karena dialog perlu DOM ref, method="dialog" pada form supaya submit otomatis menutup dialog dengan returnValue, dan aria-labelledby untuk screen reader.

Studi Kasus Ade Mulyana

Saat refactor halaman dashboard notaris untuk Ade Mulyana, modal konfirmasi hapus dokumen sebelumnya memakai library 11 KB dengan dependencies tambahan. Setelah migrasi ke <dialog> native, ukuran bundle halaman dashboard turun dari 248 KB ke 231 KB gzipped, dan temuan axe-core soal focus trap hilang tanpa perlu kode tambahan. Pelengkap menarik untuk pop-up non-blocking seperti tooltip, kombinasikan dengan Popover API.

Pertanyaan Umum

Apakah <dialog> bekerja dengan View Transitions?

Ya. Anda bisa menambahkan transisi via View Transitions API untuk animasi buka-tutup yang halus.

Bagaimana dengan SSR Next.js?

Server akan merender <dialog> sebagai elemen tertutup. Jangan panggil showModal() di server. Selalu di event handler client.

Bagaimana styling backdrop?

Gunakan selector dialog::backdrop { background: rgba(0,0,0,0.5); }. Bisa juga di-animasikan via @starting-style di browser modern.

Penutup

<dialog> bukan pilihan terbaik untuk setiap kasus, tapi untuk 70-80 persen kebutuhan modal di situs marketing dan dashboard SaaS, ia menggantikan library tanpa kompromi aksesibilitas. Mulai dari konfirmasi sederhana, lihat pengurangan bundle dan temuan WCAG, lalu putuskan apakah library masih dibutuhkan untuk kasus kompleks.

Bagikan

Artikel Terkait

#nextjs#dialog-element#accessibility#modal#wcag

Butuh website yang benar-benar bekerja?

Hubungi Vito untuk konsultasi gratis 15 menit.

WhatsApp Sekarang