Live draft autosave — ketik apa aja, langsung tersimpan di cloud secara real-time. Tanpa tombol publish, tanpa akun, tanpa ribet. Dibangun dengan vanilla HTML/CSS/JS di atas Firebase Realtime Database.
Inspirasi visual: Ghostbin oleh kilgarth — pastebin legendaris yang memulai semuanya. Kami meminjam estetika Inter UI + Envy Code R yang gelap dan menjadikannya autosave-native.
| Halaman | URL | Yang terjadi |
|---|---|---|
| Editor | / |
Buka sesi baru. Kamu ketik. Dia simpan. Udah. |
| Viewer | /d/{id} |
Real-time viewer. Lihat ketikan muncul saat penulis mengetik. |
| Raw | /raw/{id} |
Output text/plain murni. Tanpa HTML, tanpa script. |
| Admin | /admin |
Login Firebase Auth. Jelajahi semua draft, hapus massal, lihat detail. |
Fitur sekilas:
- Autosave dengan debounce 1 detik (bukan setiap ketukan)
- Sinkronisasi real-time via Firebase
onValue— viewer update langsung - Syntax highlighting (highlight.js) — 30+ bahasa, fallback auto-detect
- Penyimpanan Base64 — konten di-encode saat disimpan, di-decode saat ditampilkan
- Tombol QR code — scan dengan HP untuk buka viewer
- Batas 700 KB raw text (~1 MB encoded, diterapkan di frontend + rules)
- Admin hapus massal dengan checkbox
- Tema gelap Ghostbin — Inter UI, Envy Code R, Fontello icons
| Platform | Tombol |
|---|---|
| Vercel | |
| Heroku | |
| Railway | |
| Cloudflare Workers | npx wrangler deploy (lihat panduan di bawah) |
| Render | Arahkan ke repo ini → Build: npm install, Start: npm start |
- Node.js 18+ (hanya untuk menjalankan dev server — tidak ada build step backend)
- Akun Firebase (free tier sudah cukup)
- Tempat deploy: Vercel, Heroku, Railway, atau Cloudflare
git clone https://github.com/arilaprilio/ghostdraft.git
cd ghostdraft
npm install # opsional — hanya diperlukan untuk wrangler deploy- Buka Firebase Console
- Add project → ikuti wizard (Analytics opsional)
- Klik ikon Web (
</>) → daftarkan app → beri nama - Salin objek
firebaseConfig— akan dipakai di langkah 5
- Firebase Console → Build → Realtime Database
- Create Database → pilih lokasi → mulai dalam test mode
- Salin URL database (format:
https://NAMA-PROJECT-default-rtdb.firebaseio.com)
- Firebase Console → Build → Authentication → Get started
- Tab Sign-in method → Email/Password → Enable
- Tab Users → Add user → masukkan email admin + password (ini login admin kamu)
Salin file contoh dan isi dengan nilai dari langkah 2:
cp .env.example .envBuka .env dan ganti setiap nilai PASTE_YOUR_*:
FIREBASE_API_KEY=AIzaSy...
FIREBASE_AUTH_DOMAIN=my-project.firebaseapp.com
FIREBASE_DATABASE_URL=https://my-project-default-rtdb.firebaseio.com
FIREBASE_PROJECT_ID=my-project
FIREBASE_STORAGE_BUCKET=my-project.firebasestorage.app
FIREBASE_MESSAGING_SENDER_ID=123456789
FIREBASE_APP_ID=1:123456789:web:abc...
FIREBASE_MEASUREMENT_ID=G-ABC123
.envsudah di-gitignore — jangan pernah commit kunci asli..env.exampletetap di repo sebagai template.Untuk platform deploy, atur variabel yang sama di dashboard platform:
- Vercel: Project Settings → Environment Variables
- Heroku: Settings → Config Vars
- Railway: Tab Variables
- Render: Environment → Environment Variables
- Cloudflare Workers: lihat panduan lengkap di bawah (bagian Cloudflare Workers Setup)
Buka database.rules.json, ganti YOUR_ADMIN_EMAIL@example.com dengan email yang kamu pakai di langkah 4.
Lalu buka Firebase Console → Realtime Database → tab Rules → tempel seluruh isinya → Publish.
npm start
# atau: node server.jsBuka http://localhost:3000 — mulai mengetik!
| Halaman | URL |
|---|---|
| Editor | http://localhost:3000/ |
| Viewer | http://localhost:3000/d/{sessionId} |
| Admin | http://localhost:3000/admin |
| Raw | http://localhost:3000/raw/{sessionId} |
GhostDraft mendukung dua metode deploy ke Cloudflare Workers: deploy via CLI (wrangler) dan Connect Git (Cloudflare Pages + auto-deploy). Pilih sesuai kebutuhan.
Cocok untuk: development, private repo, atau kalau kamu deploy manual dari terminal.
1. Isi konfigurasi Firebase di wrangler.jsonc → vars (ganti setiap "" kosong):
⚠️ Peringatan: Jangan deploy dengan nilai kosong""— akan errorfirebaseConfig is not defineddi browser.
2. Deploy:
npm install --save-dev wrangler
npx wrangler deployUntuk production, gunakan
npx wrangler secret put FIREBASE_API_KEY(satu per satu) agar nilai tidak tersimpan diwrangler.jsonc. Secret yang di-putvia CLI terenkripsi dan tidak muncul di file.
Cocok untuk: repo public, auto-deploy tiap push, tidak ingin API key tersimpan di file konfigurasi.
Cloudflare Pages terhubung ke repo GitHub/GitLab kamu. Setiap git push, Cloudflare otomatis build dan deploy. Karena wrangler.jsonc ikut tercommit di repo, kamu tidak bisa menyimpan API key di wrangler.jsonc kalau repo-mu public.
1. Hubungkan repo ke Cloudflare Pages
- Buka Cloudflare Dashboard → Workers & Pages → Create → Pages
- Pilih Connect to Git → pilih GitHub/GitLab → pilih repo ghostdraft
- Konfigurasi build:
- Build command: (kosongkan — tidak perlu)
- Build output directory:
public
- Klik Save and Deploy
2. Biarkan wrangler.jsonc dengan nilai kosong (seperti kondisi awal repo):
"vars": {
"FIREBASE_API_KEY": "",
"FIREBASE_AUTH_DOMAIN": "",
"FIREBASE_DATABASE_URL": "",
"FIREBASE_PROJECT_ID": "",
"FIREBASE_STORAGE_BUCKET": "",
"FIREBASE_MESSAGING_SENDER_ID": "",
"FIREBASE_APP_ID": "",
"FIREBASE_MEASUREMENT_ID": ""
}Nilai kosong aman dicommit ke repo public — tidak ada kunci yang bocor.
3. Isi variabel di Dashboard Cloudflare
Buka Dashboard → Workers & Pages → pilih project → Settings → Environment Variables.
Tambah 8 variabel berikut di bagian Production:
| Variable | Value |
|---|---|
FIREBASE_API_KEY |
AIzaSy... |
FIREBASE_AUTH_DOMAIN |
my-project.firebaseapp.com |
FIREBASE_DATABASE_URL |
https://my-project-default-rtdb.firebaseio.com |
FIREBASE_PROJECT_ID |
my-project |
FIREBASE_STORAGE_BUCKET |
my-project.firebasestorage.app |
FIREBASE_MESSAGING_SENDER_ID |
123456789 |
FIREBASE_APP_ID |
1:123456789:web:abc... |
FIREBASE_MEASUREMENT_ID |
G-ABC123 |
📌 Penting: Environment variables di Dashboard SELALU mengambil alih (override) nilai
varsdiwrangler.jsonc. Jadi meskipunwrangler.jsonckosong, worker tetap membaca nilai dari Dashboard. Ini adalah cara yang benar dan aman untuk repo public.
4. Redeploy
Setelah menambah variabel di Dashboard, buka tab Deployments → klik Retry deployment pada deployment terakhir (atau cukup push commit baru — auto-deploy akan jalan).
5. Verifikasi
Buka URL Pages kamu (format: https://ghostdraft-xxx.pages.dev). Kalau editor muncul tanpa error di console, berarti variabel sudah terbaca.
| Metode | Commit API key di repo? | Cocok untuk Connect Git? | Aman untuk repo public? |
|---|---|---|---|
wrangler.jsonc vars |
Ya | ✅ (auto-deploy) | ❌ (API key bocor) |
| Dashboard Env Vars | Tidak | ✅ | ✅ |
wrangler secret put |
Tidak | ❌ (butuh CLI deploy) | ✅ |
Rekomendasi final: Untuk Connect Git + repo public, kosongkan
wrangler.jsoncvars dan isi semua variabel di Dashboard Environment Variables. Worker membaca dari bindingenv.*yang sama — tidak perlu ubah kode.
| Masalah | Penanganan |
|---|---|
| Session ID bisa ditebak | 16-char random dari crypto.getRandomValues() (~10²⁵ kombinasi) |
| Listing tidak sah | Hanya email admin yang bisa membaca node /drafts |
| Field injection | $other: { .validate: false } — whitelist saja |
| Content bombing | Batas 700 KB raw / 1 MB encoded (frontend + rules) |
| Path traversal | Diblokir di server.js (.. → 403) |
| Password admin | Tidak pernah di kode — Firebase Auth menangani login |
| Firebase keys | Tidak pernah dicommit — dibaca dari env vars saat runtime |
| Raw endpoint | Server-side Firebase REST proxy — tidak ada API key yang terekspos |
ghostdraft/
├── .env.example # Template environment variables
├── server.js # Node.js HTTP server (main entry)
├── worker.js # Cloudflare Workers entry (alternatif)
├── package.json # npm scripts
├── vercel.json # Konfigurasi deploy Vercel
├── wrangler.jsonc # Konfigurasi Cloudflare Workers
├── .assetsignore # Mengecualikan file sensitif dari static serving
├── database.rules.json # Aturan keamanan Firebase RTDB
├── README.md # Kamu sedang membaca ini
└── public/ # Semua aset statis
├── index.html # Halaman editor
├── viewer.html # Halaman viewer
├── admin.html # Dashboard admin
├── raw.html # Halaman raw content
└── assets/
├── ghostdraft.js # Utilitas encode/decode Base64
├── style.css # Semua stylesheet
├── editor.js # Logika editor + autosave
├── viewer.js # Logika viewer + highlighting
└── admin.js # Logika admin + hapus massal
Identitas visual GhostDraft terinspirasi dari Ghostbin — pastebin gelap nan bersih yang mendefinisikan genre. Kami memakai font yang sama:
- Inter UI — teks body (Rasmus Andersson)
- Envy Code R — kode monospace (Damien Guard)
- Fontello — set ikon (subset khusus)
Syntax highlighting via highlight.js dengan tema Monokai Sublime.
MIT — lakukan apa pun yang kamu mau. PR dipersilakan.

{ "vars": { "FIREBASE_API_KEY": "AIzaSy...", "FIREBASE_AUTH_DOMAIN": "my-project.firebaseapp.com", "FIREBASE_DATABASE_URL": "https://my-project-default-rtdb.firebaseio.com", "FIREBASE_PROJECT_ID": "my-project", "FIREBASE_STORAGE_BUCKET": "my-project.firebasestorage.app", "FIREBASE_MESSAGING_SENDER_ID": "123456789", "FIREBASE_APP_ID": "1:123456789:web:abc...", "FIREBASE_MEASUREMENT_ID": "G-ABC123" } }