Minimal URL shortener with custom codes, click tracking, stats dashboard, and delete functionality (Next.js 16 + Neon PostgreSQL + Prisma)
Live Demo: https://tiny-link-harsh.vercel.app/
- Overview
- Features
- Tech Stack
- Architecture & Project Structure
- Installation & Setup
- API Overview
- Frontend Flows
- Environment Configuration
- Author
TinyLink is a production-ready URL shortener built for a take-home assignment, featuring:
- Custom short codes with duplicate protection
- Click tracking with timestamps
- Stats dashboard per link (
/code/:code) - Delete functionality
- Clean, responsive dashboard UI
- Deployed on Vercel with Neon PostgreSQL
Demonstrates Next.js 16 App Router, Prisma ORM, and full-stack TypeScript patterns.
- Shorten any URL →
tiny.link/abc123 - Custom codes (e.g.,
tiny.link/mylink) - Duplicate protection – rejects existing codes
- HTTP 302 redirects with click counting
- Last clicked timestamp tracking
- Stats page
/code/abc123shows total clicks + timestamps - Delete links from dashboard
- List all your links with click counts
- Inline form validation + loading states
- Copy-to-clipboard buttons
- Responsive dashboard design
- Real-time validation feedback
- Clean table with sortable clicks
- Error handling + success states
- Health check endpoint
/healthz
| Layer | Technologies |
|---|---|
| Framework | Next.js 16 (App Router), TypeScript |
| Database | Neon PostgreSQL, Prisma ORM |
| UI | Tailwind CSS, React Hook Form, Zod validation |
| Deployment | Vercel (serverless), Neon (serverless Postgres) |
| Dev Tools | ESLint, Prettier, Prisma Studio, GitHub |
tiny-link/ ├── app/ # Next.js 16 App Router │ ├── api/links/ # API routes (POST, GET, DELETE) │ │ └── [code]/ # Stats + delete │ ├── code/[code]/ # Stats page │ ├── page.tsx # Dashboard │ ├── healthz/ # Health check │ └── not-found.tsx ├── lib/ │ └── prisma.ts # Prisma client ├── prisma/ │ └── schema.prisma # Link model (code, url, clicks, timestamps) ├── .env # DATABASE_URL └── tailwind.config.js
- Node.js v18+ (LTS)
- Neon PostgreSQL account
- npm or yarn
git clone https://github.com/Harsh427744/tiny-link.git cd tiny-link
Copy .env.example → .env:
DATABASE_URL="postgresql://user:pass@ep-xxx.us-east-2.aws.neon.tech/tinylink?sslmode=require" NEXTAUTH_SECRET="your-random-secret" NEXTAUTH_URL="http://localhost:3000"
npm install npx prisma generate npx prisma db push # or migrate deploy
npm run dev
Dashboard: http://localhost:3000
POST /api/links # { url: "https://...", code?: "custom" } GET /api/links # List user's links GET /api/links/:code # Stats for code DELETE /api/links/:code # Delete link
GET /:code # 302 redirect + increment clicks GET /healthz # { "ok": true, "version": "1.0" }
Create Link Payload:
{ "url": "https://google.com", "code": "google" // optional custom code }
- Dashboard → Form: Enter URL → Shorten
- Success → Copy
tiny.link/abc123+ view clicks - Stats
/code/abc123→ Total clicks + timestamps - Delete → Confirm → Removed from list
- Invalid URL → Inline error + shake animation
RequiredDATABASE_URL="postgresql://...@ep-xxx.neon.tech/tinylink?sslmode=require"OptionalNEXTAUTH_SECRET="sk-..." # Generate with openssl rand -base64 32 NEXTAUTH_URL="http://localhost:3000"
Harsh Agarwal
- GitHub: @Harsh427744
- LinkedIn: harsh323
- Email: harshagarwal323.ag@gmail.com
⭐ Star this repo if you find it helpful!
Built for take-home assignment • Deployed on Vercel + Neon • Production-ready