Make your URLs look suspicious and "freaky" with custom phrases while maintaining secure redirects. Share links that make people wonder what they're clicking on.
freakyUrl lets you transform ordinary URLs into suspicious-looking shortened links with custom phrases. Add phrases like "virus-in-the-file" or "totally-not-a-scam" to any URL—the phrase is cosmetic and purely for fun, while a unique nanoid identifier powers the actual redirect. The backend generates and stores the slug, while the frontend handles redirection from its own domain. The project was inspired by a Hacker News post about suspicious-looking URLs and was built to explore system design, URL mechanics and caching with Redis.
- Backend: Node.js, Express
- Database: MongoDB with Mongoose
- Frontend: React with Vite
- ID Generation: nanoid
- Caching: Redis
- Deployment: Vercel and Render
freakyUrl/
├── client/ # React + Vite Frontend (Vercel)
│ ├── public/
│ │ └── logo.svg
│ ├── src/
│ │ ├── assets/
│ │ ├── components/
│ │ │ ├── LinkForm.jsx
│ │ │ ├── ResultCard.jsx
│ │ │ └── Toast.jsx
│ │ ├── config/
│ │ │ └── constants.js
│ │ ├── pages/
│ │ │ └── RedirectPage.jsx
│ │ ├── utils/
│ │ │ ├── freakyCalculator.js
│ │ │ └── validation.js
│ │ ├── App.jsx
│ │ ├── App.css
│ │ ├── Root.jsx
│ │ ├── index.css
│ │ └── main.jsx
│ ├── .env
│ ├── .gitignore
│ ├── eslint.config.js
│ ├── index.html
│ ├── package.json
│ ├── vite.config.js
│ ├── vercel.json
│ └── README.md
│
├── server/ # Node.js + Express Backend (Render)
│ ├── src/
│ │ ├── app.js
│ │ ├── config/
│ │ │ ├── db.js
│ │ │ └── redis.js
│ │ ├── models/
│ │ │ └── Url.js
│ │ └── utils/
│ │ └── blockedExtensions.js
│ ├── .env
│ ├── .env.example
│ ├── package.json
│ ├── server.js
│ └── README.md
│
├── .git/
├── .gitignore
├── .vscode/
├── README.md
├── package.json
└── fUrl.png
/client - React + Vite frontend application
- Handles URL creation form
- Displays shortened URLs with frontend domain
- Handles dynamic
/:slugroutes for redirects - Deployed on Vercel
/server - Node.js + Express backend API
POST /shorten- Create shortened URLGET /:slug- Resolve slug to original URL- Manages MongoDB database
- Handles Redis caching
- Deployed on Render
/src (server) - Source code
app.js- Express routes and middlewareconfig/- Database and cache connectionsmodels/- Mongoose schemasutils/- Helper functions
-
Creating a Short URL
- User enters a long URL and custom phrase in the frontend
- Frontend validates the URL
- Frontend sends to
POST /shortenon backend - Backend generates a slug combining phrase + unique ID
- Backend stores in MongoDB and returns the slug
- Frontend constructs full URL with its own domain:
https://freaky-url.vercel.app/{slug}
-
Following a Short URL
- User visits:
https://freaky-url.vercel.app/my-phrase-abc123 - React Router on frontend matches
/:slugroute - RedirectPage component loads and shows spinner
- Frontend calls
GET /{slug}on backend - Backend checks Redis cache, then MongoDB
- Backend returns the original long URL
- Frontend redirects user using
window.location.href
- User visits:
✅ Frontend-Based Redirects - Short URLs are on the frontend domain
✅ API-Only Backend - No redirects on backend, just JSON responses
✅ Redis Caching - Fast resolution for frequently accessed URLs
✅ Custom Phrases - Make URLs "freaky" with custom text
✅ Blocked Extensions - Prevents shortened links to dangerous file types
✅ URL Validation - Validates URLs before shortening
- Platform: Render.com
- URL:
https://your-backend-url.onrender.com - Runs Node.js + Express server
- Connected to MongoDB and Redis
- Platform: Vercel
- URL:
https://freaky-url.vercel.app - Runs React + Vite SPA
- Includes
vercel.jsonfor client-side routing
- Node.js (v16+)
- MongoDB
- Redis
# Backend
cd server
npm install
npm run dev
# Frontend (in another terminal)
cd client
npm install
npm run devFrontend will be available at http://localhost:3000
Backend API will be available at http://localhost:5000
Create a .env file in the server directory using .env.example as reference:
# Database
MONGODB_URI=mongodb://localhost:27017/freakyurl
# Cache
REDIS_URL=redis://localhost:6379
# Server
NODE_ENV=development
PORT=5000
# Frontend URL (for CORS)
FRONTEND_URL=http://localhost:3000# Backend API URL
VITE_API_URL=http://localhost:5000For production (Vercel):
VITE_API_URL=https://your-backend-url.onrender.comSee .env.example files in both server/ and client/ directories for all available options.
POST /api/shorten
Content-Type: application/json
{
"longUrl": "https://example.com/very/long/path",
"phrase": "my-awesome-link"
}
Response: 201 Created
{
"slug": "my-awesome-link-abc123"
}
GET /api/resolve/:slug
Response: 200 OK
{
"longUrl": "https://example.com/very/long/path"
}
Response: 404 Not Found
{
"error": "Link not found"
}
GET /health
Response: 200 OK
{
"status": "ok",
"uptime": 12345,
"timestamp": 1696123456789
}
/ → Home page (create short URLs)
/:slug → Redirect page (resolves and redirects to long URL)
- React 19 - UI framework
- React Router v7 - Client-side routing
- Vite - Build tool and dev server
- Lucide React - Icon library
- Node.js - Runtime
- Express - Web framework
- MongoDB + Mongoose - Database
- Redis - Caching layer
- nanoid - ID generation
- Vercel - Frontend hosting
- Render - Backend hosting
- MongoDB Atlas - Managed database
- Redis Cloud - Managed cache
Feel free to submit issues and enhancement requests!
This project is open source and available under the MIT License.
- Inspired by this Hacker News post about suspicious URLs
