A simple, powerful, and self-hostable URL shortener built on Cloudflare Workers, D1 Database, and Vanilla JS. Designed for dedicated domains (e.g., link.yourdomain.com).
- 🚀 One-Click Deploy - Live in 60 seconds
- 🎨 Beautiful Dashboard - Modern, premium UI
- ⚙️ Dashboard Config - Zero code editing required
- 🔒 Secure - Admin authentication, input validation, strict headers
- 📊 Analytics - Click tracking and statistics
- 🌐 Custom Domains - Use your own domain
- 💰 Free-Tier Friendly - Runs comfortably on Cloudflare's free tier for most use cases
- 🎯 Auto-Setup - Database initializes automatically
No coding or terminal required! Follow these steps:
- Click the "Deploy to Cloudflare Workers" button above ☝️.
- Connect your GitHub account.
- Cloudflare will create the project, the database, and deploy everything automatically!
For security, we don't handle passwords during the basic setup.
- Log in to the Cloudflare Dashboard.
- Go to Workers & Pages > Click your new project (
elandio-trim). - Go to Settings > Variables.
- Click Add Variable:
- Variable name:
ADMIN_TOKEN - Value: Your Secure Password
- Click Encrypt (Recommended) > Save.
- Variable name:
- Wait a few seconds, then open your App URL. Login works! 🎉
# Clone the repository
git clone https://github.com/elandio-com/elandio-trim.git
cd elandio-trim
# Install dependencies
npm install
# Create local database
npx wrangler d1 create elandio-trim-db --local
# Initialize database
npx wrangler d1 execute elandio-trim-db --local --file=./database/schema.sql
# Start development server (default port 8787)
npm run devVisit http://localhost:8787/dashboard.html
See DEPLOYMENT.md for detailed instructions.
- Visit
/dashboard.html - Login with your admin password
- Enter a URL to shorten
- (Optional) Choose a custom slug
- Click "Create Link"
Your short link is ready! Share it anywhere.
Overview Tab:
- View all your links
- See click statistics
- Search and filter links
- Edit or delete links
Navigate to https://link.yourdomain.com/dashboard.html (or your workers.dev URL) and log in with your admin token.
- Enter the target URL (e.g.,
https://google.com). - Enter a custom slug (e.g.,
google) or let it auto-generate. - Click Shorten.
- Your link is live at
https://link.yourdomain.com/google.
- Fallback URL: Configure where users should be redirected if they visit a non-existent link (404).
You can set these in Cloudflare Settings → Variables (or .dev.vars locally):
ADMIN_TOKEN(required): Static admin token used by the dashboard and API.ENVIRONMENT(optional):developmentorproduction(defaults to production).FALLBACK_URL(optional): Redirect destination for unknown slugs (404).
- Worker handles API + redirects
- D1 stores links and settings
- Assets serve static dashboard files
This project is intended for single‑admin, self‑hosted use. It uses a static admin token (no user accounts, no sessions, no cookies). This is deliberate for simplicity and transparency in a self‑hosted model.
/api/*endpoints: 5 requests/second per IP/api/setup: 1 request/minute per IP
If you need higher limits, adjust src/worker/middleware/rateLimit.ts and/or use Cloudflare WAF rate limiting.
POST /api/admin/create: Create new linkGET /api/admin/list: List all linksDELETE /api/admin/:slug: Delete a linkPUT /api/admin/settings: Update settings
- Ensure your domain uses Cloudflare nameservers
- Go to Cloudflare Dashboard → Workers & Pages
- Click your worker → Triggers → Add Custom Domain
- Enter subdomain (e.g.,
short.yourdomain.com) - Wait 1-2 minutes for DNS
Done! Your links now use your custom domain.
-
Use a Strong Password
- Minimum 32 characters
- Mix of letters, numbers, symbols
- Generate with:
openssl rand -base64 32
-
Monitor Your Links
- Check Cloudflare Dashboard logs
- Delete suspicious links
- Rotate password periodically
✅ Authentication - Admin token required
✅ Input Validation - URLs and slugs sanitized
✅ SQL Injection Protection - Parameterized queries
✅ XSS Prevention - Strict slug format
✅ Reserved Paths - System routes protected
✅ HTTPS Only - Cloudflare enforced
✅ Rate Limiting - Built-in protection
✅ Open Redirect Prevention - URL validation (blocks private IPs/localhost + unsafe characters)
- Verify
ADMIN_TOKENis set in Cloudflare Dashboard - Click "Deploy" after adding the variable
- Clear browser cache
- Visit
/setup.htmldirectly - Check browser console for errors
- Verify database ID in
wrangler.toml
- Verify database initialized (visit
/api/health) - Check Cloudflare Dashboard logs
- Ensure slug exists in dashboard
- Wait 1-2 minutes for DNS propagation
- Verify domain uses Cloudflare nameservers
- Check domain shows "Active" in Cloudflare
dashboard.htmlloads without console errors- Login works with
ADMIN_TOKEN - Create / edit / delete links works
- Redirects work for existing slugs
- 404 fallback URL behaves as expected
Cloudflare’s free tier is typically enough for personal and small business use. For current limits and pricing, refer to Cloudflare’s official pricing pages.
- Frontend: HTML, JavaScript, Tailwind CSS
- Backend: Cloudflare Workers (TypeScript)
- Database: Cloudflare D1 (SQLite)
- Security: Admin tokens, Input Validation
- Deployment: Wrangler CLI
Contributions welcome! See CONTRIBUTING.md for guidelines.
Found a bug? Open an issue.
Have an idea? Start a discussion.
Want to help? Submit a PR.
MIT License - see LICENSE for details.
Built with ❤️ by Elandio
Powered by:
If you find this useful, please:
- ⭐ Star this repository
- 🐦 Share on social media
- 🐛 Report bugs
- 💡 Suggest features
Made with ❤️ by Elandio