Kalian akan mengatur dua theme sekaligus lewat objek theme, memakai CSS custom properties --shiki-dark dan --shiki-light, menyesuaikan warna lewat prefers-color-scheme, serta menyiapkan theme per konten dengan kontras dan aksesibilitas yang baik.

Situs modern mendukung mode gelap dan terang. Tanpa penanganan khusus, code block akan tetap memakai satu warna dan terlihat aneh di salah satu mode. Solusinya bukan dua kali render, melainkan satu render dengan dua theme sekaligus.
Episode 15 membahas multiple themes: objek theme dark dan light, CSS custom properties --shiki-dark dan --shiki-light, pengalihan otomatis lewat prefers-color-scheme, serta pertimbangan theme per konten dan aksesibilitas. Setelah episode ini, code block kalian menyesuaikan mode tanpa JavaScript.
rehype-pretty-code menerima objek theme dengan dua kunci. Setiap kunci memuat satu theme bawaan:
const options = {
theme: {
dark: "github-dark-default",
light: "github-light-default",
},
};Dengan konfigurasi ini, Shiki mewarnai kode dua kali dalam satu pemanggilan: sekali dengan theme gelap dan sekali dengan theme terang. Token kedua hasil warnanya disimpan sebagai CSS custom properties pada elemen hasil.
Pendekatan dua blok terpisah menggandakan markup dan membingungkan screen reader. Pendekatan CSS variables menjaga satu elemen <code> dengan dua set warna. Browser hanya memilih set yang aktif berdasarkan mode, sehingga konten tetap satu sumber kebenaran.
Untuk setiap token, Shiki menyimpan warna dark ke --shiki-dark dan warna light ke --shiki-light. Pada elemen <code> hasil, atribut style berisi kedua variabel tersebut:
<code style="--shiki-dark: #a5d6ff; --shiki-light: #0550ae;">
<span style="color: var(--shiki-dark)">const</span>
</code>Elemen span memakai color: var(--shiki-dark) secara default. Tugas kalian di CSS hanya mengganti variabel yang aktif saat mode berubah.
Pertama tentukan warna default untuk mode terang, lalu timpa dengan mode gelap:
[data-rehype-pretty-code-figure] span {
color: var(--shiki-light);
}
@media (prefers-color-scheme: dark) {
[data-rehype-pretty-code-figure] span {
color: var(--shiki-dark);
}
}Media query prefers-color-scheme: dark mengalihkan seluruh token ke palet gelap otomatis sesuai pengaturan sistem. Tanpa JavaScript, satu blok kode menyesuaikan diri dengan mode sistem pengunjung.
Warna token hanya setengah dari pekerjaan; background blok juga harus berubah. Matikan background bawaan dengan keepBackground: false lalu atur sendiri di CSS:
const options = {
theme: {
dark: "github-dark-default",
light: "github-light-default",
},
keepBackground: false,
};[data-rehype-pretty-code-figure] pre {
background: #ffffff;
}
@media (prefers-color-scheme: dark) {
[data-rehype-pretty-code-figure] pre {
background: #0d1117;
}
}Dengan keepBackground: false, background dipegang penuh oleh CSS. Ini memudahkan kalian menyamakan background code block dengan warna section di sekitarnya.
prefers-color-scheme mengikuti sistem, tetapi beberapa situs menawarkan toggle manual. Ubah media query menjadi class pada elemen root:
html.dark [data-rehype-pretty-code-figure] span {
color: var(--shiki-dark);
}Kombinasi keduanya umum: default mengikuti sistem, sementara class dark atau light menimpa saat pengguna memilih secara manual.
Tidak semua konten harus memakai theme yang sama. Kalian bisa memilih theme per halaman dengan menyimpan pilihan theme pada frontmatter dan meneruskannya ke opsi plugin. Ini berguna untuk artikel dengan ilustrasi kode yang dirancang khusus.
Dua theme yang dipilih harus sama-sama memenuhi kontras yang baik terhadap background masing-masing. Uji dengan alat cek kontras untuk scope utama seperti keyword, string, dan comment. Hindari memakai dua theme yang keduanya redup, karena salah satu mode akan sulit dibaca.
Samakan palet code block dengan palet keseluruhan situs. Jika situs memakai accent tertentu, pilih theme Shiki yang senada. Konsistensi ini membuat transisi dark dan light terasa menyatu, bukan seperti dua situs berbeda.
Inti yang harus dibawa pulang:
dark dan light menghasilkan dua warna sekaligus.--shiki-dark dan --shiki-light.var(--shiki-dark) dan ditimpa CSS per mode.prefers-color-scheme mengalihkan mode otomatis tanpa JavaScript.keepBackground: false memindahkan background ke CSS.Di episode 16 kalian akan belajar copy button dan interaksi UI: menambahkan tombol salin kode di sisi klien dengan memanfaatkan data attributes, menyiapkan keterangan dan layout responsive, serta memastikan aksesibilitas lewat aria-label dan navigasi keyboard.