ngodingdulu
Deploy & DevOpsTutorialMenengah

Deploy Aplikasi Buatan AI ke Production

Di laptop semuanya jalan. Sekarang aplikasinya akan dipakai orang sungguhan, dengan data sungguhan. Ini cara merilisnya tanpa membuka pintu belakang.

Oleh Afa Hernandes14 menit baca

Daftar isi

Men-deploy halaman statis itu mudah: unggah folder, dapat link, selesai. Kamu sudah melakukannya di deploy pertama ke Cloudflare Pages. Tapi begitu aplikasimu punya database dan login, deploy bukan lagi soal “bisa dibuka atau tidak”. Sekarang ada data orang lain yang harus dijaga, kunci API yang tidak boleh bocor, dan pengguna yang akan kecewa kalau aplikasinya rusak.

Production adalah versi aplikasi yang dipakai pengguna sungguhan. Lawannya adalah development, versi di laptopmu tempat kamu bebas mencoba dan merusak. Tutorial ini membahas cara memindahkan aplikasi buatan AI dari development ke production dengan aman: memisahkan keduanya, menyimpan konfigurasi di tempat yang benar, memasang penjaga yang membatalkan deploy kalau ada kunci rahasia ikut terbawa, lalu menguji di alamat aslinya.

Contohnya tetap aplikasi pencatat pengeluaran dari jalur ini, versi yang sudah memakai Supabase untuk database dan login.

Sebelum mulai

Kamu butuh:

  • Aplikasi yang sudah jalan di laptop, idealnya dengan database dan login seperti di tutorial database dan login.
  • Proyek yang sudah ada di GitHub. Belum? Ikuti Git dan GitHub untuk kerja tim.
  • Akun Cloudflare dan akun Supabase (keduanya punya paket gratis).
  • Node.js di laptopmu, untuk menjalankan build dan skrip pemeriksaan.

Diuji dengan Node 24, Vite 8, dan @supabase/supabase-js 2. Aplikasi buatan AI yang memakai database biasanya sudah memakai build tool seperti Vite: alat yang mengubah kode proyekmu menjadi folder dist berisi file siap online. Kalau AI-mu memakai framework lain, prinsipnya sama. Yang berbeda hanya beberapa nama, dan akan disebutkan.

Struktur proyek yang kita pakai:

catatanku/
├── index.html
├── src/
│ ├── main.js
│ └── supabase.js ← koneksi ke Supabase
├── scripts/
│ ├── cek-rahasia.mjs ← dibuat di langkah 3
│ └── cek-production.mjs ← dibuat di langkah 6
├── .env.example
├── .env.local ← tidak masuk Git
├── .gitignore
└── package.json

Langkah 1: Pisahkan development dan production

Kesalahan yang paling sering: aplikasi online memakai database yang sama dengan yang kamu pakai untuk mencoba-coba di laptop. Akibatnya, data percobaan bercampur dengan data pengguna, dan satu perintah hapus yang salah saat mencoba fitur baru bisa menghapus data sungguhan.

Buat dua proyek Supabase:

Development Production
Nama proyek catatanku-dev catatanku
Dipakai oleh Laptopmu dan alamat pratinjau Alamat utama yang dipakai pengguna
Isi data Data contoh, boleh dihapus kapan saja Data pengguna sungguhan
Boleh dicoba-coba? Ya Tidak

Struktur tabel dan aturan aksesnya harus sama persis di kedua proyek. Caranya: simpan semua SQL yang kamu jalankan (pembuatan tabel dan aturan Row Level Security) sebagai file di repository, misalnya supabase/aturan-akses.sql. Jalankan di proyek development dulu, uji, lalu jalankan file yang sama di SQL Editor proyek production. Jangan pernah mengubah tabel production langsung dari dashboard tanpa mencatatnya di file.

Minta AI membantu dengan prompt seperti ini:

prompt-pisah-lingkungan.txt
Saya akan memakai dua proyek Supabase: satu untuk development, satu untuk production.
Kumpulkan semua SQL pembuatan tabel dan aturan Row Level Security yang pernah kita buat
ke dalam satu file supabase/aturan-akses.sql, urut dari awal, supaya bisa saya jalankan
di proyek baru dan hasilnya sama persis. Jangan sertakan data contoh.

Langkah 2: Pindahkan konfigurasi ke environment variable

Alamat dan kunci Supabase berbeda antara development dan production, jadi tidak boleh ditulis langsung di kode. Simpan sebagai environment variable, dan biarkan kodenya membaca dari sana:

src/supabase.js
import { createClient } from '@supabase/supabase-js';
const url = import.meta.env.VITE_SUPABASE_URL;
const key = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY;
if (!url || !key) {
throw new Error('VITE_SUPABASE_URL atau VITE_SUPABASE_PUBLISHABLE_KEY belum diisi');
}
export const supabase = createClient(url, key);

Perhatikan awalan VITE_. Vite hanya memasukkan variabel berawalan VITE_ ke kode yang berjalan di browser. Variabel tanpa awalan itu tidak ikut, dan justru itu yang kita mau untuk kunci rahasia. Framework lain punya aturan serupa dengan awalan berbeda: NEXT_PUBLIC_ di Next.js dan PUBLIC_ di Astro.

Artinya, semua yang berawalan VITE_ bisa dibaca siapa saja yang membuka aplikasimu. Karena itu, di sini kita hanya memakai publishable key, kunci publik yang aksesnya dibatasi aturan akses database. Secret key tidak pernah boleh diberi awalan VITE_.

Untuk development, isi nilainya di file .env.local:

.env.local
VITE_SUPABASE_URL=https://kode-proyek-dev.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=sb_publishable_isi_kunci_proyek_dev

Nilai aslinya ada di dashboard Supabase proyek development, di bagian pengaturan API. File ini tidak boleh masuk Git. Pastikan .gitignore berisi:

.gitignore
node_modules/
dist/
.env
.env.*
!.env.example

Baris terakhir membuat satu pengecualian: .env.example boleh masuk Git. File ini berisi nama variabel tanpa nilai, supaya kamu (atau developer yang membantumu nanti) tahu apa saja yang harus diisi:

.env.example
# Salin menjadi .env.local lalu isi nilainya. File ini boleh masuk Git, nilainya jangan.
VITE_SUPABASE_URL=
VITE_SUPABASE_PUBLISHABLE_KEY=

Sebelum lanjut, cek riwayat Git-mu: git log --all --oneline -- .env .env.local. Kalau perintah itu menampilkan commit, berarti file rahasia pernah masuk repository. Ganti (rotate) kunci yang ada di dalamnya, karena menghapus file-nya sekarang tidak menghapusnya dari riwayat.

Langkah 3: Pasang penjaga kunci rahasia

Kamu sudah berhati-hati, tapi AI tidak selalu. Saat memperbaiki bug “data tidak bisa disimpan”, AI kadang mengambil jalan pintas: mengganti publishable key dengan secret key, karena secret key melewati semua aturan akses. Bug-nya hilang, dan seluruh database terbuka untuk umum.

Jangan mengandalkan ingatan untuk menangkap ini. Buat skrip yang memeriksa folder dist (hasil build, persis yang akan online) dan menggagalkan build kalau menemukan sesuatu yang mirip kunci rahasia:

scripts/cek-rahasia.mjs
// Memeriksa hasil build (folder dist) sebelum deploy.
// Kalau ada yang mirip kunci rahasia, skrip berhenti dengan error dan deploy dibatalkan.
import { readdirSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
const FOLDER = 'dist';
const pola = [
{ nama: 'Supabase secret key', regex: /sb_secret_[A-Za-z0-9_-]{16,}/g },
{ nama: 'Private key', regex: /-----BEGIN [A-Z ]*PRIVATE KEY-----/g },
];
// Kunci Supabase versi lama berbentuk JWT. Isi bagian tengahnya menyebut perannya.
function jwtServiceRole(teks) {
const temuan = [];
for (const [jwt] of teks.matchAll(/eyJ[\w-]+\.eyJ[\w-]+\.[\w-]+/g)) {
try {
const isi = JSON.parse(Buffer.from(jwt.split('.')[1], 'base64url').toString());
if (isi.role === 'service_role') temuan.push(jwt);
} catch {
// bukan JWT yang valid, lewati
}
}
return temuan;
}
function semuaFile(folder) {
return readdirSync(folder, { withFileTypes: true }).flatMap((f) =>
f.isDirectory() ? semuaFile(join(folder, f.name)) : [join(folder, f.name)],
);
}
let jumlahMasalah = 0;
for (const file of semuaFile(FOLDER)) {
const teks = readFileSync(file, 'utf8');
for (const { nama, regex } of pola) {
for (const [cocok] of teks.matchAll(regex)) {
console.error(`BAHAYA: ${nama} di ${file}: ${cocok.slice(0, 14)}...`);
jumlahMasalah++;
}
}
for (const jwt of jwtServiceRole(teks)) {
console.error(`BAHAYA: kunci service_role (JWT) di ${file}: ${jwt.slice(0, 14)}...`);
jumlahMasalah++;
}
}
if (jumlahMasalah > 0) {
console.error(`\n${jumlahMasalah} temuan. Deploy dibatalkan. Pindahkan kunci rahasia ke server.`);
process.exit(1);
}
console.log(`Aman: tidak ada kunci rahasia di folder ${FOLDER}.`);

Skrip ini mencari dua bentuk secret key Supabase: format baru yang diawali sb_secret_, dan format lama berupa JWT (teks panjang diawali eyJ) yang isinya menyebut peran service_role. Publishable key dan anon key lama tidak dianggap masalah, karena memang boleh ada di browser. Pola pencariannya sengaja meminta minimal 16 karakter setelah sb_secret_, karena library Supabase sendiri menyimpan teks sb_secret_ (tanpa kunci) untuk mengenali jenis kunci.

Sambungkan skrip ini ke perintah build di package.json, supaya selalu berjalan setelah Vite selesai:

package.json
{
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build && node scripts/cek-rahasia.mjs"
}
}

Tanda && berarti: jalankan perintah kedua hanya kalau yang pertama berhasil, dan anggap seluruh build gagal kalau perintah kedua gagal. Saat dicoba dengan kode yang benar, hasilnya:

$ npm run build
✓ built in 263ms
Aman: tidak ada kunci rahasia di folder dist.

Lalu kami sengaja meniru kesalahan AI: mengganti VITE_SUPABASE_PUBLISHABLE_KEY dengan VITE_SUPABASE_SECRET_KEY di src/supabase.js. Build-nya langsung ditolak:

$ npm run build
✓ built in 245ms
BAHAYA: Supabase secret key di dist\assets\index-BlsZOCSc.js: sb_secret_iniR...
1 temuan. Deploy dibatalkan. Pindahkan kunci rahasia ke server.

Skrip ini adalah jaring pengaman, bukan jaminan. Ia hanya mengenali pola yang ia tahu. Untuk kunci layanan lain (API AI, pembayaran), tambahkan polanya ke daftar pola, dan tetap ikuti checklist keamanan aplikasi buatan AI.

Langkah 4: Deploy ke Cloudflare Pages lewat GitHub

Commit dan push semua perubahan di atas. Lalu, seperti di deploy pertama, buat proyek Pages yang terhubung ke GitHub (Workers & Pages → Create → Pages → hubungkan ke Git). Bedanya ada di pengaturan build:

Pengaturan Isi Penjelasan
Production branch main Branch yang menjadi versi production
Framework preset None, atau preset framework-mu Preset hanya mengisi dua baris di bawah. Isian manual tetap yang menentukan
Build command npm run build Menjalankan Vite dan penjaga kunci rahasia
Build output directory dist Folder hasil build

Sebelum menekan tombol deploy, isi environment variable di pengaturan proyek (di bagian variabel dan secrets). Cloudflare Pages memisahkan nilai untuk Production dan Preview. Manfaatkan itu:

Variabel Production Preview
VITE_SUPABASE_URL URL proyek catatanku URL proyek catatanku-dev
VITE_SUPABASE_PUBLISHABLE_KEY Publishable key catatanku Publishable key catatanku-dev

Dengan begitu, alamat pratinjau dari branch lain (misalnya saat kamu mencoba fitur baru) memakai database development, dan hanya branch main yang menyentuh data pengguna.

Dua hal yang perlu diketahui:

  • Variabel ini dipakai saat build. Kalau kamu mengubah nilainya, perubahan baru berlaku di deployment berikutnya. Jalankan ulang deployment (retry deployment) atau push commit baru.
  • Kunci rahasia tidak perlu diisi di sini sama sekali. Aplikasi kita tidak memakainya, dan memang tidak boleh ada di build yang dikirim ke browser.

Tambahkan juga file .node-version berisi 24 di akar proyek. Cloudflare Pages membaca file ini untuk memilih versi Node saat build, sehingga hasilnya sama dengan di laptopmu.

Langkah 5: Atur alamat login di Supabase

Langkah ini paling sering terlupa, dan gejalanya membingungkan: aplikasi sudah online, pengguna mendaftar, lalu link konfirmasi di email membawa mereka ke localhost, halaman yang tentu tidak bisa dibuka di HP mereka.

Penyebabnya, Supabase perlu tahu alamat aplikasimu untuk mengarahkan pengguna kembali setelah login lewat email, magic link, atau akun Google. Di dashboard proyek production, buka Authentication → URL Configuration:

  • Site URL: alamat utama aplikasimu, misalnya https://catatanku.pages.dev (atau domain sendiri, kalau sudah dipasang). Nilai bawaannya adalah alamat localhost, jadi wajib diganti.
  • Redirect URLs: daftar alamat lain yang boleh dituju setelah login. Isi hanya alamat milikmu. Jangan memakai pola yang terlalu longgar, karena daftar ini mencegah orang lain membelokkan pengguna (lengkap dengan token login-nya) ke situs mereka.

Di proyek development, tambahkan alamat laptopmu (misalnya http://localhost:5173, alamat bawaan Vite) dan pola alamat pratinjau Cloudflare, misalnya https://*.catatanku.pages.dev/**.

Langkah 6: Uji di production, bukan hanya di laptop

Deploy berhasil bukan berarti aplikasinya benar. Uji di alamat aslinya, karena di sinilah konfigurasi yang salah ketahuan. Mulai dengan skrip uji cepat ini:

scripts/cek-production.mjs
// Uji cepat setelah deploy: node scripts/cek-production.mjs https://catatanku.pages.dev
// Opsional, uji database tanpa login: isi SUPABASE_URL dan SUPABASE_PUBLISHABLE_KEY di terminal.
const situs = process.argv[2];
if (!situs?.startsWith('https://')) {
console.error('Pakai: node scripts/cek-production.mjs https://alamat-situsmu');
process.exit(1);
}
let gagal = 0;
const lulus = (pesan) => console.log(`LULUS ${pesan}`);
const bahaya = (pesan) => { console.log(`GAGAL ${pesan}`); gagal++; };
// 1. Halaman utama terbuka
const utama = await fetch(situs);
utama.ok ? lulus(`halaman utama (${utama.status})`) : bahaya(`halaman utama menjawab ${utama.status}`);
// 2. File yang tidak boleh ikut ter-deploy
for (const path of ['/.env', '/.env.local', '/.git/config']) {
const res = await fetch(new URL(path, situs));
const isi = await res.text();
const miripFileRahasia = /^\s*[A-Z][A-Z0-9_]*\s*=/m.test(isi) || isi.includes('[core]');
if (res.status === 404) lulus(`${path} tidak ada (404)`);
else if (!miripFileRahasia) lulus(`${path} dijawab dengan halaman aplikasi (${res.status}), bukan isi file`);
else bahaya(`${path} bisa diunduh! Hapus dari folder yang di-deploy`);
}
// 3. Database tanpa login tidak boleh mengembalikan data
const { SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, TABEL = 'pengeluaran' } = process.env;
if (SUPABASE_URL && SUPABASE_PUBLISHABLE_KEY) {
const res = await fetch(`${SUPABASE_URL}/rest/v1/${TABEL}?select=*&limit=1`, {
headers: { apikey: SUPABASE_PUBLISHABLE_KEY },
});
const data = await res.json().catch(() => null);
if (Array.isArray(data) && data.length === 0) lulus(`tabel ${TABEL} kosong untuk pengunjung tanpa login`);
else if (Array.isArray(data)) bahaya(`tabel ${TABEL} bisa dibaca tanpa login! Periksa Row Level Security`);
else console.log(`CEK tabel ${TABEL} menjawab ${res.status}: ${JSON.stringify(data)}`);
}
console.log(gagal ? `\n${gagal} uji gagal. Jangan bagikan link-nya dulu.` : '\nSemua uji lulus.');
process.exit(gagal ? 1 : 0);

Skrip ini memeriksa tiga hal: halaman utama terbuka, file rahasia seperti .env tidak bisa diunduh, dan (kalau kamu mengisi alamat serta publishable key proyek production) tabel tidak mengembalikan data kepada pengunjung yang belum login.

Kenapa bagian kedua tidak cukup memeriksa kode 404? Karena Cloudflare Pages menganggap proyek tanpa file 404.html sebagai single-page application: alamat apa pun yang tidak ada dijawab dengan halaman utama, status 200. Jadi /.env tetap “terbuka”, tapi isinya halaman aplikasimu, bukan file rahasia. Skrip ini membedakan keduanya dari isinya.

Jalankan di terminal Git Bash (atau terminal macOS/Linux):

Terminal window
SUPABASE_URL=https://kode-proyek.supabase.co \
SUPABASE_PUBLISHABLE_KEY=sb_publishable_isi_kunci_production \
node scripts/cek-production.mjs https://catatanku.pages.dev

Hasil yang diharapkan untuk aplikasi Vite di Cloudflare Pages:

LULUS halaman utama (200)
LULUS /.env dijawab dengan halaman aplikasi (200), bukan isi file
LULUS /.env.local dijawab dengan halaman aplikasi (200), bukan isi file
LULUS /.git/config dijawab dengan halaman aplikasi (200), bukan isi file
LULUS tabel pengeluaran kosong untuk pengunjung tanpa login
Semua uji lulus.

Kalau ada baris GAGAL, perbaiki dulu sebelum membagikan link. Baris CEK muncul kalau Supabase menjawab dengan pesan, bukan data. Misalnya, nama tabelnya salah: baca pesannya, lalu sesuaikan TABEL.

Setelah skrip lulus, ulangi uji dua akun dari tutorial database dan login di alamat production: daftar sebagai Budi, tambah catatan, lalu login sebagai Sari dan pastikan catatan Budi tidak terlihat. Skrip di atas hanya menguji pengunjung tanpa login. Kebocoran antar-pengguna hanya ketahuan lewat uji dua akun. Hapus kedua akun uji setelah selesai, supaya data production tetap bersih.

Langkah 7: Siapkan jalan mundur

Suatu hari, versi baru akan merusak sesuatu di production. Itu normal. Yang penting kamu bisa memulihkannya dalam hitungan menit, bukan jam.

  • Kembalikan versi sebelumnya. Di daftar deployment proyek Pages, setiap deployment lama tersimpan. Pilih deployment terakhir yang sehat, lalu gunakan opsi Rollback untuk menjadikannya production lagi. Setelah itu, perbaiki masalahnya dengan tenang di branch lain.
  • Uji di pratinjau dulu. Kerjakan fitur baru di branch terpisah. Cloudflare membuat alamat pratinjau untuk setiap branch, yang terhubung ke database development (langkah 4). Gabungkan ke main hanya setelah fiturnya lulus uji di sana.
  • Cadangkan data. Kode bisa di-rollback, data tidak. Cek fitur backup di paket Supabase-mu dan pahami cara memulihkannya. Kalau paketmu tidak menyediakan backup otomatis, ekspor datamu secara berkala.
  • Pasang peringatan biaya dan pemakaian. Paket gratis punya batas pemakaian, dan proyek gratis yang lama tidak dipakai bisa dijeda otomatis. Baca ketentuan terbaru di dashboard layanan yang kamu pakai, dan nyalakan notifikasi email-nya.
  • Development dan production memakai proyek database yang berbeda.
  • Struktur tabel dan aturan akses production dibuat dari file SQL yang sama dengan development.
  • .env.local tidak ada di repository maupun riwayat commit-nya.
  • npm run build menjalankan cek-rahasia.mjs, dan hasilnya “Aman”.
  • Environment variable Production dan Preview di Cloudflare Pages menunjuk ke proyek yang benar.
  • Site URL dan Redirect URLs di Supabase production sudah diganti ke alamat aplikasimu.
  • cek-production.mjs lulus semua.
  • Uji dua akun lulus di alamat production.
  • Kamu tahu cara rollback, dan cara memulihkan data.

Error yang sering muncul

Halaman kosong, dan di Console browser muncul VITE_SUPABASE_URL atau VITE_SUPABASE_PUBLISHABLE_KEY belum diisi. Environment variable belum diisi di Cloudflare Pages, namanya salah ketik, atau nilainya diisi setelah build terakhir. Periksa nama variabel di pengaturan proyek (harus persis, termasuk awalan VITE_), lalu jalankan ulang deployment.

Link konfirmasi email membuka localhost. Site URL di Supabase production masih bernilai bawaan. Ganti di Authentication → URL Configuration (langkah 5). Link yang sudah terkirim tetap salah, jadi minta pengguna mendaftar atau meminta link ulang.

Build gagal dengan BAHAYA: Supabase secret key di dist/.... Penjagamu bekerja. Cari di folder src kata SECRET dan service_role, lalu kembalikan kodenya ke publishable key. Kalau sebuah fitur memang butuh secret key, fitur itu harus berjalan di server (misalnya Supabase Edge Functions atau Cloudflare Pages Functions), bukan di browser. Minta AI menjelaskan kenapa ia memakai secret key sebelum kamu menerima perbaikannya. Biasanya masalah aslinya ada di aturan akses.

Di laptop data muncul, di production kosong. Bisa jadi ini benar: production memakai database lain, yang memang masih kosong. Kalau setelah login dan menambah catatan datanya tetap tidak muncul, cek apakah aturan akses (file SQL dari langkah 1) sudah dijalankan di proyek production.

Langkah berikutnya: rilis dan amankan

Aplikasimu sudah online dengan aman. Langkah selanjutnya:

Pertanyaan yang sering diajukan

Apakah publishable key aman walaupun bisa dilihat siapa saja?

Aman, selama aturan akses di setiap tabel benar. Publishable key hanya membuktikan bahwa permintaan datang dari aplikasimu. Yang menentukan data apa yang boleh dibaca adalah Row Level Security. Itu sebabnya skrip di langkah 6 menguji tabel memakai publishable key: siapa pun bisa melakukan hal yang sama.

Haruskah memakai dua proyek Supabase? Repot.

Untuk aplikasi yang dipakai orang lain, ya. Repotnya hanya di awal, dan manfaatnya terasa setiap kali kamu mencoba fitur baru tanpa takut merusak data pengguna. Paket gratis Supabase mengizinkan lebih dari satu proyek (cek batas terbarunya di halaman harga mereka).

Bisakah memakai Vercel atau Netlify, bukan Cloudflare Pages?

Bisa. Langkahnya sama: perintah build, folder output, environment variable terpisah untuk production dan preview, lalu uji di alamat aslinya. Nama menunya saja yang berbeda.

Aplikasiku dibuat di app builder dan deploy-nya cukup satu klik. Apakah artikel ini berlaku?

Prinsipnya tetap berlaku, walaupun langkahnya disederhanakan oleh tool-mu. Cari tahu apakah tool-mu memisahkan database development dan production, di mana environment variable disimpan, dan bagaimana cara kembali ke versi sebelumnya. Uji di langkah 6 tetap bisa kamu jalankan ke alamat aplikasi apa pun.

Kesimpulan

Merilis aplikasi dengan database berarti menjaga tiga hal: data pengguna terpisah dari data percobaan, kunci rahasia tidak pernah sampai ke browser, dan setiap rilis diuji di alamat aslinya. Dengan dua proyek Supabase, environment variable yang benar, penjaga cek-rahasia.mjs, dan uji production, kamu bisa merilis versi baru tanpa deg-degan, dan kembali ke versi lama kalau ada yang salah.

Ini langkah pertama Level 3 jalur Vibe Coding. Begitu aplikasimu dipakai orang, kamu akan menemui bagian yang tidak bisa (dan tidak seharusnya) kamu tangani sendirian. Kenali tandanya di kapan aplikasi vibe coding butuh developer.

Bagikan:WhatsAppTelegramXFacebook
Ilustrasi address bar dengan gembok dan alamat https www.catatanku.id, terhubung ke tabel DNS berisi record A, CNAME, MX, dan TXT yang menunjuk ke server
DeployKonsep

Domain, DNS, dan HTTPS untuk Pemula

Alamat .pages.dev sudah jalan, tapi nama sendiri terasa lain. Begini cara internet menemukan aplikasimu, dan cara memasang domainmu tanpa merusak yang lain.

26 Januari 20266 mnt

Ilustrasi grafik commit Git: jalur utama main dengan cabang fitur-total-bulanan yang bergabung kembali, dan kartu pull request yang sudah disetujui
DeployTutorial

Git dan GitHub untuk Kerja Tim: Commit sampai PR

Git menyimpan setiap versi kodemu, GitHub menyimpannya di internet. Dengan keduanya, kode bisa dikerjakan bersama tanpa saling menimpa, dan setiap perubahan bisa langsung online.

15 Desember 20256 mnt

Enter bukaEsc tutupHalaman pencarian