Cara Deploy Vite ke GitHub Pages
Panduan deploy project Vite ke GitHub Pages: mengatur base path, workflow GitHub Actions, memperbaiki 404 pada SPA, dan menyesuaikan router agar tautan tidak rusak.
Deploy Vite ke GitHub Pages punya satu jebakan yang menjatuhkan hampir semua orang di percobaan pertama: base path. Situsmu terbuka, tapi tampil polos tanpa gaya sama sekali, dan Console penuh 404.
Panduan ini menyelesaikan itu lebih dulu, lalu masuk ke workflow-nya. Langkahnya sama untuk React, Vue, Svelte, atau Vite polos — yang membedakan hanya bagian router di akhir.
Kenapa base path itu masalah
GitHub Pages menaruh situsmu di https://namauser.github.io/nama-repo/. Perhatikan bagian /nama-repo/.
Vite secara bawaan membangun situs dengan asumsi ia berada di root domain, jadi tag scriptnya jadi seperti ini:
<script src="/assets/index-a1b2c3.js"></script>
Browser mencarinya di namauser.github.io/assets/... — padahal berkasnya ada di namauser.github.io/nama-repo/assets/.... Hasilnya 404 untuk semua aset.
Langkah 1: Set base di vite.config
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
base: '/nama-repo/',
});
Ganti nama-repo dengan nama repositorimu, persis. Garis miring di depan dan belakang keduanya wajib.
- Repo biasa →
'/nama-repo/' - Repo
namauser.github.io→'/' - Pakai custom domain →
'/'
Kalau kamu ingin situsnya tetap jalan di lokal maupun di GitHub Pages tanpa mengganti nilai bolak-balik, buat base bergantung pada mode:
export default defineConfig(({ command }) => ({
plugins: [react()],
base: command === 'build' ? '/nama-repo/' : '/',
}));
Langkah 2: Aktifkan Pages lewat Actions
Buka repositori → Settings → Pages → di bagian Source, pilih GitHub Actions.
Kalau ini masih diset Deploy from a branch, workflow di bawah tidak akan berpengaruh apa pun.
Langkah 3: Buat workflow
Bikin .github/workflows/deploy.yml:
name: Deploy ke GitHub Pages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- name: Siapkan fallback SPA
run: cp dist/index.html dist/404.html
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: ./dist
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- id: deployment
uses: actions/deploy-pages@v4
Langkah cp dist/index.html dist/404.html itu penting — penjelasannya di bawah.
Langkah 4: Perbaiki 404 saat refresh
Kalau situsmu SPA dengan routing di sisi klien, kamu akan menemui ini: navigasi antar halaman lancar, tapi begitu di-refresh di /tentang, muncul 404.
Sebabnya, browser meminta /tentang ke server, dan GitHub mencari berkas bernama tentang yang memang tidak ada.
Netlify dan Vercel punya aturan rewrite untuk ini. GitHub Pages tidak. Akalinya dengan menyalin index.html jadi 404.html — GitHub menyajikan 404.html untuk apa pun yang tidak ditemukan, jadi aplikasimu tetap termuat dan routernya mengambil alih.
Itulah gunanya langkah cp di workflow. Kalau kamu lebih suka mengaturnya di package.json:
"scripts": {
"build": "vite build && cp dist/index.html dist/404.html"
}
Langkah 5: Sesuaikan router
Base path juga harus diberitahukan ke router, kalau tidak semua tautan internal akan meleset.
React Router
<BrowserRouter basename={import.meta.env.BASE_URL}>
<Routes>...</Routes>
</BrowserRouter>
Vue Router
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes,
});
import.meta.env.BASE_URL otomatis berisi nilai base dari vite.config.js, jadi kamu tidak perlu menuliskannya dua kali.
Langkah 6: Push
git add .
git commit -m "tambah workflow deploy"
git push origin main
Buka tab Actions. Setelah hijau, situsmu live di https://namauser.github.io/nama-repo/.
Masalah yang sering muncul
Halaman putih, Console penuh 404
Base path salah. Buka DevTools → Network, lihat URL berkas yang gagal dimuat. Kalau tidak ada /nama-repo/ di dalamnya, berarti base belum diset atau nilainya keliru.
Gambar di folder public tidak muncul
Menulis src="/logo.png" akan menghasilkan path absolut yang mengabaikan base. Pakai salah satu ini:
// impor — cara yang paling aman
import logo from './assets/logo.png';
<img src={logo} />
// atau rangkai dengan BASE_URL
<img src={import.meta.env.BASE_URL + 'logo.png'} />
Error "Resource not accessible by integration"
Blok permissions di workflow hilang atau tidak lengkap. Ketiganya wajib ada.
npm ci gagal
package-lock.json tidak ter-commit atau tidak sinkron dengan package.json. Jalankan npm install, lalu commit lockfile-nya.
Situs tidak berubah padahal workflow hijau
Cek Source di Settings → Pages sudah GitHub Actions. Kalau sudah benar, coba muat ulang dengan menekan Ctrl+Shift+R — GitHub Pages punya cache yang cukup agresif.
Setelah pasang custom domain, situs rusak lagi
Custom domain menempatkan situs di root, jadi base path lamanya jadi salah. Ubah base jadi '/', dan taruh berkas CNAME berisi nama domainmu di folder public/ supaya ikut tersalin tiap build.
Memastikan deploy-nya benar
Workflow hijau belum tentu situsnya benar. Tiga pemeriksaan cepat yang menangkap hampir semua masalah:
- Buka DevTools lalu tab Network, dan muat ulang. Semua berkas harus berstatus 200. Kalau ada yang merah, perhatikan URL-nya — di situ ketahuan base path-mu salah atau tidak.
- Lihat sumber halaman. Klik kanan lalu View Page Source. Tag
<script>dan<link>harus memuat nama repositorimu di path-nya. - Coba refresh di halaman dalam. Buka rute selain beranda, lalu tekan F5. Kalau muncul 404, langkah fallback
404.htmlbelum jalan.
Dari terminal, satu perintah ini memeriksa apakah halamannya benar-benar tersaji:
curl -sSI https://namauser.github.io/nama-repo/ | head -3
Kalau project-mu pakai TypeScript
Script build bawaan template Vite untuk TypeScript menjalankan pengecekan tipe lebih dulu:
"build": "tsc -b && vite build"
Artinya satu error tipe akan menggagalkan seluruh deploy, meskipun aplikasinya jalan normal di npm run dev — mode dev tidak melakukan pengecekan penuh.
Ini sebetulnya perilaku yang bagus, dan jangan buru-buru dimatikan. Jalankan npx tsc -b di lokal sebelum push supaya errornya ketahuan lebih awal, bukan setelah workflow merah.
Batas GitHub Pages yang perlu diketahui
| Hal | Batas |
|---|---|
| Ukuran situs | 1 GB |
| Bandwidth | 100 GB per bulan (batas lunak) |
| Build | 10 per jam |
| Repositori privat | Perlu akun berbayar |
| Kode sisi server | Tidak ada sama sekali |
Batas yang paling sering kena bukan ukuran atau bandwidth, tapi tidak adanya sisi server. Begitu situsmu butuh menyembunyikan API key, menerima form, atau memanggil database — GitHub Pages tidak bisa, dan tidak ada cara mengakalinya. Di titik itu pindahkan ke Netlify atau Cloudflare, yang punya function bawaan.
Ringkasan
| Hal | Nilainya |
|---|---|
base di vite.config | '/nama-repo/' |
| Source di Settings → Pages | GitHub Actions |
| Folder keluaran | ./dist |
| Fallback SPA | cp dist/index.html dist/404.html |
| Router | basename={import.meta.env.BASE_URL} |
| Custom domain | base: '/' + public/CNAME |
Untuk situs Hugo, workflow-nya serupa tapi urusan base path-nya berbeda — lihat cara deploy Hugo ke GitHub Pages. Kalau errormu tidak ada di sini, cek 15 error deploy paling umum.
Menimbang platform lain? Lihat GitHub Pages vs Netlify, atau panduan memilih hosting statis.