1557 words
8 minutes
How to Build a URL Shortener with Flask, SQLite, and Bootstrap

Building a URL Shortener with Flask, SQLite, and Bootstrap

A URL shortener provides a concise way to represent long web addresses. This process involves creating a short code that maps to an original, longer URL. When the short code is accessed, the system redirects the user to the original URL. URL shorteners are valuable for sharing links on platforms with character limits, improving readability, and sometimes for tracking click data.

Constructing a URL shortener involves three core components: a backend application to handle requests and manage data, a database to store the mapping between short codes and long URLs, and a frontend to provide a user interface for submitting long URLs and displaying the resulting short ones. Flask, SQLite, and Bootstrap offer a practical combination for developing such a service.

Essential Concepts for a URL Shortener

Understanding the fundamental technologies and processes is crucial for building a URL shortener.

Flask: The Web Framework#

Flask is a lightweight Python web framework. It provides the necessary tools to handle HTTP requests, route URLs to specific functions, and manage web application logic. Its minimalist design makes it easy to learn and use for projects of varying sizes. For a URL shortener, Flask will manage the submission of long URLs, generate short codes, store mappings in the database, and handle redirection requests.

SQLite: The Database#

SQLite is a serverless, self-contained, file-based SQL database engine. It is ideal for smaller applications or development environments where setting up a separate database server is unnecessary. SQLite stores the data persistence for the URL shortener, specifically the table that pairs the unique short codes with their corresponding original URLs. The database operates as a single file, making setup and management straightforward.

Bootstrap: The Frontend Framework#

Bootstrap is a popular open-source CSS framework directed at responsive, mobile-first front-end web development. It contains HTML and CSS-based design templates for typography, forms, buttons, navigation, and other interface components, as well as optional JavaScript extensions. Using Bootstrap simplifies the creation of a user-friendly interface for the URL shortener, ensuring it looks presentable and functions well across different devices without extensive manual CSS coding.

Short Code Generation#

A critical component of a URL shortener is the method used to generate unique short codes. These codes must be relatively short and unique to avoid collisions (two different long URLs mapping to the same short code). Common techniques include:

  • Sequential IDs: Using a database primary key (auto-incrementing integer) and converting it to a different base (e.g., base62 using a-z, A-Z, 0-9). This guarantees uniqueness.
  • Hashing: Using a cryptographic hash function and potentially truncating the output. Requires collision handling.
  • Random String Generation: Creating random strings and checking for existence in the database, regenerating if a collision occurs.

For simplicity and guaranteed uniqueness, using a database’s auto-incrementing ID converted to a different base is a robust approach for a basic implementation.

Step-by-Step Guide to Building the Shortener

This section outlines the process of building the URL shortener using Flask, SQLite, and Bootstrap.

1. Project Setup and Dependencies#

Begin by setting up a project directory and installing the required Python packages.

Terminal window
mkdir url-shortener
cd url-shortener
pip install Flask Flask-SQLAlchemy shortuuid
  • Flask: The web framework.
  • Flask-SQLAlchemy: A Flask extension that adds support for SQLAlchemy, an Object-Relational Mapper (ORM), making database interactions simpler.
  • shortuuid: A library for generating short, unique, unambiguous, and URL-safe UUIDs. This is an alternative to converting integer IDs and provides unique codes out-of-the-box.

2. Database Model Definition#

Define the database structure using Flask-SQLAlchemy. A single table is needed to store the original URL and its corresponding short code.

Create a file (e.g., app.py) and set up the basic Flask application and database connection.

from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
import shortuuid
import os
# Setup Flask application
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///urls.db' # SQLite database file
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# Define the database model
class URL(db.Model):
id = db.Column(db.Integer, primary_key=True)
original_url = db.Column(db.String(500), nullable=False)
short_code = db.Column(db.String(10), unique=True, nullable=False)
def __init__(self, original_url, short_code):
self.original_url = original_url
self.short_code = short_code
# Create database tables
# This should ideally be handled by Flask-Migrate for production, but for simplicity:
with app.app_context():
db.create_all()
  • The URL model represents a row in the urls table.
  • id: An auto-incrementing primary key.
  • original_url: Stores the long URL.
  • short_code: Stores the generated short code, ensuring it’s unique.
  • db.create_all() creates the table if it doesn’t exist when the application context is available.

3. Frontend Design with Bootstrap#

Create the HTML templates for the user interface. This requires a directory named templates in the project root.

Inside the templates directory, create index.html. This file will contain the form for submitting long URLs and display the resulting short URL. Include Bootstrap CSS for styling.

<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<title>URL Shortener</title>
</head>
<body>
<div class="container mt-5">
<h1 class="text-center mb-4">Shorten Your URL</h1>
<form method="POST" action="/">
<div class="form-group">
<label for="long_url">Enter Long URL:</label>
<input type="url" class="form-control" id="long_url" name="long_url" required>
</div>
<button type="submit" class="btn btn-primary btn-block">Shorten</button>
</form>
{% if short_url %}
<div class="mt-4 alert alert-success" role="alert">
Your shortened URL: <a href="{{ short_url }}" target="_blank">{{ short_url }}</a>
</div>
{% endif %}
{% if error %}
<div class="mt-4 alert alert-danger" role="alert">
{{ error }}
</div>
{% endif %}
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.3/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
  • This template uses Bootstrap classes (container, mt-5, form-group, btn, alert) for basic layout and styling.
  • It includes a form to submit the long_url.
  • Flask’s Jinja templating ({% if short_url %}, {{ short_url }}) is used to display the result or any error messages.

4. Implementing Flask Routes#

Now, add Flask routes to app.py to handle the homepage (GET and POST) and the redirection route.

# ... (previous imports and database setup) ...
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
original_url = request.form['long_url']
if not original_url:
return render_template('index.html', error="URL cannot be empty.")
# Generate a short code
# Using shortuuid ensures uniqueness reasonably well without checking DB every time initially
short_code = shortuuid.uuid()[:7] # Generate a short, unique code
# Check if code already exists (unlikely with shortuuid, but good practice)
existing_url = URL.query.filter_by(short_code=short_code).first()
while existing_url: # Rare, but handle collision
short_code = shortuuid.uuid()[:7]
existing_url = URL.query.filter_by(short_code=short_code).first()
# Create new URL object and save to database
new_url = URL(original_url=original_url, short_code=short_code)
db.session.add(new_url)
db.session.commit()
# Construct the full short URL
short_url = request.url_root + short_code
return render_template('index.html', short_url=short_url)
# Handle GET request for the homepage
return render_template('index.html')
@app.route('/<short_code>')
def redirect_to_url(short_code):
# Retrieve the original URL from the database using the short code
url_mapping = URL.query.filter_by(short_code=short_code).first()
if url_mapping:
# Redirect to the original URL
return redirect(url_mapping.original_url)
else:
# Handle cases where the short code does not exist
return render_template('404.html'), 404 # Assume a 404.html template exists or render a simple message
  • The / route handles both GET (displaying the form) and POST (processing the form submission).
  • On POST, it retrieves the long_url from the form data.
  • It generates a unique short_code using shortuuid. A basic collision check is included.
  • A new URL object is created and added to the database session, then committed.
  • The full short_url is constructed (e.g., http://127.0.0.1:5000/<code>).
  • The / template is rendered again, passing the short_url to be displayed.
  • The /<short_code> route handles incoming requests to the short URLs.
  • It queries the database for the short_code.
  • If found, it uses redirect() to send the user to the original_url.
  • If not found, it renders a 404 error page (requires creating a simple 404.html or modifying the code to render text).

5. Running the Application#

Add the standard Flask runner code at the end of app.py.

# ... (previous code) ...
if __name__ == '__main__':
app.run(debug=True) # Run the Flask application in debug mode

Now, from the project directory, run the application:

Terminal window
python app.py

The server will start, typically on http://127.0.0.1:5000/. Accessing this address in a web browser will show the form. Submitting a long URL will generate and display the short URL. Visiting the short URL will redirect to the original long URL.

Real-World Application Example

Consider a marketing campaign where a company wants to share a link to a specific product page on social media platforms like Twitter, which have character limits.

  • Original URL: https://www.example.com/products/new-amazing-gadget-launch-special-offer (potentially very long)
  • Using the Shortener: The marketing team enters this long URL into the built Flask shortener.
  • Shortener Output: The shortener processes the request, generates a unique code (e.g., AbCd12), and saves the mapping in the SQLite database. It displays the short URL: http://yourshortenersite.com/AbCd12.
  • Sharing: The team shares http://yourshortenersite.com/AbCd12 on Twitter. This concise link fits within the character limit and looks cleaner.
  • User Experience: When a user clicks http://yourshortenersite.com/AbCd12, the request goes to the Flask application’s /<short_code> route. The application looks up AbCd12 in the SQLite database, finds the corresponding original URL, and redirects the user seamlessly to the product page.

This demonstrates the practical utility of the built shortener: providing a simple, effective way to manage and share long links using standard web technologies and a lightweight database.

Key Takeaways

  • Building a URL shortener involves a backend for logic and data, a database for storage, and a frontend for user interaction.
  • Flask provides a flexible framework for handling web requests and application flow.
  • SQLite offers a simple, file-based database solution suitable for small to medium-sized applications or development.
  • Bootstrap simplifies the creation of a responsive and user-friendly web interface.
  • Generating unique short codes is crucial, with methods like converting sequential IDs or using libraries like shortuuid.
  • The core functionality involves two routes: one to accept long URLs and return short codes, and one to accept short codes and redirect to original URLs.
  • The shortener enables the use of concise links for sharing, improving readability and fitting within character constraints.
How to Build a URL Shortener with Flask, SQLite, and Bootstrap
https://dev-resources.site/posts/how-to-build-a-url-shortener-with-flask-sqlite-and-bootstrap/
Author
Dev-Resources
Published at
2025-06-29
License
CC BY-NC-SA 4.0