Meta: charset dan viewport
Dua baris meta paling krusial: utf-8 wajib pertama agar karakter tidak rusak, viewport agar web tidak hancur di HP.
Dua Baris yang Menentukan Hidup-Mati Halaman
Dari semua baris di head, dua yang paling krusial justru paling sering diremehkan: charset dan viewport. Salah menaruh charset, karakter Indonesia seperti "é" atau emoji berubah jadi simbol rusak (mojibake). Lupa viewport, situs yang rapi di laptop berubah jadi halaman mungil yang harus di-zoom di HP. Keduanya adalah fondasi sebelum CSS dan JavaScript apa pun.
charset: utf-8 Wajib Pertama
Browser membaca HTML sebagai byte mentah, lalu harus menebak cara mengubah byte menjadi karakter. meta charset="utf-8" memberi tahu jawabannya. UTF-8 mencakup hampir semua karakter dunia: latin, Arab, CJK, emoji.
Kenapa harus pertama di dalam head? Karena browser mulai menebak encoding sejak byte pertama. Kalau deklarasi charset datang terlambat (setelah title panjang atau script besar), browser mungkin sudah salah menebak dan menampilkan karakter rusak sebelum sempat dikoreksi. Aturannya: taruh dalam 1024 byte pertama dokumen, praktisnya baris pertama setelah <head>.
<head>
<meta charset="utf-8" />
<title>Warkop Kita</title>
<!-- sisanya menyusul -->
</head>Contoh kerusakan nyata: halaman tanpa charset yang memuat kata "café" bisa tampil sebagai "café", dan emoji berubah jadi kotak-kotak. Satu baris mencegah semuanya.
viewport: Kunci Web Mobile
Browser HP punya perilaku warisan dari era iPhone pertama: mereka me-render halaman seolah layarnya 980px lebarnya, lalu mengecilkan hasilnya agar muat di layar kecil. Akibatnya situs desktop tampil utuh tapi mungil, teks tidak terbaca, pengguna harus cubit-zoom untuk tiap paragraf.
Meta viewport mematikan perilaku itu:
<meta name="viewport" content="width=device-width, initial-scale=1" />Artinya: "lebar viewport = lebar perangkat, zoom awal = 100%". Sekarang CSS pixel sama dengan lebar layar HP, dan media query responsifmu akhirnya bekerja sebagaimana mestinya.
Before / After
Tanpa viewport, di HP:
<!-- SEBELUM: halaman di-render 980px lalu dikecilkan -->
<head>
<meta charset="utf-8" />
<title>Toko</title>
</head>Hasilnya: teks sebesar semut, tombol sulit disentuh, pengguna langsung pergi.
Dengan viewport:
<!-- SESUDAH: halaman mengikuti lebar perangkat -->
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Toko</title>
</head>Hasilnya: layout mengalir mengikuti layar, media query aktif, teks terbaca tanpa zoom. Inilah alasan "mobile-friendly" Google mensyaratkan viewport: tanpanya, peringkat mobile-mu anjlok.
Contoh Lengkap head Minimal
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Warkop Kita: Kopi Tubruk Autentik</title>
<meta name="description" content="Warkop Kita menyajikan kopi tubruk autentik di Bandung." />
</head>
<body>
<h1>Selamat datang</h1>
</body>
</html>Urutan ini bukan kebetulan: charset dulu (agar parsing benar), viewport kedua (agar rendering benar), baru title dan sisanya.
Salah vs Benar
<!-- SALAH: charset tenggelam setelah script besar -->
<head>
<title>Toko</title>
<script src="bundle-besar.js"></script>
<meta charset="utf-8" />
</head>
<!-- BENAR: charset baris pertama -->
<head>
<meta charset="utf-8" />
<title>Toko</title>
<script src="bundle-besar.js"></script>
</head><!-- SALAH: mematikan zoom merusak aksesibilitas -->
<!-- pengguna low-vision tidak bisa memperbesar teks -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<!-- BENAR: biarkan pengguna mengontrol zoom -->
<meta name="viewport" content="width=device-width, initial-scale=1" />maximum-scale=1 dan user-scalable=no memang membuat tampilan "terkunci rapi", tapi harganya mahal: pengguna dengan penglihatan terbatas tidak bisa memperbesar teks. Jangan pernah pakai keduanya kecuali kamu membangun aplikasi kios tertutup.
Catatan teknis: Header HTTP
Content-Type: text/html; charset=utf-8dari server mengalahkan meta charset. Meta charset hanyalah fallback saat server tidak mengirim info encoding (mis. file dibuka lokal via file://). Jadi pastikan server juga mengirim header yang benar, dan anggap meta charset sebagai jaring pengaman, bukan satu-satunya pertahanan.
export default function App(): JSX.Element { return <h1>Hello world</h1> }
Tantangan
Perbaiki head yang Rusak
Starter berisi head yang salah: charset ada tapi setelah script besar, dan viewport mematikan zoom (maximum-scale=1, user-scalable=no). Perbaiki keduanya: charset jadi baris pertama, viewport jadi width=device-width + initial-scale=1 saja. Dua baris ini menentukan apakah jutaan pengguna HP bisa membaca situsmu atau langsung pergi.
<!doctype html> <html lang="id"> <head> <title>Toko</title> <script src="bundle-besar.js"></script> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> </head> <body> <h1>Toko Kita</h1> </body> </html>