Episode ini membahas accessibility dan pengalaman pengguna: ARIA roles, keyboard navigation dan focus management, semantic HTML dan accessible forms, responsive layout dan inclusive design, serta dasar internationalization dan localization.

Aplikasi yang dapat diakses bukan hanya kewajiban etis, tetapi juga memperluas jangkauan pengguna dan meningkatkan kualitas pengalaman bagi semua orang. Episode 17 membahas accessibility dan UX di SvelteKit: ARIA roles, navigasi keyboard, semantic HTML, form yang aksesibel, desain inklusif, serta dasar internationalization.
Prinsipnya sederhana: semua orang, apa pun alat bantu yang dipakainya, harus bisa memakai aplikasi dengan setara. Layar pembaca, pengguna keyboard, dan layar sentuh semuanya berhak mendapatkan pengalaman yang lengkap, bukan versi yang lebih kecil.
Setelah episode ini, kalian bisa membangun antarmuka yang ramah alat bantu, form yang mudah dipahami, dan struktur yang siap diterjemahkan ke banyak bahasa.
Elemen semantik seperti header, nav, main, footer, dan h1 sampai h6 memberi struktur yang bisa dipahami pembaca layar. Struktur yang benar bahkan lebih penting daripada atribut ARIA: gunakan elemen native terlebih dahulu, dan tambahkan ARIA hanya saat elemen native tidak memadai.
<a class="skip-link" href="#konten">Lewati ke konten utama</a>
<nav aria-label="Navigasi utama">
<ul>
<li><a href="/">Beranda</a></li>
<li><a href="/artikel">Artikel</a></li>
</ul>
</nav>
<main id="konten">
<h1>Judul halaman</h1>
</main>Saat konten berubah secara asinkron, misalnya pesan error atau hasil pencarian, pembaca layar perlu diberi tahu. Atribut aria-live="polite" membuat perubahan diumumkan tanpa memindahkan fokus pengguna secara paksa.
<script>
let hasil = $state([]);
let sedangMencari = $state(false);
</script>
<p aria-live="polite">
{#if sedangMencari}Mencari...{:else}{hasil.length} hasil ditemukan{/if}
</p>Pastikan urutan tab mengikuti alur visual dan logis: navigasi, konten utama, lalu tindakan sekunder. Elemen interaktif asli seperti a, button, dan input sudah bisa difokuskan secara default; hindari membuat elemen non-interaktif bisa menerima fokus tanpa kebutuhan nyata.
Saat membuka dialog, pindahkan fokus ke elemen pertama dan kembalikan ke pemicunya saat dialog ditutup. Saat berpindah halaman dengan route, pastikan judul halaman dan fokus berubah agar pengguna pembaca layar tahu konteks baru.
Setiap input butuh label yang terhubung lewat atribut for dan id. Pesan error dihubungkan dengan aria-describedby, dan nilai aria-invalid menandai input yang gagal validasi sehingga pengguna yang hanya memakai keyboard atau pembaca layar tetap paham apa yang salah.
<script>
let nama = $state("");
let error = $state("");
</script>
<form method="POST" action="?/simpan">
<label for="nama">Nama lengkap</label>
<input
id="nama"
name="nama"
bind:value={nama}
aria-invalid={error ? "true" : "false"}
aria-describedby={error ? "error-nama" : undefined}
/>
{#if error}
<p id="error-nama" class="error" role="alert">{error}</p>
{/if}
</form>Desain inklusif dimulai dari tata letak yang berfungsi di layar kecil lalu berkembang. Gunakan unit yang relatif, container queries, dan pastikan kontras teks memenuhi rasio yang direkomendasikan. Jangan mengandalkan warna sebagai satu-satunya penanda status — tambahkan ikon atau teks.
<span class="status status-ok" role="status">Tersedia</span>Aplikasi yang siap mendunia memisahkan semua teks dari kode. Simpan terjemahan dalam satu struktur terpusat dan pilih bahasa sesuai preferensi pengguna, atribut lang pada HTML, atau URL seperti /en dan /id. Pustaka seperti paraglide-svelte mempermudah alur ini di SvelteKit; pasang dengan npm install -D @inlang/paraglide-sveltekit lalu ikuti panduan setup-nya.
export const terjemahan = {
id: { sapa: "Halo dunia", cari: "Cari" },
en: { sapa: "Hello world", cari: "Search" }
};
export const terjemahkan = (locale, kunci) =>
terjemahan[locale]?.[kunci] ?? kunci;Inti yang harus dibawa pulang:
aria-live.for dan aria-describedby.Di episode 18 selanjutnya kita membahas architecture & maintainability: feature-based structure dan modular routing, separation of concerns antara UI, data, dan server logic, reusable composables dan utility modules, serta organisasi kode yang skalabel untuk tim.