⚡ A blazingly fast, self-hosted link shortener with click tracking & QR codes
Live Demo: miniurl.shalusri.com
Relinkr is a modern, self-hosted URL shortener that provides enterprise-grade features while maintaining simplicity and performance. Built with Next.js and Redis, it offers lightning-fast redirects, comprehensive analytics, and QR code generation.
- 🔗 Custom & Case-Insensitive Slugs - Create human-readable short URLs with your own custom slugs
- 🔒 Secure Random Generation - Automatically generate unique, non-guessable slugs using nanoid
- 📊 Click Tracking & Analytics - Built-in analytics track click counts with detailed logging
- 📱 Dynamic QR Code Generation - Instantly generate high-quality SVG QR codes for every link
- 🎛️ Simple User Dashboard - Clean, intuitive interface to manage all your links
- 🎨 Artist-Inspired Themes - 15 beautiful themes inspired by famous artists (Indian & Western)
- 🐳 Docker Deployment - Deploy anywhere with a single Docker command
- 🔐 OAuth Authentication - Secure authentication via GitHub and Google using NextAuth.js
- ⚡ Redis Performance - Lightning-fast URL lookups powered by Redis in-memory storage
- 💾 Database Backup/Restore - Built-in scripts for backing up and restoring Redis data
What it does: Containerizes the Relinkr Next.js client app and Redis for easy local or production deployment.
Build: docker-compose build
Run: docker-compose up --build -d
Access: Open http://localhost:3000 in your browser
Notes:
- Ports:
3000:3000(web interface),6379:6379(Redis) - Env vars: Set in
apps/client/.env.local(copied to.env.dockerfor containers) - No file-based input/output volumes required
- Redis data is persisted in the
redis-dataDocker volume
# Clone the repository
git clone https://github.com/knightsri/Relinkr.git
cd Relinkr
# Step 1: Set up your OAuth credentials (one-time setup)
cp apps/client/.env.example apps/client/.env.local
# Edit .env.local with your GitHub and Google OAuth credentials
# Step 2: Deploy with Docker (credentials automatically copied)
docker-compose up --build -d
# Your Relinkr instance is now running at http://localhost:3000🔄 How Docker Handles Environment Variables:
docker-compose upautomatically copies OAuth credentials from.env.localto.env.docker- Docker containers use
.env.dockerfor runtime configuration - Containers never read
.env.localdirectly (keeps secrets isolated)
📋 Important Notes:
- Setup OAuth credentials once in
.env.local, Docker handles the rest - All dependencies (Node.js, npm, Redis) are included in containers
docker-compose stopstops,docker-compose up -drestarts- See
DOCKER_README.mdfor detailed Docker commands and troubleshooting
✨ What's Included in Docker Setup: ✅ Next.js application with custom Dockerfile for optimal performance ✅ Redis database container for fast URL lookups and analytics ✅ Automatic OAuth credential sync for GitHub and Google authentication ✅ Network isolation and security best practices ✅ Production-ready container images
# Clone and setup
git clone https://github.com/knightsri/Relinkr.git
cd Relinkr/apps/client
# Install dependencies
npm install
# Setup environment
cp .env.example .env.local
# Edit .env.local with your configuration
# Start Redis (in separate terminal)
redis-server
# Start the application
npm run devFor Docker Container Setup (Recommended):
Create .env.local file in apps/client/ - Docker automatically copies OAuth credentials:
# NextAuth.js Configuration
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-secret-key-here
# OAuth Providers (copied automatically to .env.docker for containerized auth)
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
# Redis Configuration (auto-managed in Docker)
REDIS_URL=redis://redis:6379
# Application Settings
SLUG_LENGTH=10
NEXT_PUBLIC_HIGHLIGHT_DURATION=3For Manual Installation:
Create .env.local file in apps/client/ (same variables as above, but set REDIS_URL=redis://localhost:6379)
📝 Note: Docker containers use .env.docker internally but sync from your .env.local - no manual setup needed!
- Go to GitHub Settings → Developer settings → OAuth Apps
- Click "New OAuth App"
- Set Authorization callback URL to:
http://localhost:3000/api/auth/callback/github - Copy the Client ID and Client Secret to your
.env.localfile
- Go to Google Cloud Console → APIs & Services → Credentials
- Create a new OAuth 2.0 Client ID
- Add authorized redirect URI:
http://localhost:3000/api/auth/callback/google - Copy the Client ID and Client Secret to your
.env.localfile
- Access the Dashboard: Navigate to
http://localhost:3000and sign in with GitHub or Google - Create Short Links: Enter a long URL and optionally specify a custom slug
- Manage Links: View, edit, delete, and track analytics for all your links
- Copy & Share: Click "Copy link" to get the short URL for sharing
- QR Codes: Access QR codes by visiting
http://localhost:3000/[slug]/qr
All API endpoints require authentication via NextAuth.js session cookies.
POST /api/links/create
Content-Type: application/json
{
"longUrl": "https://example.com/very-long-url",
"customSlug": "my-event" // optional
}GET /api/links/list?page=1&perPage=10&q=search&sortField=clicks&sortDirection=descPOST /api/links/update
Content-Type: application/json
{
"internalId": "abc123",
"longUrl": "https://example.com/updated-url"
}POST /api/links/delete
Content-Type: application/json
{
"internalId": "abc123"
}GET /api/analytics/counts?slugs=slug1&slugs=slug2Relinkr features 15 artist-inspired themes with carefully curated color palettes. The default theme is Nandalal Bose.
Indian Artists:
| Theme | Artist | Palette |
|---|---|---|
| Nandalal Bose (default) | Bengal School | Muted earth tones, dusty greens |
| Raja Ravi Varma | Classical Indian | Deep reds, royal gold, warm ivory |
| Jamini Roy | Bengali Folk Art | Terracotta, ochre, earthy browns |
| M.F. Husain | Indian Modernism | Bold reds, earthy browns |
| S.H. Raza | Bindu/Geometric | Deep reds, black, gold |
| Amrita Sher-Gil | Indian Post-Impressionism | Rich ochres, warm reds |
Western Artists:
| Theme | Artist | Palette |
|---|---|---|
| Van Gogh | Post-Impressionism | Deep blues, vibrant yellows |
| Matisse | Fauvism | Bold reds on soft pink |
| Monet | Impressionism | Soft pastels, misty blues |
| Klimt | Art Nouveau | Rich golds on deep brown |
| Frida Kahlo | Mexican Surrealism | Hot pinks, bright yellows |
| David Hockney | Pop/Contemporary | California pool turquoise |
| Gauguin | Post-Impressionism | Tropical oranges, deep greens |
| Andy Warhol | Pop Art | Neon pinks, magentas |
| Yayoi Kusama | Contemporary | Vibrant reds on cream |
-
Create a CSS File: In
apps/client/styles/themes/, create a new CSS file:.my-theme { --background: #f0f0f0; --foreground: #333333; --primary: #ff6347; --primary-foreground: #ffffff; --surface: #ffffff; --surface-border: #e0e0e0; --table-row-bg: #fafafa; --table-row-alt-bg: #f5f5f5; --table-row-hover-bg: #eeeeee; --font-sans: "Roboto", sans-serif; }
-
Import the Theme: Add to
apps/client/styles/globals.css:@import "./themes/my-theme.css";
-
Register the Theme: Add to
apps/client/components/ThemeSwitcher.tsx:{ id: 'my-theme', name: 'My Theme' }
- Frontend: Next.js (React) with TypeScript
- Backend: Next.js API Routes (Node.js)
- Database: Redis for high-performance storage
- Authentication: NextAuth.js with OAuth (GitHub, Google)
- Validation: Zod for type-safe data validation
- Deployment: Docker with Docker Compose
- QR Codes: Built-in SVG QR code generation
# Build and run in production mode
docker-compose -f docker-compose.prod.yml up -dRelinkr can be deployed on any cloud platform that supports Docker:
- DigitalOcean: App Platform or Droplets
- AWS: ECS, Fargate, or EC2
- Google Cloud: Cloud Run or Compute Engine
- Azure: Container Instances or App Service
- Heroku: Container Registry with Redis add-on
Update your production environment variables:
NEXTAUTH_URL=https://yourdomain.com
REDIS_URL=redis://your-redis-host:6379
# Update OAuth callback URLs to match your domainRelinkr includes built-in scripts to backup and restore your Redis database.
cd apps/client
# Create a timestamped backup
npm run db:backup
# Create a backup with custom filename
npm run db:backup my-backup.jsoncd apps/client
# Restore with confirmation prompt
npm run db:restore backup-2024-01-15.json
# Restore without confirmation (for scripts/automation)
npm run db:restore backup.json --force- URL mappings - All short links and their destinations
- Click counts - Analytics data for each link
- User ownership - Which user owns which links
- Detailed logs - Timestamped click logs (if enabled)
Backups are stored as JSON files:
{
"version": "1.0",
"timestamp": "2024-01-15T10:30:00.000Z",
"data": {
"urls": { "slug": { "longUrl": "...", "ownerId": "...", "internalId": "..." } },
"clicks": { "slug": 42 },
"userLinks": { "user@email.com": ["slug1", "slug2"] },
"logs": { "slug": [{ "timestamp": "...", "ip": "..." }] }
}
}To backup/restore a remote Redis instance, set the REDIS_URL environment variable:
REDIS_URL=redis://remote-host:6379 npm run db:backup
REDIS_URL=redis://remote-host:6379 npm run db:restore backup.jsonRelinkr/
├── apps/client/ # Next.js application
│ ├── components/ # React components
│ │ ├── Toast.tsx # Toast notifications
│ │ └── ThemeSwitcher.tsx # Theme selection dropdown
│ ├── pages/ # Next.js pages and API routes
│ │ ├── api/ # API endpoints
│ │ │ ├── auth/ # NextAuth.js configuration
│ │ │ ├── links/ # Link management APIs
│ │ │ └── analytics/ # Analytics APIs
│ │ ├── index.tsx # Main dashboard
│ │ ├── [slug].tsx # Link redirect handler
│ │ └── signin.tsx # Authentication page
│ ├── scripts/ # Utility scripts
│ │ ├── backup.js # Database backup
│ │ └── restore.js # Database restore
│ ├── styles/ # CSS styles
│ │ ├── globals.css # Global styles
│ │ ├── dashboard.css # Dashboard styles
│ │ └── themes/ # Artist-inspired themes (15 files)
│ ├── lib/ # Utility libraries
│ ├── config/ # Configuration files
│ └── public/ # Static assets
├── docker-compose.yml # Docker orchestration
└── README.md # This file
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make your changes and test thoroughly
- Commit your changes:
git commit -am 'Add feature' - Push to the branch:
git push origin feature-name - Submit a pull request
Redis Connection Failed
- Verify Redis is running:
docker psorredis-cli ping - Check Redis URL in environment variables
- Ensure Redis port (6379) is not blocked
OAuth Authentication Not Working
- Verify OAuth app callback URLs match your domain
- Check CLIENT_ID and CLIENT_SECRET are correct
- Ensure NEXTAUTH_URL matches your actual domain
- Verify NEXTAUTH_SECRET is set and secure
Port Already in Use
- Stop existing processes:
pkill -f "npm run dev" - Or use a different port by modifying the start script
This project is licensed under the MIT License - see the LICENSE file for details.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: See the
/docsfolder for detailed guides
- Built with Next.js
- Authentication by NextAuth.js
- Powered by Redis
- Deployed with Docker
Relinkr - Fast, secure, and self-hosted link shortening for everyone.