A modern URL shortener built with Node.js, Express, and MongoDB. Features a JWT-based authentication system, bcrypt password hashing, a glassmorphism dashboard, and real-time link analytics.
- URL Shortening: Convert long URLs into short, shareable links with custom short IDs
- JWT Authentication: Stateless, scalable user sessions with secure cookie storage
- Bcrypt Security: Passwords are hashed with bcrypt for maximum security 🔒
- Auto-Login: Users are immediately authenticated upon successful registration
- Link Management: View all your shortened links in one dashboard with quick actions
- Delete Links: Remove unwanted links with one click
- Click Analytics: Track total clicks, unique visitors, and visit history
- Time-Based Insights: Hourly breakdown charts and 30-day performance trends
- Geographic Tracking: Interactive heatmaps showing clicks by location (city, state, country)
- Device Analytics: Desktop, mobile, tablet, and bot detection
- Referral Sources: Track traffic from WhatsApp, Telegram, LinkedIn, Google, and more
- OS Detection: Detects and tracks the operating system of visitors for enhanced analytics
- Bcrypt Password Hashing: All user passwords are securely hashed using bcrypt.
- JWT & Cookie Security: Secure, stateless authentication with JWT. Sessions persist for 7 days using
httpOnlycookies with environment-awaresecureandsameSitesettings. - Rate Limiting: Request throttling on global traffic and auth endpoints to reduce abuse and brute-force attempts.
- Secure Headers: HTTP security headers enabled with Helmet.
- Environment Variables: Sensitive data is managed via environment variables.
- Premium UI: Floating pill-shaped navigation and glassmorphism cards with smooth transitions
- Responsive Design: Fully optimized for mobile, tablet, and desktop views
- Social Sharing: Direct share buttons for popular platforms with tracking parameters
- Real-time Updates: Live analytics and instant link generation
- Password Visibility Toggle: Eye icon on login and signup forms to show/hide password
- Persistent Sessions: Stay logged in for 7 days — works reliably on mobile browsers
- Node.js - Runtime environment
- Express.js - Web framework
- MongoDB - Database
- Mongoose - ODM for MongoDB
- JWT - JSON Web Tokens for authentication
- bcrypt - Password hashing
- Cookie-Parser - Cookie handling
- Helmet - Security headers
- Express Rate Limit - Request throttling
- EJS - Embedded JavaScript Templates
- CSS3 - Modern Flexbox/Grid with Glassmorphism effects
- Chart.js - Analytics charts
- Leaflet.js - Interactive maps
- Phosphor Icons - Icon library
- NanoID - Unique ID generation
- Dotenv - Environment variable management
- IP Geolocation - Location tracking (ip-api.com)
- User Agent Parser - Device detection
url-shortener/
├── config/
│ ├── constants.js # App constants and shared messages
│ └── index.js # Centralized environment/config loader
├── controllers/
│ ├── url.js # URL business logic
│ └── user.js # User business logic
├── middleware/
│ ├── auth.js # Authentication & authorization middleware
│ ├── errorHandler.js # Global error handling
│ └── security.js # Helmet + rate limit middleware
├── models/
│ ├── url.js # MongoDB schema for URLs
│ └── user.js # MongoDB schema for users
├── routes/
│ ├── staticRouter.js # Static pages routes
│ ├── url.js # URL shortening routes
│ └── user.js # Authentication routes
├── service/
│ ├── analytics.js # Visit tracking service
│ └── auth.js # JWT service functions
├── utils/
│ ├── analytics.js # User-agent and source helpers
│ ├── errors.js # Error utility helpers
│ ├── formatters.js # Data formatting helpers
│ ├── geolocation.js # IP + geo helpers
│ └── locationMap.js # State/country mapping data
├── public/
│ ├── css/
│ │ ├── about.css
│ │ ├── analytics.css
│ │ ├── auth.css
│ │ ├── base.css
│ │ ├── common.css
│ │ ├── components.css
│ │ ├── dashboard.css
│ │ ├── home.css
│ │ ├── login.css
│ │ ├── navbar.css
│ │ ├── signup.css
│ │ └── variables.css
│ └── js/
│ ├── about.js
│ ├── analytics-charts.js
│ ├── analytics-geo.js
│ ├── analytics-main.js
│ ├── analytics-map.js
│ ├── analytics-modals.js
│ └── home-modals.js
├── views/
│ ├── partials/
│ │ ├── analytics/
│ │ │ ├── activity-table.ejs
│ │ │ ├── chart-card.ejs
│ │ │ ├── geo-list.ejs
│ │ │ ├── header.ejs
│ │ │ ├── map-section.ejs
│ │ │ ├── modals.ejs
│ │ │ └── stat-card.ejs
│ │ └── navbar.ejs
│ ├── about.ejs
│ ├── analytics.ejs
│ ├── dashboard.ejs
│ ├── home.ejs
│ ├── login.ejs
│ └── signup.ejs
├── screenshots/
│ ├── analytics1.png
│ ├── analytics2.png
│ ├── dashboard.png
│ ├── Home.png
│ └── Login.png
├── connection.js # MongoDB connection
├── index.js # Server entry point
├── package.json # Dependencies
├── README.md
├── .env.sample
├── .env # Environment variables (local)
└── LICENCE
- Node.js (v14 or higher)
- MongoDB (local installation or MongoDB Atlas)
- npm or yarn
- Clone the repository and install dependencies:
git clone https://github.com/HiteshShonak/short-url.git
cd short-url
npm install- Create a
.envfile in the root directory:
NODE_ENV=development
PORT=8000
MONGO_URL=mongodb://localhost:27017/short-url
JWT_SECRET=your_super_secret_key_here
APP_BASE_URL=http://localhost:8000
TRUST_PROXY=false
COOKIE_SECURE=false
COOKIE_SAME_SITE=lax
RATE_LIMIT_WINDOW_MINUTES=15
RATE_LIMIT_MAX_REQUESTS=1200
AUTH_RATE_LIMIT_MAX=10
VISIT_HISTORY_LIMIT=5000- Start the application:
# For development
npm run dev
# For production
npm start- Access the application at
http://localhost:8000
- Sign up or log in to your account
- Navigate to the home page
- Paste your long URL into the input field
- Click "Shorten It"
- Copy and share your generated short link
- From the home page, click "📊 Stats" next to any link
- View comprehensive analytics including:
- Total clicks and unique visitors
- Hourly activity chart
- 30-day performance trend
- Geographic heatmap
- Device breakdown
- Referral sources
- Click the share icon next to any link
- Choose your platform (WhatsApp, Telegram, LinkedIn, Instagram)
- The link will automatically include tracking parameters
POST /user/- Register a new user & auto-loginPOST /user/login- Authenticate userGET /user/logout- Clear session cookies
POST /url/- Create a shortened URL (requires authentication)GET /url/:shortId- Redirect to original destinationGET /url/analytics/:shortId- Get detailed click statisticsPOST /url/delete/:shortId- Remove a link (requires authentication)
GET /- Home pageGET /dashboard- User dashboard (shows guest state if not logged in)GET /about- About/features pageGET /login- Login pageGET /signup- Signup page
| Variable | Description | Required |
|---|---|---|
NODE_ENV |
Runtime mode (development or production) |
No |
PORT |
Server port (default: 8000) | No |
MONGO_URL |
MongoDB connection string | Yes |
JWT_SECRET |
Secret key for JWT encryption | Yes |
APP_BASE_URL |
Public app base URL used for generated links | No |
TRUST_PROXY |
Enable Express proxy trust when behind reverse proxy | No |
COOKIE_SECURE |
Force secure auth cookie (true/false) |
No |
COOKIE_SAME_SITE |
Auth cookie sameSite policy (default: lax) |
No |
RATE_LIMIT_WINDOW_MINUTES |
Global/auth limiter window in minutes | No |
RATE_LIMIT_MAX_REQUESTS |
Max requests per IP per limiter window | No |
AUTH_RATE_LIMIT_MAX |
Max failed auth attempts per window | No |
VISIT_HISTORY_LIMIT |
Max analytics entries stored per short link | No |
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENCE file for details.
Hitesh
- GitHub: @HiteshShonak
- Chart.js - Beautiful, responsive charts
- Leaflet.js - Interactive maps
- Phosphor Icons - Flexible icon library
- ip-api.com - IP geolocation API (free, no key required)
Note: This is a personal project built for learning purposes. For production use, additional security measures and optimizations are recommended.




