Skip to content
AdrielcodesPublic

About

Full-stack URL shortener with custom aliases, click tracking, and QR codes — React 19 + Vite frontend, Flask + SQLite API.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚡ ZipURL

A full-stack URL shortener. Paste a long link and get a short one, pick your own custom alias, track how many times it's clicked, and share it with a QR code.

▶ Live demo: https://zipurl-two.vercel.app

This started as one of my first full-stack projects in college (React + Flask + Firebase on Heroku). I rebuilt it in 2026 with a cleaner architecture, a real database layer, click analytics, and tests.

Features

  • Shorten any link: generates a random 6-character code, or use your own alias like /my-portfolio
  • Click tracking: every redirect is counted, and you can see the total and the time of the last click
  • QR codes: generated instantly for any short link
  • Recent links: your last 10 links are saved in the browser, with one-click copy and live click counts
  • Validation that protects users: only http(s) URLs are accepted (no javascript: links), aliases are checked for format and uniqueness, and reserved paths like /api can't be taken
  • Light and dark mode: follows your system setting

Tech Stack

Layer Tech
Frontend React 19, Vite, qrcode.react
Backend Python, Flask 3
Database Postgres (Neon) in production, SQLite locally
Testing pytest (19 tests)
Hosting Vercel (static React build + Flask as a Python function)

How It Works

Browser ──POST /api/links──► Flask ──► SQLite (code, url, clicks, created_at)
Browser ──GET /<code>──────► Flask ──► increment clicks ──► 302 redirect to original URL

In development, Vite proxies /api calls to Flask. In production, Flask serves the built React app and the API from one server.

API

Method Endpoint Description
POST /api/links Body { "url": "...", "alias": "optional" }. Returns the new link (201), 400 if invalid, 409 if the alias is taken
GET /api/links/<code> Stats for a link (URL, clicks, created, last click)
GET /<code> Redirects to the original URL and counts the click
GET /api/health Health check

Running Locally

1. Start the API (Python 3.10+)

cd server
python -m venv .venv
.venv\Scripts\activate          # macOS/Linux: source .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
flask --app app run

2. Start the client (Node 20+), in a second terminal

cd client
npm install
npm run dev

Open http://localhost:5173.

Tests

cd server
pytest

Deploying

The live version runs on Vercel with a Neon Postgres database:

  • vercel.json builds the React client into public/, which is served as static files
  • api/index.py exposes the Flask app as a Python function; /api/* and short-link paths are rewritten to it
  • The server uses Postgres automatically when DATABASE_URL is set, and falls back to SQLite otherwise

Every push to main deploys automatically.

Project Structure

client/          React + Vite frontend
  src/App.jsx    Shortener form, result card, QR code, link history
  src/api.js     API helpers
api/index.py     Vercel function entrypoint
server/          Flask backend
  app.py         Routes, validation, Postgres/SQLite storage
  tests/         pytest suite

About

Full-stack URL shortener with custom aliases, click tracking, and QR codes — React 19 + Vite frontend, Flask + SQLite API.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages