A URL shortening service built with Node.js, Express, and MongoDB. It generates short links that redirect to the original long URLs, tracks visit history per link, and supports authenticated, role-based link management (Normal / Admin).
- 🔐 Authentication — JWT-based signup, login, and logout
- ✂️ Short Link Generation — Unique short IDs via
nanoid - 🔁 Redirection — Fast redirects from short link to original URL
- 📊 Visit Tracking — Timestamp, IP, and user recorded per visit
- 👤 Per-User Management — Users manage only the links they created
- 🛡️ Role-Based Access — Separate
NORMALandADMINviews - 🎨 Server-Rendered UI — EJS templates with custom CSS
| Layer | Technology |
|---|---|
| Runtime | Node.js |
| Framework | Express.js |
| Database | MongoDB (Mongoose) |
| Auth | JWT + cookie-parser |
| Templating | EJS |
| Short ID | nanoid |
| Config | dotenv |
Public/ # Static assets (CSS, JS, images)
controller/ # Route handler / business logic
middleware/ # Auth & request middleware
model/ # Mongoose schemas (Url, User)
routes/ # Express route definitions
service/ # Supporting business logic
views/ # EJS templates
index.js # App entry point — wires middleware, DB, routes
connection.js # MongoDB connection helper
.env.example # Sample environment variables
index.js initializes the database connection and middleware, then mounts routes; routes/ map paths to controller/ handlers, which use the model/ schemas and render views/.
- Node.js (v16+)
- A MongoDB instance (local or Atlas)
git clone https://github.com/Aman-20/nodejs-url-shortener.git
cd nodejs-url-shortener
npm install
cp .env.example .env # then fill in the values below
npm startThe server runs on PORT (default 3000) — visit http://localhost:3000 or your configured DOMAIN_NAME.
| Variable | Description |
|---|---|
MONGO_URL |
MongoDB connection string |
JWT_SECRET |
Secret used to sign/verify auth tokens |
DOMAIN_NAME |
Base URL used to build/display short links |
PORT |
Server port (optional, default 3000) |
The MongoDB connection uses database name
Auth1(set inconnection.js) unless overridden.
Authentication middleware runs globally; /url requires NORMAL or ADMIN, and /admin requires ADMIN.
| Method | Endpoint | Access | Description |
|---|---|---|---|
| POST | /user/signup |
Public | Register a new user |
| POST | /user/login |
Public | Authenticate a user |
| GET | /user/logout |
Authenticated | Log out the current user |
| GET | /url |
Normal/Admin | List short URLs created by the logged-in user |
| POST | /url |
Normal/Admin | Create a short URL from a submitted long URL |
| POST | /url/delete/:id |
Normal/Admin | Delete a short URL (only if owned by the user) |
| GET | /u/:id |
Public | Redirect to the long URL; logs a visit record |
| GET | /admin |
Admin | View all shortened URLs across users |
Example — create a short URL
curl -X POST -d "url=https://example.com" http://localhost:3000/urlOn success, the app redirects to /url/?id=<short> to display the newly created link.
Example — visit a short URL
curl -L http://localhost:3000/u/<short>| Field | Type | Description |
|---|---|---|
short |
String | Unique short code |
long |
String | Original long URL |
history |
[{ timestamp, ip, user }] |
Visit log per short link |
createdBy |
ObjectId (ref: User) |
Owner of the link |
| timestamps | — | createdAt / updatedAt auto-managed |
- Short IDs (
nanoid(6)) aren't retried on collision — a duplicate ID could throw a uniqueness error under rare conditions. - Submitted URLs aren't validated/sanitized (e.g., no scheme check or SSRF protection).
- Most endpoints render EJS views/redirects rather than returning JSON.
- Retry logic for short ID collisions
- Input validation & URL sanitization
- Optional JSON API mode for external consumers
- Click analytics dashboard (referrer, device, location)
- Link expiration & custom aliases
ISC
Aman GitHub: @Aman-20