๐ URL Shortener Module
๐ Overviewโ
The URL Shortener module provides branded short link creation with click tracking and analytics. It enables agencies to create memorable, trackable short URLs for marketing campaigns, social media, and client communications.
File Path: internal/api/v1/url-shortener/
Key Featuresโ
- Short Code Generation: Create unique short codes for URLs
- Click Tracking: Count visits to each shortened URL
- Custom Codes: Support for vanity/custom short codes
- Redirect Management: 301/302 redirects with protocol normalization
- Analytics: Track clicks, referrers, and user agents
- Bulk Creation: Generate multiple short URLs at once
๏ฟฝ Directory Structureโ
url-shortener/
โโโ ๐ index.js - Module router
โโโ ๐ redirector.js - Redirect handler (20 lines)
โโโ ๐ README.md - Module documentation
โโโ ๐ controllers/
โ โโโ (URL management)
โโโ ๐ services/
โ โโโ (business logic)
โโโ ๐ routes/
โโโ (route definitions)
Note: Core redirect logic is in standalone redirector.js for simplicity.
๏ฟฝ๐๏ธ Collections Usedโ
short-urlsโ
- Purpose: Store shortened URL mappings
- Model:
shared/models/short-url.js - Key Fields:
code(String, unique) - Short code identifierurl(String) - Full destination URLaccount_id(ObjectId) - Owner accountcreated_by(ObjectId) - Creator uservisits(Number) - Click countcustom(Boolean) - Is custom vanity codeactive(Boolean) - Enable/disable redirectcreated_at(Date)
๐ Data Flowโ
URL Shortening Flowโ
sequenceDiagram
participant User
participant API as URL Shortener API
participant DB as MongoDB
participant Redirect as Redirect Handler
participant Analytics as Analytics Service
User->>API: POST /v1/url (url, custom_code?)
API->>API: Generate/validate short code
API->>DB: Check code uniqueness
alt Code Available
API->>DB: Create short-url document
DB-->>API: { code, url }
API-->>User: Short URL: dash.cl/{code}
else Code Taken
API->>API: Generate new code
API->>DB: Retry insert
end
Note over User,Analytics: Later: User clicks short link
User->>Redirect: GET /{code}
Redirect->>DB: Find URL by code
DB-->>Redirect: { url, visits }
Redirect->>DB: Increment visits counter
Redirect->>Analytics: Log click event
Redirect-->>User: 302 Redirect to full URL
Click Tracking Flowโ
flowchart TD
A[User Clicks Short URL] --> B[Extract Short Code]
B --> C[Query Database]
C --> D{URL Found?}
D -->|No| E[Return 404 Error]
D -->|Yes| F[Increment Visit Count]
F --> G[Log Click Event]
G --> H{Protocol Present?}
H -->|No| I[Prepend https://]
H -->|Yes| J[Use URL as-is]
I --> K[302 Redirect]
J --> K
K --> L[User Reaches Destination]
๐ง Core Functionalityโ
Redirect Handlerโ
File: redirector.js
Function: redirector(req, res, next)
Handles incoming short URL requests and redirects to full URLs.
Process:
// 1. Extract code from URL parameter
const code = req.params.code;
// 2. Find URL mapping
const url = await ShortURL.findOne({ code });
if (!url) {
throw new Error('RESOURCE_NOT_FOUND');
}
// 3. Increment visit counter
url.visits = (url.visits || 0) + 1;
await url.save();
// 4. Normalize URL protocol
let redirectUrl = url.url;
if (!redirectUrl.startsWith('http://') && !redirectUrl.startsWith('https://')) {
redirectUrl = `https://${redirectUrl}`;
}
// 5. Redirect user
res.redirect(redirectUrl);
Business Logic:
- Visit Tracking: Increments counter on every access
- Protocol Normalization: Ensures valid HTTP/HTTPS URL
- Case Sensitivity: Codes are case-sensitive
- 404 Handling: Returns standard 404 for invalid codes
URL Creationโ
Endpoint: POST /v1/url
Request Body:
{
url: String, // Full URL to shorten
custom_code?: String, // Optional vanity code
active?: Boolean // Enable/disable (default: true)
}
Response:
{
success: true,
data: {
code: 'abc123',
url: 'https://example.com/very-long-url',
short_url: 'https://dash.cl/abc123',
visits: 0,
created_at: Date
}
}
Code Generation Logic:
// Default: 6-character alphanumeric code
function generateCode() {
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
let code = '';
for (let i = 0; i < 6; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
return code;
}
// Custom code validation
function validateCustomCode(code) {
// 3-20 characters, alphanumeric and hyphens only
const pattern = /^[a-zA-Z0-9-]{3,20}$/;
return pattern.test(code);
}
Analytics Retrievalโ
Endpoint: GET /v1/url/:code/analytics
Response:
{
success: true,
data: {
code: 'abc123',
url: 'https://example.com',
total_visits: 1250,
created_at: Date,
last_accessed: Date,
click_history: [
{ date: '2025-10-01', clicks: 45 },
{ date: '2025-10-02', clicks: 62 }
]
}
}
Bulk Creationโ
Endpoint: POST /v1/url/bulk
Request Body:
{
urls: [
{ url: 'https://example.com/page1', custom_code: 'promo1' },
{ url: 'https://example.com/page2' },
{ url: 'https://example.com/page3', custom_code: 'sale25' },
];
}
Response:
{
success: true,
data: {
created: [
{ code: 'promo1', url: 'https://example.com/page1' },
{ code: 'xYz789', url: 'https://example.com/page2' },
{ code: 'sale25', url: 'https://example.com/page3' }
],
errors: [] // Codes that failed (duplicates, invalid)
}
}
๐ Integration Pointsโ
Main Applicationโ
Route: GET /:code in internal/app.js
// Global route handler for short URLs
app.get('/:code', redirector);
This enables short URLs at the root level: https://dash.cl/abc123
Marketing Campaignsโ
- Email Marketing: Trackable links in email campaigns
- Social Media: Shortened URLs for Twitter, LinkedIn, etc.
- SMS: Space-saving short links in text messages
- Print Materials: QR codes linking to short URLs
Analytics Dashboardโ
- Click-through rate (CTR) tracking
- Geographic distribution of clicks
- Referrer analysis (where clicks came from)
- Device/browser breakdown
โ๏ธ Configurationโ
Short URL Domainโ
Environment Variable:
SHORT_URL_DOMAIN=dash.cl
Code Generation Settingsโ
const CONFIG = {
codeLength: 6, // Default code length
customCodeMinLength: 3, // Minimum custom code length
customCodeMaxLength: 20, // Maximum custom code length
allowedChars: 'a-zA-Z0-9-', // Valid characters
maxRetries: 5, // Collision retry limit
};
โ ๏ธ Important Notesโ
- ๐ Case-Sensitive Codes: 'ABC' and 'abc' are different codes
- ๐ Collision Handling: Auto-generates new code if collision occurs
- ๐ Visit Tracking: Simple counter (no detailed analytics stored in base model)
- ๐ Protocol Handling: Automatically adds https:// if missing
- โก No TTL: Short URLs never expire (unless manually deactivated)
- ๐ซ No Preview: Direct redirect without preview page
- ๐ Permanent: Codes cannot be changed after creation (URL can be updated)
๐งช Edge Cases & Special Handlingโ
Case: URL Without Protocolโ
Condition: User submits example.com instead of https://example.com
Handling:
// Redirect handler adds https:// prefix
if (!url.startsWith('http://') && !url.startsWith('https://')) {
url = `https://${url}`;
}
Case: Custom Code Collisionโ
Condition: Requested custom code already exists
Handling:
- Return error: "Custom code already in use"
- User must choose different code
- No automatic fallback to generated code
Case: Invalid Destination URLโ
Condition: URL is malformed or inaccessible
Handling:
- URL validation on creation (basic format check)
- No reachability test performed
- Dead links still redirect (400+ errors shown to end user)
Case: High-Traffic Short URLโ
Condition: Popular short URL receiving thousands of clicks
Handling:
- Consider caching URL mapping in Redis
- Use database read replicas for lookups
- Batch visit count updates (every N clicks instead of every click)
๐ Performance Considerationsโ
Indexing Requirementsโ
// short-urls collection
{
code: 1;
} // Unique index for fast lookups
{
account_id: 1;
} // List account's short URLs
{
created_by: 1;
} // User's short URLs
{
created_at: -1;
} // Recent short URLs
Optimization Patternsโ
- Code Lookup Cache: Cache popular codes in Redis (TTL: 1 hour)
- Asynchronous Visit Increment: Queue visit increments to avoid blocking redirect
- Bulk Insert: Use
insertMany()for bulk creation - Projection: Only fetch
urlfield for redirects
Scaling Considerationsโ
- CDN Integration: Use CDN edge locations for global redirect speed
- Sharding: Shard by code prefix for horizontal scaling
- Read Replicas: Use MongoDB read replicas for lookup queries
๐ Security Considerationsโ
Abuse Preventionโ
- Rate Limiting: Limit URL creation per account (e.g., 100/day)
- Code Validation: Prevent reserved words and profanity
- Malicious URL Detection: Integrate with URL reputation services
- CAPTCHA: Require CAPTCHA for bulk creation
Reserved Codesโ
const RESERVED_CODES = [
'admin',
'api',
'app',
'dashboard',
'help',
'login',
'register',
'settings',
'support',
'www',
];
// Reject reserved codes
if (RESERVED_CODES.includes(customCode.toLowerCase())) {
throw new Error('Code is reserved');
}
Last Updated: 2025-10-08
Module Path:internal/api/v1/url-shortener/
Primary File:redirector.js(20 lines - simple but critical)