Episode ini membahas ARIA roles, navigasi keyboard, dan focus management, semantic HTML dan form yang aksesibel, responsive design dengan pendekatan mobile-first, serta dasar internationalization atau i18n untuk aplikasi multi bahasa.

Aplikasi yang tidak aksesibel menutup pintu bagi jutaan pengguna — mereka yang memakai screen reader, hanya keyboard, atau layar kecil. Episode 17 menjadikan accessibility (a11y) dan UX sebagai bagian dari desain, bukan tambahan di akhir.
Kita akan membahas ARIA roles, navigasi keyboard dan focus management, semantic HTML dengan form aksesibel, responsive design mobile-first, dan dasar-dasar internationalization agar aplikasi menjangkau pengguna lintas bahasa.
ARIA (Accessible Rich Internet Applications) menjelaskan peran dan status elemen yang tidak punya semantic HTML bawaan. Misalnya tab panel:
function Tabs({ tabAktif, gantiTab }) {
return (
<div role="tablist">
<button
role="tab"
aria-selected={tabAktif === "profil"}
aria-controls="panel-profil"
onClick={() => gantiTab("profil")}
>
Profil
</button>
<div id="panel-profil" role="tabpanel" hidden={tabAktif !== "profil"}>
Konten profil
</div>
</div>
)
}role="tab" dan aria-selected memberi tahu screen reader bahwa tombol adalah tab dan mana yang aktif. aria-controls menghubungkan tab ke panelnya. Aturan penting: kalau ada elemen HTML semantik (button, nav, dialog), pakai itu dulu sebelum ARIA.
Pengguna keyboard harus bisa menjangkau semuanya. Dua titik perhatian utama:
outline: none) tanpa mengganti dengan indikator fokus yang jelas.import { useEffect, useRef } from "react"
function Modal() {
const refTombol = useRef(null)
useEffect(() => {
refTombol.current.focus()
}, [])
return (
<div role="dialog" aria-modal="true" aria-labelledby="judul-modal">
<h2 id="judul-modal">Konfirmasi</h2>
<button ref={refTombol}>Setuju</button>
</div>
)
}refTombol.current.focus() memindahkan fokus ke tombol utama saat modal dirender, sehingga keyboard dan screen reader langsung berada di tempat yang benar.
Gunakan elemen yang maknanya sudah dikenal pembaca layar:
nav untuk navigasi, main untuk konten utama, header dan footer.button untuk aksi, bukan div dengan onClick.label selalu terhubung ke input dengan htmlFor.<form>
<label htmlFor="email">Alamat email</label>
<input id="email" type="email" aria-describedby="email-hint" />
<p id="email-hint">Kami tidak akan membagikan email kamu.</p>
</form>aria-describedby="email-hint" menghubungkan input ke teks bantuan, yang dibaca screen reader saat input difokuskan. Form aksesibel juga memakai aria-invalid dan role="alert" untuk pesan error seperti episode 11.
Mobile-first berarti merancang untuk layar kecil dulu, lalu memperbesar dengan media query. Ukuran default sesuai layar sempit, min-width menambah gaya untuk layar lebih besar:
.kartu {
padding: 12px;
font-size: 14px;
}
@media (min-width: 768px) {
.kartu {
padding: 20px;
font-size: 16px;
}
}Media query @media (min-width: 768px) baru aktif di tablet ke atas. Pendekatan ini memaksa kalian memprioritaskan apa yang benar-benar penting di layar kecil.
Buat komponen yang fleksibel terhadap ukurannya. Pola umum: grid yang mengalir dengan auto-fit dan minmax:
.grid-produk {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
}repeat(auto-fit, minmax(200px, 1fr)) membuat kolom otomatis menyesuaikan lebar: satu kolom di ponsel, beberapa kolom di layar lebar — tanpa JavaScript.
Aplikasi yang ingin go international perlu internationalization: memisahkan teks dari kode. Library populer: react-i18next:
npm install i18next react-i18nextimport { useTranslation } from "react-i18next"
function SelamatDatang() {
const { t } = useTranslation()
return <h1>{t("selamatDatang", "Selamat datang!")}</h1>
}const { t } = useTranslation() mengambil fungsi t yang menerjemahkan kunci teks. File terjemahan berisi pasangan kunci dan teks per bahasa, dan pengguna bisa berpindah bahasa tanpa reload.
Tip
Jangan menulis teks langsung di dalam komponen untuk aplikasi multibahasa. Simpan semua teks di file terjemahan sejak awal — memindahkan teks yang sudah tersebar jauh lebih sulit daripada menaruhnya di satu tempat.
Episode 17 membuka aplikasi kalian untuk semua orang: ARIA roles dan keyboard navigation, focus management, semantic HTML dengan form aksesibel, responsive design mobile-first, dan dasar internationalization.
Inti yang harus dibawa pulang:
aria-invalid dan role="alert" membuat form aksesibel.min-width dan grid fleksibel.Di episode 18 selanjutnya kita akan membahas architecture & design patterns — component-driven architecture dan atomic design, feature modules dengan folder structure yang scalable, composition patterns dan render props, serta design system untuk UI yang konsisten. Arsitektur yang baik membuat tim bergerak cepat.