A full-stack URL shortener application with a Python Flask backend and React frontend.
🚀 Live Demo: https://url-shortener.sadlers.cloud/
- ✅ Create short URLs from long URLs
- ✅ Redirect short URLs to original URLs
- ✅ Multiple short URLs allowed for same long URL (for tracking)
- ✅ Base62 encoding for short, readable URLs
- ✅ SQLite database for persistence
- ✅ IDs start at 10000 for better-looking short URLs
- ✅ CORS support for frontend integration
- ✅ Comprehensive error handling and validation
- ✅ Modern, responsive UI with gradient background
- ✅ Real-time URL validation
- ✅ Copy shortened URL to clipboard
- ✅ Test shortened URLs directly in the interface
- ✅ Loading states and error handling
- ✅ Success notifications
./start-dev.shThis will start both the backend (port 8000) and frontend (port 3000) automatically.
-
Set up Virtual Environment
python3 -m venv venv source venv/bin/activate -
Install Python dependencies:
pip install -r requirements.txt
-
Start the backend:
python main.py
-
Install Node.js dependencies:
cd frontend npm install -
Start the React development server:
npm start
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
Test if the server is running:
curl http://localhost:8000/Expected Response:
{ "message": "URL Shortener API is running!" }Convert a long URL to a short one:
curl -X POST \
-H "Content-Type: application/json" \
-d '{"url": "https://www.google.com"}' \
http://localhost:8000/shortenExpected Response:
{ "short_url": "2Bi" }Note: Your actual short URL will vary but will be 3+ characters
Use the short URL to redirect to the original:
curl -L http://localhost:8000/2BiThis will redirect you to https://www.google.com (showing in the CLI the HTML content from Google's homepage)
alternatively:
curl -I http://localhost:8000/2BiThis will show you the redirect response instead of following it (cleaner in the CLI)
Create several short URLs:
# GitHub
curl -X POST \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/EmiSadler/URL_shortener"}' \
http://localhost:8000/shorten
# Bootcamp Simulator
curl -X POST \
-H "Content-Type: application/json" \
-d '{"url": "https://bootcampsim.netlify.app/"}' \
http://localhost:8000/shortenTest with missing URL:
curl -X POST \
-H "Content-Type: application/json" \
-d '{}' \
http://localhost:8000/shortenTest with non-existent short URL:
curl http://localhost:8000/xyz123./build-prod.shOr manually:
cd frontend
npm run buildOption 1 - Using a static file server:
npm install -g serve
serve -s frontend/build -l 3000Option 2 - Using Python's built-in server:
cd frontend/build
python -m http.server 3000For production deployment:
-
Backend: Use a WSGI server like Gunicorn
pip install gunicorn gunicorn -w 4 -b 0.0.0.0:8000 main:create_app() -
Frontend: Serve the built files using a web server like Nginx or Apache
-
Database: Consider using PostgreSQL for production instead of SQLite
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Health check |
POST |
/shorten |
Create short URL from long URL |
GET |
/<short_url> |
Redirect to original URL |
URL_shortener/
├── app/ # Backend Flask application
│ ├── __init__.py
│ ├── config.py # Configuration settings
│ ├── db.py # Database connection and initialization
│ ├── models.py # URL model and database operations
│ ├── routes.py # Flask API routes
│ ├── shortener.py # Short URL generation logic (base62)
│ ├── validators.py # Input validation functions
│ └── error_handlers.py # Error handling utilities
├── frontend/ # React frontend application
│ ├── public/
│ │ ├── index.html # HTML template
│ │ └── manifest.json # PWA manifest
│ ├── src/
│ │ ├── components/ # React components
│ │ │ ├── Header.js # App header
│ │ │ ├── Footer.js # App footer
│ │ │ └── URLShortener.js # Main URL shortener form
│ │ ├── App.js # Main App component
│ │ ├── index.js # React entry point
│ │ └── index.css # Global styles
│ ├── package.json # Node.js dependencies
│ └── build/ # Production build (after npm run build)
├── tests/ # Test files for backend
├── .github/ # GitHub Actions CI/CD
├── docs/ # Documentation
├── scripts/ # Utility scripts
├── main.py # Backend entry point
├── requirements.txt # Python dependencies
├── start-dev.sh # Development startup script
├── build-prod.sh # Production build script
├── url_shortener.db # SQLite database (created automatically)
└── README.md
- URL Submission: User submits a long URL via POST request
- ID Generation: Database assigns an ID starting from 10000
- Short Code Creation: ID is converted to base62 (0-9, a-z, A-Z)
- Database Storage: Both original URL and short code are saved
- Response: Short code is returned to user
- Database: SQLite with auto-incrementing IDs starting at 10000
- Encoding: Base62 encoding for compact, readable URLs
- Port: Runs on port 8000
- Framework: Flask
- URL Format:
http://localhost:8000/<short_code>
Port 8000 in use?
- Kill the process:
lsof -ti:8000 | xargs kill -9 - Or change the port in
main.py
Database issues?
- Delete and recreate:
rm url_shortener.dbthen restart the app