πΈ Overview
FusionTik adalah web application modern untuk mendownload konten TikTok tanpa watermark. Dibangun dengan Next.js 15 App Router, TypeScript, dan Tailwind CSS β FusionTik menawarkan pengalaman download yang cepat, bersih, dan responsif di semua perangkat.
Tidak perlu install aplikasi. Tidak perlu login. Cukup paste link TikTok, klik Download, dan simpan konten ke perangkatmu.
Built on Next.js β’ Powered by Supabase β’ Written in TypeScript
ποΈ Architecture Overview
graph TD
A["User Browser - Paste TikTok URL"] -->|Submit Form| B["Next.js Frontend - app/page.tsx"]
B -->|POST /api/tiktok| C["API Route Handler - Validate URL"]
C -->|Try Provider 1| D["Zell API - apizell.web.id"]
C -->|Fallback| E["Sanka API - sankavollerei.com"]
D -->|Success| F["Parse Response - video, audio, images"]
E -->|Success| F
D -->|Fail| E
E -->|All Fail| G["notifyProviderFailure - Alert System"]
G --> H["Telegram Bot - Instant Alert"]
G --> I["Email SMTP - Nodemailer"]
G --> J["Webhook POST - Custom Endpoint"]
F -->|JSON Response| B
B -->|Show VideoPreview| K["Download UI - Progress Bar"]
K -->|downloadWithProgress| L["TikTok CDN - Direct Download"]
B -->|POST /api/global-stats| M["Global Counter - Increment"]
M -->|Atomic RPC| N[("Supabase DB - global_stats")]
M -->|Fallback| O[("JSON File - global-stats.json")]
style A fill:#e3f2fd,stroke:#2196f3,stroke-width:3px,color:#0d47a1
style B fill:#e8f5e9,stroke:#4caf50,stroke-width:3px,color:#1b5e20
style C fill:#fff3e0,stroke:#ff9800,stroke-width:3px,color:#e65100
style D fill:#f3e5f5,stroke:#9c27b0,stroke-width:3px,color:#4a148c
style E fill:#e8eaf6,stroke:#3f51b5,stroke-width:3px,color:#1a237e
style F fill:#e0f2f1,stroke:#00695c,stroke-width:3px,color:#004d40
style G fill:#fce4ec,stroke:#e91e63,stroke-width:3px,color:#880e4f
style H fill:#e8f5e9,stroke:#4caf50,stroke-width:2px,color:#1b5e20
style I fill:#fff3e0,stroke:#ff9800,stroke-width:2px,color:#e65100
style J fill:#e3f2fd,stroke:#2196f3,stroke-width:2px,color:#0d47a1
style K fill:#fff8e1,stroke:#ff8f00,stroke-width:3px,color:#ff6f00
style L fill:#efebe9,stroke:#795548,stroke-width:3px,color:#3e2723
style M fill:#f5f5f5,stroke:#616161,stroke-width:2px,color:#424242
style N fill:#d7ccc8,stroke:#5d4037,stroke-width:2px,color:#3e2723
style O fill:#d7ccc8,stroke:#5d4037,stroke-width:2px,color:#3e2723
π§± Software Architecture
FusionTik menggunakan Layered Architecture dengan pemisahan yang jelas antara Presentation, Application, dan Infrastructure layer.
graph TB
subgraph PRESENTATION["Presentation Layer - Client Side"]
P1["app/page.tsx - Main Page"]
P2["video-preview.tsx - Download UI"]
P3["result-card.tsx - History Card"]
P4["stats-card.tsx - Stats Display"]
P5["navbar.tsx - Navigation"]
end
subgraph STATE["State Management Layer - React Hooks"]
S1["use-download-history - localStorage"]
S2["use-download-stats - Personal Stats"]
S3["use-global-stats - Global Counter"]
end
subgraph APPLICATION["Application Layer - Next.js API Routes"]
A1["POST /api/tiktok - Core Downloader"]
A2["GET/POST /api/global-stats - Counter API"]
end
subgraph INFRASTRUCTURE["Infrastructure Layer"]
I1["lib/supabase.ts - DB Client"]
I2["lib/download-utils.ts - Download Engine"]
I3["lib/utils.ts - Utilities"]
end
subgraph EXTERNAL["External Services"]
E1["Zell API - Provider 1"]
E2["Sanka API - Provider 2"]
E3["Supabase DB - PostgreSQL"]
E4["TikTok CDN - Media Files"]
E5["Telegram API - Alerts"]
end
PRESENTATION --> STATE
PRESENTATION --> APPLICATION
APPLICATION --> INFRASTRUCTURE
INFRASTRUCTURE --> EXTERNAL
style PRESENTATION fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
style STATE fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style APPLICATION fill:#fff3e0,stroke:#ff9800,stroke-width:2px
style INFRASTRUCTURE fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px
style EXTERNAL fill:#efebe9,stroke:#795548,stroke-width:2px
graph LR
subgraph PAGE["app/page.tsx"]
FORM["Form Input"]
RESULT["Result Display"]
HIST["History Section"]
STATS["Stats Section"]
end
subgraph HOOKS["React Hooks"]
UDH["useDownloadHistory"]
UDS["useDownloadStats"]
UGS["useGlobalStats"]
end
subgraph COMPONENTS["Components"]
VP["VideoPreview"]
RC["ResultCard"]
SC["StatsCard"]
end
subgraph API["API Routes"]
TK["POST /api/tiktok"]
GS["GET/POST /api/global-stats"]
end
subgraph LIB["Libraries"]
DU["download-utils"]
SB["supabase client"]
end
FORM -->|submit| TK
TK -->|response| RESULT
RESULT --> VP
VP --> DU
HIST --> RC
STATS --> SC
PAGE --> UDH
PAGE --> UDS
PAGE --> UGS
UDH -->|localStorage| UDS
UGS -->|fetch| GS
GS --> SB
PAGE -->|increment| GS
style PAGE fill:#e3f2fd,stroke:#2196f3
style HOOKS fill:#e8f5e9,stroke:#4caf50
style COMPONENTS fill:#fff3e0,stroke:#ff9800
style API fill:#f3e5f5,stroke:#9c27b0
style LIB fill:#efebe9,stroke:#795548
flowchart LR
subgraph INPUT["Input"]
URL["TikTok URL"]
end
subgraph VALIDATION["Validation"]
REGEX["Regex Check - tiktok.com"]
end
subgraph FETCH["Data Fetching"]
Z["Zell Provider"]
S["Sanka Provider"]
PARSE["Parse and Normalize - title, creator, videos, audio, images"]
end
subgraph RESPONSE["Response"]
VIDEO["Video Response - MP4 + Audio"]
IMAGE["Image Response - Photos + Audio"]
end
subgraph STORAGE["Storage"]
LS["localStorage - history and stats"]
DB[("Supabase - global_stats")]
end
subgraph DOWNLOAD["Download"]
BLOB["Blob with Progress Bar"]
OPEN["window.open fallback"]
end
URL --> REGEX
REGEX -->|valid| Z
REGEX -->|invalid| ERR["Error 400"]
Z -->|success| PARSE
Z -->|fail| S
S -->|success| PARSE
S -->|fail| ALERT["Alert System - Telegram/Email"]
PARSE --> VIDEO
PARSE --> IMAGE
VIDEO --> LS
IMAGE --> LS
VIDEO --> DB
IMAGE --> DB
VIDEO --> BLOB
IMAGE --> BLOB
BLOB -->|CORS ok| BLOB
BLOB -->|CORS fail| OPEN
style INPUT fill:#e3f2fd,stroke:#2196f3,color:#0d47a1
style VALIDATION fill:#fff3e0,stroke:#ff9800,color:#e65100
style FETCH fill:#f3e5f5,stroke:#9c27b0,color:#4a148c
style RESPONSE fill:#e8f5e9,stroke:#4caf50,color:#1b5e20
style STORAGE fill:#efebe9,stroke:#795548,color:#3e2723
style DOWNLOAD fill:#e0f2f1,stroke:#00695c,color:#004d40
| Pattern | Implementasi | File |
|---|---|---|
| Provider Pattern | Fallback chain Zell β Sanka | app/api/tiktok/route.ts |
| Repository Pattern | Supabase β File JSON fallback | app/api/global-stats/route.ts |
| Custom Hook Pattern | State management terpisah per concern | hooks/ |
| Compound Component | VideoPreview + download buttons | components/video-preview.tsx |
| Strategy Pattern | Download: Blob progress vs window.open | lib/download-utils.ts |
| Observer Pattern | useRef untuk avoid stale closure | hooks/use-download-history.ts |
β¨ Key Features
π Message Flow
sequenceDiagram
participant U as User
participant FE as Frontend
participant API as API Server
participant Z as Zell Provider
participant S as Sanka Provider
participant DB as Supabase
participant TG as Telegram
U->>FE: Paste TikTok URL
U->>FE: Click Download
FE->>API: POST /api/tiktok
API->>API: Validate URL regex
API->>Z: GET url=tiktok_url
alt Zell Success
Z-->>API: video, music, images
API-->>FE: type, video, music
else Zell Failed
Z-->>API: Error 5xx
API->>S: GET apikey and url
alt Sanka Success
S-->>API: play, music, images
API-->>FE: type, video, music
else All Providers Failed
S-->>API: Error
API->>TG: Alert notification
API-->>FE: error message
FE-->>U: Show error message
end
end
FE->>FE: Show VideoPreview component
U->>FE: Click UNDUH MP4
FE->>FE: downloadWithProgress
FE-->>U: Progress 0 to 100 percent
FE-->>U: File saved
FE->>API: POST /api/global-stats
API->>DB: RPC increment_global_downloads
DB-->>API: new_total
API-->>FE: totalDownloads N
FE-->>U: Update counter display
ποΈ Project Structure
FusionTik/
β
βββ π app/ # Next.js App Router
β βββ π layout.tsx # Root layout + SEO metadata + PWA
β βββ π page.tsx # β Halaman utama downloader
β βββ π globals.css # Global styles + custom animations
β βββ π robots.ts # SEO robots.txt
β βββ π sitemap.ts # SEO sitemap.xml
β β
β βββ π api/
β β βββ π tiktok/
β β β βββ π route.ts # β Core API: fetch + fallback + alerts
β β βββ π global-stats/
β β βββ π route.ts # Global download counter
β β
β βββ π faq/ # Halaman FAQ
β βββ π feedback/ # Halaman Feedback
β βββ π help-center/ # Halaman Help Center
β βββ π privacy/ # Privacy Policy
β βββ π terms/ # Terms of Service
β
βββ π components/
β βββ π navbar.tsx # Navigation bar + dark mode toggle
β βββ π video-preview.tsx # β Preview + download buttons
β βββ π result-card.tsx # History item card
β βββ π result-buttons.tsx # Download action buttons
β βββ π stats-card.tsx # Personal statistics card
β βββ π video-preview-modal.tsx # Modal preview
β βββ π mode-toggle.tsx # Dark/light mode toggle
β βββ π theme-provider.tsx # Theme context provider
β βββ π ui/ # shadcn/ui (50+ komponen)
β
βββ π hooks/
β βββ π use-download-history.ts # β History (localStorage, max 100)
β βββ π use-download-stats.ts # Personal download statistics
β βββ π use-global-stats.ts # Global counter state
β βββ π use-toast.ts # Toast notification hook
β
βββ π lib/
β βββ π download-utils.ts # β Download dengan progress tracking
β βββ π supabase.ts # Supabase client (nullable)
β βββ π utils.ts # Tailwind merge utilities
β
βββ π data/
β βββ π global-stats.json # Fallback counter (development)
β
βββ π public/ # Static assets + PWA manifest
βββ π next.config.mjs # Next.js config + CSP headers
βββ π tailwind.config.ts # Tailwind configuration
βββ π tsconfig.json # TypeScript configuration
βββ π env.example # Template environment variables
π οΈ Tech Stack
|
Framework |
Language |
Styling |
Database |
| Layer | Teknologi | Versi | Fungsi |
|---|---|---|---|
| Framework | Next.js | 15 | App Router, SSR, API Routes |
| Language | TypeScript | 5 | Type safety end-to-end |
| Styling | Tailwind CSS | 3 | Utility-first CSS |
| UI Components | shadcn/ui | latest | 50+ komponen siap pakai |
| Animation | Framer Motion | latest | Animasi halus & interaktif |
| Database | Supabase | 2.x | Global download counter |
| Nodemailer | 6.x | Alert notifikasi via SMTP | |
| Deployment | Vercel | β | Hosting + Edge Functions |
β‘ Quick Start
- Node.js 18+
- npm / pnpm / yarn
- Akun Supabase (opsional, untuk global stats)
git clone https://github.com/jundy779/FusionTik.git
cd FusionTik
npm installcp env.example .env.localEdit .env.local:
# Supabase (untuk global stats β opsional)
NEXT_PUBLIC_SUPABASE_URL=https://<your-project-ref>.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=<your-supabase-anon-key>
# Notifikasi error (semua opsional)
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=youremail@gmail.com
SMTP_PASS=your-app-password
ALERT_EMAIL_TO=owner@domain.comnpm run devBuka http://localhost:3000 di browser.
npm run build
npm run start
# Custom port
PORT=8080 npm run startβοΈ Environment Variables
| Variable | Wajib | Deskripsi |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL |
β | URL project Supabase untuk global stats |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
β | Anon key Supabase |
ZELL_TIKTOK_API_URL |
β | Override URL provider Zell |
SANKA_TIKTOK_API_URL |
β | Override URL provider Sanka |
SANKA_TIKTOK_API_KEY |
β | API key untuk provider Sanka |
ALERT_WEBHOOK_URL |
β | Webhook URL untuk notifikasi error |
TELEGRAM_BOT_TOKEN |
β | Token bot Telegram untuk alert |
TELEGRAM_CHAT_ID |
β | Chat ID penerima notifikasi Telegram |
SMTP_HOST |
β | SMTP host untuk email alert |
SMTP_PORT |
β | SMTP port (587 TLS / 465 SSL) |
SMTP_USER |
β | Email pengirim |
SMTP_PASS |
β | Password / App Password email |
ALERT_EMAIL_TO |
β | Email penerima alert |
Catatan: Jika Supabase tidak dikonfigurasi, global stats menggunakan
data/global-stats.jsonsebagai fallback (cocok untuk development).
π Deployment
- Fork repo ini ke akun GitHub kamu
- Buka vercel.com/import dan pilih repo FusionTik
- Set environment variables di dashboard Vercel
- Klik Deploy β Vercel akan build dan host otomatis
git clone https://github.com/jundy779/FusionTik.git
cd FusionTik
npm install
cp env.example .env.local
# Edit .env.local sesuai kebutuhan
npm run build
npm run startGunakan PM2 untuk production:
npm install -g pm2
pm2 start "npm run start" --name fusiontik
pm2 save && pm2 startupPull dan jalankan image dari GitHub Container Registry:
# Pull image terbaru
docker pull ghcr.io/jundy779/fusiontik:latest
# Jalankan container
docker run -d \
--name fusiontik \
-p 3000:3000 \
-e NEXT_PUBLIC_SUPABASE_URL=your_supabase_url \
-e NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_key \
-e TELEGRAM_BOT_TOKEN=your_telegram_token \
-e TELEGRAM_CHAT_ID=your_chat_id \
ghcr.io/jundy779/fusiontik:latestAtau build sendiri dari source:
git clone https://github.com/jundy779/FusionTik.git
cd FusionTik
docker build -t fusiontik .
docker run -d --name fusiontik -p 3000:3000 fusiontikDengan Docker Compose:
# docker-compose.yml
services:
fusiontik:
image: ghcr.io/jundy779/fusiontik:latest
ports:
- "3000:3000"
environment:
- NEXT_PUBLIC_SUPABASE_URL=${NEXT_PUBLIC_SUPABASE_URL}
- NEXT_PUBLIC_SUPABASE_ANON_KEY=${NEXT_PUBLIC_SUPABASE_ANON_KEY}
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}
restart: unless-stoppeddocker compose up -dποΈ Setup Supabase
Untuk mengaktifkan global download counter yang persisten:
1. Buat Tabel
CREATE TABLE global_stats (
id BIGINT PRIMARY KEY DEFAULT 1,
total_downloads BIGINT DEFAULT 0,
updated_at TIMESTAMPTZ DEFAULT NOW()
);
INSERT INTO global_stats (id, total_downloads) VALUES (1, 0);2. Buat RPC Function (Atomic Increment)
CREATE OR REPLACE FUNCTION increment_global_downloads()
RETURNS BIGINT LANGUAGE plpgsql AS $$
DECLARE new_total BIGINT;
BEGIN
UPDATE global_stats
SET total_downloads = total_downloads + 1, updated_at = NOW()
WHERE id = 1
RETURNING total_downloads INTO new_total;
RETURN new_total;
END;
$$;3. Row Level Security
ALTER TABLE global_stats ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow public read" ON global_stats FOR SELECT USING (true);
CREATE POLICY "Allow public update" ON global_stats FOR UPDATE USING (true);π Sistem Notifikasi Error
Ketika semua provider API gagal, FusionTik otomatis mengirim alert:
flowchart LR
A["Provider Zell - FAILED"] --> B["Provider Sanka - FAILED"]
B --> C{"notifyProviderFailure"}
C --> D["Telegram Bot - Instant Alert"]
C --> E["Email SMTP - Nodemailer"]
C --> F["Webhook POST - Custom Endpoint"]
C --> G["User Error UI - Friendly Message"]
style A fill:#fce4ec,stroke:#e91e63,color:#880e4f
style B fill:#fce4ec,stroke:#e91e63,color:#880e4f
style C fill:#fff3e0,stroke:#ff9800,color:#e65100
style D fill:#e8f5e9,stroke:#4caf50,color:#1b5e20
style E fill:#e3f2fd,stroke:#2196f3,color:#0d47a1
style F fill:#f3e5f5,stroke:#9c27b0,color:#4a148c
style G fill:#efebe9,stroke:#795548,color:#3e2723
Contoh pesan Telegram yang dikirim:
β οΈ FusionTik downloader error
URL: https://www.tiktok.com/@user/video/123
Error: Zell API returned 503: Service Unavailable
Time: 2025-01-15T10:30:00.000Z
π Statistik & Analytics
Disimpan di Supabase dengan atomic increment via RPC. Fallback ke file JSON untuk development. Ditampilkan di hero section halaman utama.
Disimpan di localStorage browser:
| Metrik | Deskripsi |
|---|---|
| π₯ Total Downloads | Jumlah total konten yang didownload |
| π¬ Videos Downloaded | Jumlah video yang didownload |
| πΌοΈ Images Downloaded | Jumlah foto/carousel yang didownload |
| π΅ Audio Extracted | Jumlah audio yang diekstrak |
| π Today Downloads | Download hari ini |
| π This Week | Download 7 hari terakhir |
| ποΈ This Month | Download 30 hari terakhir |
| π Most Active Day | Hari dengan download terbanyak |
| π Average/Day | Rata-rata download per hari |
π Keamanan & Privasi
- β Tidak ada file tersimpan di server β semua konten langsung dari CDN TikTok
- β History hanya di device pengguna β tidak ada tracking server-side
- β CSP Headers β Content Security Policy ketat di semua response
- β Security Headers β HSTS, X-Frame-Options, X-Content-Type-Options, dll
- β XSS Protection β Caption TikTok di-escape sebelum render HTML
- β No Third-party Tracking β Tidak ada Google Analytics atau tracker pihak ketiga
π Changelog
- β
Refactor: hapus semua
anytype β proper TypeScript interfaces - β Security: XSS fix pada caption rendering (HTML entity escaping)
- β Fix: atomic Supabase counter increment via RPC
- β Fix: sequential image download (cegah browser popup blocking)
- β
Improvement:
response.okcheck pada semua fetch calls - β
Improvement: history limit 100 item +
useReffix untuk infinite loop - β
Improvement: konsistensi
downloadWithProgressdi semua download handler - β
Security: hapus exposed Supabase key dari
env.example
- β Dual provider dengan fallback (Zell β Sanka)
- β Notifikasi error multi-channel (Webhook + Telegram + Email)
- β Global download counter dengan Supabase
- β Download progress tracking dengan ReadableStream
- β Personal download statistics
- β Dark/Light mode
π€ Contributing
Contributions are welcome! π
- Fork repo ini
- Buat branch baru:
git checkout -b feature/nama-fitur - Commit perubahan:
git commit -m "feat: tambah fitur X" - Push ke branch:
git push origin feature/nama-fitur - Buka Pull Request ke branch
main
Konvensi Commit:
| Prefix | Deskripsi |
|---|---|
feat: |
Fitur baru |
fix: |
Bug fix |
refactor: |
Refactoring kode |
docs: |
Update dokumentasi |
style: |
Perubahan styling |
chore: |
Maintenance / dependency update |
βοΈ Legal & Disclaimer
Warning
Gunakan dengan bijak:
- Layanan ini untuk penggunaan pribadi saja
- Hormati hak cipta kreator konten
- Jangan gunakan konten yang didownload untuk tujuan komersial tanpa izin
- Ikuti Terms of Service TikTok
- FusionTik tidak berafiliasi dengan TikTok atau ByteDance Ltd.
π Acknowledgements
Core Technologies
Community & Contributors
- π Semua contributors yang membuat ini mungkin
- π Komunitas open-source yang luar biasa
- β Semua yang sudah memberikan bintang di repo ini









