ToolViral is a Next.js app for free social media tools. The first implemented
tools are available at /tiktok-video-downloader and
/instagram-reels-downloader.
pnpm install
pnpm devOpen http://localhost:3000.
This app is configured for Cloudflare Workers with OpenNext.
Build the Worker locally:
pnpm build:workerPreview the production Worker locally:
pnpm preview:workerDeploy to Cloudflare Workers:
pnpm deploy:workerThe root wrangler.jsonc deploys .open-next/worker.js and serves static
assets from .open-next/assets.
Set non-secret production variables in wrangler.jsonc or the Cloudflare
dashboard. Keep API keys as Worker secrets:
pnpm wrangler secret put COBALT_API_KEY
pnpm wrangler secret put TIKTOK_DOWNLOADER_API_KEY
pnpm wrangler secret put INSTAGRAM_DOWNLOADER_API_KEYFor Instagram downloads, set COBALT_API_URL to the deployed yt-dlp Worker URL.
For a custom domain, update NEXT_PUBLIC_SITE_URL before deploying so canonical
URLs, sitemap entries, Open Graph URLs, and llms.txt point at the real site.
The website Worker timeout should be longer than the yt-dlp provider timeout;
INSTAGRAM_PROVIDER_TIMEOUT_MS defaults to 75000.
The UI and API boundary are implemented in this repo. By default, the app uses
the internal provider route at /api/providers/tiktok, which resolves public
TikTok links through TikWM.
You can override the built-in provider with your own trusted endpoint:
TIKTOK_DOWNLOADER_PROVIDER_URL="https://your-provider.example/resolve"
TIKTOK_DOWNLOADER_API_KEY="optional-provider-token"The app sends:
{ "url": "https://www.tiktok.com/@creator/video/123" }The provider should return either a downloads array or direct video URL
fields:
{
"title": "Video title",
"author": "creator",
"thumbnailUrl": "https://example.com/thumb.jpg",
"downloads": [
{
"label": "Download without watermark",
"url": "https://example.com/video.mp4",
"format": "mp4",
"quality": "HD"
}
]
}Only public videos should be supported, and users should only download content they own or have permission to save.
You can also override the internal TikWM endpoint if needed:
TIKWM_PROVIDER_URL="https://www.tikwm.com/api/"Downloads are proxied through /api/tiktok/download so the browser receives a
real attachment response instead of opening MP4 files in a new tab. The proxy
allows TikWM/TikTok CDN hosts by default. For another provider, configure the
allowed download hosts:
TIKTOK_DOWNLOAD_ALLOWED_HOSTS="cdn.example.com,files.example.com"The Instagram downloader uses /api/instagram/resolve and the internal provider
route at /api/providers/instagram. For production, point COBALT_API_URL at
the included cobalt-api-worker, which is now a Cloudflare Worker + Container
deployment running yt-dlp:
COBALT_API_URL="https://toolviral-ytdlp-api.your-subdomain.workers.dev/"
COBALT_API_KEY="your-worker-api-key"
INSTAGRAM_PROVIDER_TIMEOUT_MS="75000"The Worker exposes a Cobalt-compatible POST / API, while its colocated
container runs Python and yt-dlp. See cobalt-api-worker/README.md for deploy
steps.
You can override the built-in Instagram provider with your own trusted endpoint:
INSTAGRAM_DOWNLOADER_PROVIDER_URL="https://your-provider.example/instagram/resolve"
INSTAGRAM_DOWNLOADER_API_KEY="optional-provider-token"The custom provider should accept:
{ "url": "https://www.instagram.com/reel/ABC123/" }And return either a downloads array or a direct video URL:
{
"title": "Instagram video",
"author": "creator",
"thumbnailUrl": "https://example.com/thumb.jpg",
"downloads": [
{
"label": "Download video",
"url": "https://example.com/video.mp4",
"format": "mp4"
}
]
}Instagram downloads are proxied through /api/instagram/download. For another
provider, configure the allowed download hosts:
INSTAGRAM_DOWNLOAD_ALLOWED_HOSTS="cdn.example.com,files.example.com"pnpm dev
pnpm build
pnpm lint