Discover a step-by-step guide to build a URL shortener app using Lovable. Uncover best practices to craft an efficient, scalable solution.
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Creating a New Lovable Project
Using Lovable, start by creating a new project. In the Lovable dashboard, click “New Project” and choose Python as your language. Name your project (for example, “URL Shortener App”). This project will contain all of your code files.
Setting Up Dependencies
Because Lovable does not have a terminal, you install dependencies by creating a file that lists them. Create a new file in your project named requirements.txt
and insert the following code snippet. This file tells Lovable which libraries your app needs.
Flask
Lovable will read this file and install Flask automatically.
Creating the Main Application File
Now create a new file named app.py
. This file will contain all the logic for your URL shortener application. Open app.py
in the Lovable code editor.
Adding URL Shortener Logic to Your App
Copy the following code snippet into your app.py
file. This code uses Flask to create a simple web server that accepts a URL through a form, generates a random short code, and stores the URL in a temporary in-memory dictionary. When the short URL is visited, it redirects to the original URL.
from flask import Flask, request, redirect, render_template_string
import random
import string
app = Flask(name)
Dictionary to store the mapping between short codes and original URLs.
url_mapping = {}
Function to generate a random alphanumeric code.
def generate_short_code(length=6):
return ''.join(random.choices(string.ascii_letters + string.digits, k=length))
Route for the home page with a form to enter a URL.
@app.route('/', methods=['GET', 'POST'])
def home():
message = ''
if request.method == 'POST':
original_url = request.form.get('url')
short_code = generate_short_code()
url_mapping[short_code] = original_url
message = f"Short URL: {request.host_url}{short_code}"
return render_template_string("""
URL Shortener
URL Shortener
{{ message|safe }}
""", message=message)
Route to redirect short URL to the original URL.
@app.route('/<short_code>')
def redirect_short(short_code):
original_url = url_mapping.get(short_code)
if original_url:
return redirect(original_url)
return "URL not found", 404
Run the app on Lovable.
if name == 'main':
app.run(host='0.0.0.0', port=8000)
Save the app.py
file after pasting the code.
Understanding the Code
The code is divided into several parts:
url\_mapping
is used to store the relationship between the short code and the original URL.
generate_short_code
creates a random string of 6 characters.
redirect_short
function looks up the original URL from url_mapping
and redirects the user.
Testing Your URL Shortener Application
In Lovable, click the “Run” button to start your application. The app will start on port 8000 and Lovable will provide a live URL for testing.
Visit the live URL in your web browser. You should see a form where you can enter a URL to shorten. After submitting a URL, a short URL will be displayed. Clicking the short URL should redirect you to your original URL.
Final Notes
Each time you make changes to your code, save the file and click “Run” in Lovable to update your live application. Remember that the URL mapping is stored in a temporary in-memory dictionary; if the server restarts, the data will be lost. For persistent storage, you would need to integrate a database.
const express = require('express');
const mongoose = require('mongoose');
const crypto = require('crypto');
const app = express();
app.use(express.json());
mongoose.connect('mongodb://localhost:27017/lovable-shortener', {
useNewUrlParser: true,
useUnifiedTopology: true
});
const urlSchema = new mongoose.Schema({
originalUrl: { type: String, required: true },
shortCode: { type: String, unique: true, required: true },
createdAt: { type: Date, default: Date.now, expires: '30d' }
});
const Url = mongoose.model('Url', urlSchema);
function generateShortCode() {
return crypto.randomBytes(4).toString('hex');
}
app.post('/api/shorten', async (req, res) => {
const { originalUrl, customAlias } = req.body;
let shortCode = customAlias ? customAlias : generateShortCode();
try {
const exists = await Url.findOne({ shortCode });
if (exists) {
return res.status(409).json({ error: 'Alias already exists' });
}
const newUrl = new Url({ originalUrl, shortCode });
await newUrl.save();
res.json({ shortUrl: `${req.protocol}://${req.get('host')}/${shortCode}` });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.get('/:shortCode', async (req, res) => {
try {
const urlEntry = await Url.findOne({ shortCode: req.params.shortCode });
if (!urlEntry) {
return res.status(404).json({ error: 'URL not found' });
}
res.redirect(urlEntry.originalUrl);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => console.log('Server started on port 3000'));
const express = require('express');
const axios = require('axios');
const mongoose = require('mongoose');
const app = express();
app.use(express.json());
mongoose.connect('mongodb://localhost:27017/lovable-shortener', {
useNewUrlParser: true,
useUnifiedTopology: true
});
const urlSchema = new mongoose.Schema({
originalUrl: { type: String, required: true },
shortCode: { type: String, unique: true, required: true },
createdAt: { type: Date, default: Date.now }
});
const Url = mongoose.model('Url', urlSchema);
const ANALYTICS_API_URL = 'https://analytics.example.com/track';
const ANALYTICS_API_TOKEN = 'YOUR_ANALYTICS_TOKEN';
async function reportAnalytics(shortCode, req) {
try {
await axios.post(ANALYTICS_API_URL, {
shortCode,
ip: req.ip,
userAgent: req.headers['user-agent'],
timestamp: new Date()
}, {
headers: {
'Authorization': `Bearer ${ANALYTICS_API_TOKEN}`
}
});
} catch (error) {
console.error('Analytics reporting failed:', error.message);
}
}
app.get('/:shortCode', async (req, res) => {
try {
const urlData = await Url.findOne({ shortCode: req.params.shortCode });
if (!urlData) {
return res.status(404).json({ error: 'URL not found' });
}
reportAnalytics(req.params.shortCode, req);
res.redirect(urlData.originalUrl);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => console.log('Server running on port 3000'));
const express = require('express');
const { Pool } = require('pg');
const Redis = require('ioredis');
const amqp = require('amqplib');
const app = express();
const pgPool = new Pool({
connectionString: process.env.PG_CONNECTION_STRING
});
const redis = new Redis(process.env.REDIS\_URL);
let amqpChannel = null;
async function initAMQP() {
try {
const connection = await amqp.connect(process.env.AMQP\_URL);
amqpChannel = await connection.createChannel();
await amqpChannel.assertQueue('analytics', { durable: true });
} catch (err) {
console.error('Failed to initialize AMQP:', err.message);
}
}
initAMQP();
app.get('/:shortCode', async (req, res) => {
const { shortCode } = req.params;
try {
// Attempt to retrieve the original URL from Redis cache
let originalUrl = await redis.get(`short:${shortCode}`);
if (!originalUrl) {
// Fallback to PostgreSQL if not in cache
const result = await pgPool.query('SELECT original_url FROM urls WHERE short_code = $1', [shortCode]);
if (result.rowCount === 0) {
return res.status(404).json({ error: 'URL not found' });
}
originalUrl = result.rows[0].original\_url;
// Cache the result for subsequent requests (expire in 1 hour)
await redis.set(`short:${shortCode}`, originalUrl, 'EX', 3600);
}
// Asynchronously report analytics via AMQP
if (amqpChannel) {
amqpChannel.sendToQueue('analytics',
Buffer.from(JSON.stringify({
shortCode,
ip: req.ip,
userAgent: req.headers['user-agent'],
timestamp: Date.now()
})), { persistent: true }
);
}
res.redirect(originalUrl);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => console.log('Server listening on port 3000'));
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Prerequisites
Planning Your URL Shortener App
Setting Up Your Development Environment
app.py
which will contain your application code.
Generating Code with an AI Code Generator
app.py
).app.py
.
Implementing the URL Shortener Logic
from flask import Flask, request, redirect, jsonify
import string
import random
app = Flask(name)
Dictionary to hold URL mappings in memory
url_mapping = {}
def generate_short_code(length=6):
characters = string.ascii_letters + string.digits
return ''.join(random.choices(characters, k=length))
@app.route('/shorten', methods=['POST'])
def shorten_url():
data = request.get_json()
original_url = data.get('url')
if not original_url:
return jsonify({'error': 'URL is required'}), 400
short_code = generate_short_code()
url_mapping[short_code] = original_url
short_url = request.host_url + short_code
return jsonify({'short_url': short_url})
@app.route('/<short_code>')
def redirect_to_url(short_code):
original_url = url_mapping.get(short_code)
if original_url:
return redirect(original_url)
return jsonify({'error': 'Invalid short URL'}), 404
if name == 'main':
app.run(debug=True)
Testing Your Application
python app.py
(or use your online IDE’s run feature)./shorten
endpoint.
Implementing Best Practices
Deploying Your URL Shortener App
When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.