🏠 Home

πŸ“‚ Kategori

πŸ“ LekturπŸ“ FinansialπŸ“ Gadget
Cara Saya Kustomisasi VitePress Menjadi Blog Personal

Awalnya saya tidak percaya ini bisa dilakukan.

VitePress adalah static site generator buatan tim Vue.js. Tujuan utamanya jelas yaitu membuat dokumentasi teknis. Kalau kamu buka situs resminya, semua contoh yang ditampilkan adalah halaman docs, API reference, dan panduan penggunaan library. Tidak ada satu pun contoh blog di sana.

Tapi saya penasaran. Dan rasa penasaran itu akhirnya berubah menjadi proyek yang lebih serius dari yang saya bayangkan.

Kenapa VitePress, Bukan yang Lain ​

Sebelum sampai ke VitePress, saya sudah mencoba beberapa opsi. WordPress terasa terlalu besar untuk blog personal. Hugo cepat, tapi saya tidak akrab dengan Go. Astro menarik, tapi ekosistemnya terasa asing dan banyak lainnya yang sudah pernah saya coba jekyll dan 11ty juga.

VitePress menarik perhatian saya karena satu alasan sederhana, ia berbasis Vue.js, teknologi yang sudah saya kenal. Artinya kalau ada sesuatu yang tidak bisa dilakukan lewat konfigurasi, saya bisa tulis sendiri dalam bentuk komponen Vue.

Yang tidak saya duga adalah seberapa dalam kustomisasi yang bisa dilakukan.

Masalah Pertama: Tidak Ada Fitur Blog ​

VitePress tidak punya konsep "artikel" atau "post". Ia hanya tahu satu hal: file Markdown menjadi halaman HTML.

Tidak ada list artikel otomatis. Tidak ada pagination. Tidak ada kategori. Tidak ada sidebar berisi daftar tulisan terbaru.

Semua itu harus dibangun dari nol.

Langkah pertama yang saya lakukan adalah membaca artikel otomatis dari folder data/ menggunakan Node.js di dalam file konfigurasi VitePress. Dengan library gray-matter, saya bisa baca frontmatter setiap file Markdown, ambil judul, deskripsi, tanggal, dan kategori, lalu simpan sebagai data yang bisa diakses oleh semua komponen Vue.

js
function getArticles() {
  const dir = resolve(__dirname, '../data')
  const files = readdirSync(dir).filter(f => f.endsWith('.md'))
  return files.map(file => {
    const content = readFileSync(resolve(dir, file), 'utf-8')
    const { data } = matter(content)
    return {
      title: data.title,
      description: data.description,
      date: data.date,
      category: data.category,
      thumbnail: data.thumbnail,
      link: `/data/${file.replace('.md', '')}`,
    }
  }).sort((a, b) => new Date(b.date) - new Date(a.date))
}

Kode ini dijalankan saat build. Hasilnya disimpan di themeConfig dan bisa diakses dari mana saja lewat useData().

Membangun Custom Theme dari Nol ​

Ini bagian yang paling menyenangkan sekaligus paling melelahkan.

VitePress punya sistem theme yang cukup fleksibel. Kamu bisa extend theme bawaan, atau buat sepenuhnya dari nol. Saya memilih jalan tengah: extend theme bawaan tapi override layout utamanya.

Saya membuat file Layout.vue yang berfungsi sebagai router visual. Kalau path-nya /, tampilkan BlogHome.vue. Kalau path-nya diawali /kategori/, tampilkan KategoriPage.vue. Selain itu, tampilkan layout artikel biasa.

vue
<template>
  <BlogHome v-if="isHome" :articles="articles" />
  <KategoriPage v-else-if="isKategori" />
  <div v-else class="page-wrapper">
    <Navbar />
    <div class="page-content">
      <Breadcrumb v-if="isArticle" />
      <Content />
      <Giscus v-if="isArticle" />
    </div>
    <BlogFooter />
  </div>
</template>

Sederhana di permukaan, tapi di baliknya ada cukup banyak logika.

Hero Section yang Selalu Dinamis ​

Salah satu fitur yang paling saya sukai adalah hero section di halaman utama.

Artikel yang paling baru secara otomatis saya buat menjadi hero. Tidak ada yang perlu dikonfigurasi manual. Begitu saya publish artikel baru dengan tanggal terkini, artikel itu langsung naik ke posisi teratas dan mengisi hero section.

Ini mungkin terdengar sepele, tapi bagi saya ini adalah bukti bahwa arsitektur yang dirancang dengan baik bisa membuat pengalaman menulis menjadi jauh lebih menyenangkan. Saya cukup fokus menulis, sisanya berjalan sendiri.

Sistem Kategori Tanpa Database ​

Satu hal yang sering jadi pertanyaan ketika membangun blog statis adalah: bagaimana cara mengelola kategori?

Di WordPress, kategori disimpan di database. Di blog statis, tidak ada database.

Solusi yang saya pakai cukup sedeehana sebenarnya, kategori dibaca langsung dari frontmatter setiap artikel. Komponen kategori lalu mengumpulkan semua nilai unik dari field category dan menampilkannya secara dinamis.

Kalau saya menulis artikel baru dengan category: "Gadget", kategori Gadget otomatis muncul di navbar, di sidebar, dan di halaman kategori, tanpa saya perlu mendaftarkannya di mana pun.

Halaman kategori pun tidak perlu dibuat manual per kategori. Satu file KategoriPage.vue menangani semua kategori yang ada.

SEO di Static Site ​

Ini bagian yang banyak orang lewatkan ketika membangun blog statis.

VitePress punya fitur transformPageData yang dipanggil untuk setiap halaman saat build. Di sinilah saya menyuntikkan semua meta tag yang dibutuhkan: Open Graph, Twitter Card, canonical URL, artikel published time, dan lain-lain.

Semua bersumber dari satu variabel BASE_URL di konfigurasi. Jadi kalau domain berubah, cukup ubah satu baris dan semua URL di seluruh blog ikut berubah.

Saya juga menambahkan JSON-LD structured data untuk setiap artikel, lengkap dengan breadcrumb. Ini yang membuat Google bisa memahami struktur konten dengan lebih baik.

Shortcodes untuk Kemudahan Menulis ​

Salah satu kelebihan VitePress yang jarang disebut adalah kemampuannya untuk menerima komponen Vue langsung di dalam file Markdown.

Saya memanfaatkan ini untuk membuat shortcodes yang bisa dipakai saat menulis artikel:

  • <toc /> untuk daftar isi otomatis
  • <youtube id="..." /> untuk embed video
  • <gambar src="..." caption="..." /> untuk gambar dengan keterangan
  • <related /> untuk artikel terkait

Komponen-komponen ini didaftarkan secara global lewat enhanceApp, jadi bisa dipakai di artikel mana pun tanpa perlu import.

Hasilnya, pengalaman menulis menjadi cukup nyaman. Saya cukup fokus pada konten, dan komponen-komponen itu mengurus tampilan.

Komentar dengan Giscus ​

Blog statis tidak punya backend, jadi sistem komentar konvensional tidak bisa dipakai.

Solusi yang saya pilih adalah Giscus, sistem komentar berbasis GitHub Discussions. Setiap artikel punya thread diskusi sendiri di GitHub, dan komentar ditampilkan langsung di halaman artikel lewat iframe.

Tidak ada database. Tidak ada server. Tidak ada biaya.

Yang dibutuhkan hanya repo GitHub yang publik dengan fitur Discussions diaktifkan.

Deploy dan Alur Kerja ​

Seluruh kode blog disimpan di repo GitHub private. Vercel dihubungkan ke repo tersebut dan secara otomatis melakukan build dan deploy setiap kali ada push baru.

Untuk mempermudah alur kerja, saya membuat dua skrip:

Pertama, posting.py, skrip Python yang memandu pembuatan artikel baru dengan meminta input frontmatter satu per satu. Hasilnya adalah file Markdown yang sudah siap diisi konten.

Kedua, dep.sh, skrip bash yang melakukan git add, commit, dan push dalam satu perintah. Pesan commit bisa diisi manual atau dibiarkan otomatis menggunakan timestamp.

Alur lengkapnya: jalankan python post.py, isi konten artikel, preview dengan npm run docs:dev, lalu jalankan ./dep.sh. Dalam satu menit, artikel sudah live.

Yang Saya Pelajari ​

Membangun blog dengan VitePress mengajarkan saya beberapa hal yang tidak akan saya dapat kalau langsung pakai WordPress atau platform blog siap pakai.

Pertama, memahami bagaimana static site generator bekerja di balik layar. Bagaimana file Markdown diproses, bagaimana data mengalir dari konfigurasi ke komponen, bagaimana build process menghasilkan file HTML statis.

Kedua, pentingnya arsitektur yang dipikirkan sejak awal. Keputusan seperti menyimpan BASE_URL di satu tempat, atau membuat komponen footer yang digunakan bersama, terasa sepele di awal tapi menghemat banyak waktu ketika ada perubahan.

Ketiga, bahwa dokumentasi bukan satu-satunya hal yang bisa dibangun dengan VitePress. Dengan cukup kreativitas dan kesabaran, alat apa pun bisa diubah menjadi sesuatu yang berbeda dari tujuan asalnya.

Penutup ​

Kalau kamu seorang developer yang ingin punya blog personal dan sudah familiar dengan Vue.js, saya sangat merekomendasikan VitePress sebagai pilihan, kenapa? ya kamu nilai saja sendiri blog yang sedang kamu baca sekarang ini.

Memang butuh waktu lebih di awal untuk menyiapkan custom theme dan berbagai komponen. Tapi begitu semuanya siap, pengalaman menulisnya terasa ringan dan menyenangkan.

Dan ada kepuasan tersendiri ketika membuka blog yang kamu bangun sendiri dari nol, tahu persis bagaimana setiap bagiannya bekerja, dan bisa mengubah apa pun sesuai keinginan.

Komentar

Login dengan GitHub untuk berkomentar