Langsung ke konten
Kembali ke project

Web Development

Bilingual CMS & Portfolio Platform

CMS buatan sendiri di balik website ini: dashboard admin dengan konten bilingual, publikasi terjadwal, dan media di Cloudflare R2, yang menjalankan website publik cepat dengan hero WebGL, animasi scroll, dan share image otomatis.

Bilingual CMS & Portfolio Platform

Ringkasan

Website ini jalan di atas content management system yang aku design dan develop sendiri, dari database sampai interface. Setiap project, artikel, dan bagian profil cukup aku tulis sekali per bahasa di dashboard admin, terus website publik nampilinnya lengkap dengan animasi, 3D, dan SEO.

Tantangan

Portfolio builder biasanya kelihatan generik atau ribet buat konten dua bahasa. Aku pengin kontrol penuh atas desain, versi Inggris dan Indonesia buat semua konten tanpa kerja dua kali, dan website yang tetap cepat serta accessible walaupun visualnya berat. Websitenya juga harus gampang di-update, karena portofolio yang ribet diedit bakal cepat basi.

Yang aku bikin

Dashboard admin

  • Konten buat project, artikel, profil, riwayat kerja, layanan, testimoni, dan lainnya, dengan versi Inggris dan Indonesia berdampingan.

  • Rich text editor dengan heading, list, tabel, gambar, embed YouTube, dan diagram Mermaid dengan live preview, yang dipakai buat diagram arsitektur di halaman ini.

  • Status draft, terjadwal, dan published, dengan job harian yang nerbitin konten terjadwal.

  • Upload media ke Cloudflare R2, lengkap dengan crop gambar.

  • Field SEO buat judul, deskripsi, dan social card, di balik login yang terlindungi.

Konten bilingual dengan fallback

  • Setiap entri punya versi Inggris dan Indonesia. Kalau versi Indonesia-nya belum ada, versi Inggris ditampilkan dengan label yang jelas dan nggak diindeks mesin pencari, jadi nggak ada konten duplikat.

  • URL per bahasa dan link hreflang ngasih tahu mesin pencari versi mana yang harus ditampilkan.

Website publik

  • Tanda tangan 3D WebGL di hero, animasi berbasis scroll pakai GSAP, dan smooth scrolling.

  • Quality tier yang nyesuaiin efek dengan perangkat: versi lebih ringan buat HP, artwork statis tanpa WebGL, dan halaman yang tenang buat pengguna reduced motion.

  • Social share image otomatis buat halaman dan artikel.

Kecepatan, SEO, dan AI search

  • Halaman dilayani dari CDN Vercel dengan revalidasi di background, jadi konten ke-update dalam satu menit tanpa bikin pengunjung nunggu.

  • Gambar AVIF dan WebP yang responsif, dan script berat kayak scene 3D dan diagram yang baru dimuat pas dibutuhkan.

  • Structured data, sitemap, RSS feed, dan ringkasan llms.txt buat AI search tools.

Gambaran arsitektur

Gambaran umumnya: satu aplikasi Astro melayani website publik dan dashboard admin di Vercel. Konten disimpan di PostgreSQL dan media di Cloudflare R2.

flowchart LR
  accTitle: Arsitektur CMS dan portofolio
  accDescr: Pengunjung dilayani dari CDN Vercel. Satu app Astro merender website publik dan dashboard admin, dengan konten di PostgreSQL dan media di Cloudflare R2. Job harian memublikasikan konten terjadwal.
  visitor([Pengunjung]) --> cdn["Vercel CDN<br/>halaman ter-cache"]
  editor([Editor]) --> adminApp
  cron["Job publikasi harian"] --> db
  subgraph astro["App Astro di Vercel"]
    site["Website publik<br/>halaman EN dan ID, share image, feed"]
    adminApp["Dashboard admin<br/>wajib login"]
  end
  cdn --> site
  site & adminApp --> db[("PostgreSQL<br/>konten")]
  adminApp --> r2[("Cloudflare R2<br/>media")]
  visitor -. gambar .-> r2

Model konten

Semua konten mengikuti model sederhana yang sama, dan itu yang bikin dua bahasa tetap gampang dikelola:

classDiagram
  accTitle: Model konten
  accDescr: Satu entri punya satu terjemahan per bahasa. Terjemahan memakai media, dan entri dikelompokkan dengan kategori dan tag.
  class Entry {
    +type
  }
  class Translation {
    +language
    +status
    +title
    +slug
    +body
  }
  class Media {
    +file
    +altText
  }
  class Taxonomy {
    +kind
    +name
  }
  Entry "1" --> "1..2" Translation : punya
  Entry "*" --> "*" Taxonomy : dikelompokkan
  Translation --> Media : memakai

Siklus publikasi

stateDiagram-v2
  accTitle: Siklus publikasi
  accDescr: Setiap entri dimulai sebagai draft. Entri bisa langsung dipublikasikan atau dijadwalkan, dan job harian memublikasikan entri yang terjadwal.
  [*] --> Draft
  Draft --> Scheduled: Atur tanggal terbit
  Draft --> Published: Publikasikan sekarang
  Scheduled --> Published: Dipublikasikan job harian
  Scheduled --> Draft: Batalkan jadwal
  Published --> Draft: Batalkan publikasi

Cara halaman sampai ke pengunjung

sequenceDiagram
  accTitle: Cara halaman sampai ke pengunjung
  accDescr: CDN menjawab dari cache. Kalau salinannya sudah lebih dari satu menit, CDN tetap menjawab seketika dan merender halaman baru di background.
  actor Visitor as Pengunjung
  participant CDN as Vercel CDN
  participant App as Astro app
  participant DB as PostgreSQL
  Visitor->>CDN: Membuka halaman
  alt Salinan cache masih baru
    CDN-->>Visitor: Halaman dari cache
  else Salinan lebih dari satu menit
    CDN-->>Visitor: Halaman dari cache, seketika
    CDN->>App: Merender salinan baru di background
    App->>DB: Membaca konten published
    DB-->>App: Konten
    App-->>CDN: Halaman baru untuk pengunjung berikutnya
  end

Tech stack

Astro, TypeScript, PostgreSQL dengan Drizzle ORM, Better Auth, Plate, Tailwind CSS, Cloudflare R2, dan Vercel, ditambah GSAP, Lenis, Three.js, dan Mermaid di sisi publik.

Hasil

Platform ini menjalankan raflimaulana.dev dalam bahasa Inggris dan Indonesia, dan aku bisa nerbitin karya baru tanpa nyentuh kode. Di Lighthouse, halamannya dapat skor 100 buat accessibility, best practices, dan SEO.

Next project

Bionesia

Front-End Developer · 2026