Turn long, messy links into clean, shareable short URLs - with password protection, custom codes and click tracking
Try the live application here: https://url-shortner-service-eight.vercel.app
- First request may be slightly slow due to backend cold start
- All data is stored in a remote MySQL database which is TiDB Cloud Database
It is a full-stack URL shortening web app. You paste a long URL, and it gives you a short one that redirects anyone who visits it. Think Bit.ly or TinyURL - but built fromm scratch, wih you own features and auth system.
Kwy Things you can do:
- Shorten any URL instantly with a random generated code
- Choose you own custom short code
- Password-protect a link so only people with the password can access it
- Track how many times each link has been clicked
- Delete links you no longer need
- Expand a short URL to see where it actually points befor clicking
| Feature | Description |
|---|---|
| Random Short Code | Auto-generates a unique short code for your URL |
| Custom Short Code | Pick you own code and check if it's available in real time |
| Password Protection | Protect links with a password; visitors see a unlock form |
| Click Tracking | See how many times each of your links has been clicked |
| URL Expander | Pasta a short URL and Find out where it leads |
| Delete Links | Remove any link you've created |
| Auth System | Register, login, or continue with Google OAuth |
| Profile Page | View your account info and manage your session |
- Log in to your account
- On the Home page, paste your long URL
- Choose Random code (auto-generated) or Custom code (your own keyword)
- Click Generate - your short link is ready to copy and share
- On the Random Code tab, check "Password Protect"
- Enter a password
- Anyone visiting the short link will see a password from before being redirected
- Go to My URLs to see all links you've created
- Each card shows the original URL, short URL, click count and creation data
- Copy or delete any link directly from the list
- React - UI framework
- React Router - page navigation and tab state via URL params
- Framer Motion - smooth tab transition animations
- Tailwind CSS - Styling and layout
- Axios - API requests
- Go (GoLang) - Server Language
- Gin - HTTP web framework and routing
- GROM - ORM for database interactions
- MySQL - relational database (with TLS connection support)
- JWT - authentication tokens
- bcrypt - password hashing
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/register |
Create a new account |
| POST | /api/auth/login |
Login and receive JWT |
| POST | /api/auth/google |
Google OAuth Login |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/shorten |
Create a random short URL |
| POST | /api/shorten/custom |
Create a custom short URL |
| POST | /api/protected |
Create a password-protected URL |
| GET | /api/myurls |
Get All URLs for logged-in user |
| DELETE | /api/url/:code |
Delete a URL (owner only) |
| GET | /api/shortcode/:code/check |
Check if a short code is taken |
| GET | /api/expand?url=... |
Resolve a URL to its final destination |
| Method | Endpoint | Description |
|---|---|---|
| GET | /:code |
Redirect to original URL (or show password form) |
| POST | /:code/verify |
Submit password and redirect |
- Go 1.21 +
- Node.js 18+
- MySQL database
.envfile withDB_DSNandDB_CERT
cd server
go mod tidy
go run main.go
o
# Server runs on :8000cd client
npm install
npm run dev
v
# App runs on :5173DB_DSN=user:password@tcp(host:port)/dbname?tls=custom&parseTime=truetrue
DB_CERT=-------BEGIN CERTIFICATE-----\n...\n----END CERTIFICATE-------
JWT_SECRET=your_jwt_secret
GOOGLE_CLIENT_ID=google_client_id- Short Code Collision handling - when generating a random code, the server loops and regenerates until a unique code is confirmed against the DB. This prevents duplicates even under high load.
-- TLS-Secured DB connection - the MySQL connection uses a custom TLS config with a CA cert parsed from an environment variable, supporting cloud-hosted databases that require encrypted connections.
-
DB connection retry - on startup, the server retries the DB connection up to 5 times with a 3-second delay between attempts, making it resilient to cold-start race conditions.
-
Password hashing - link passwords are hashed with bcrypt before storage. Plain-text passwords are never saved. Verification uses
bcrypt.Compare. -
Real-time availability - the custom short code input debounces API calls and shows instant feedback ("Available" / "Already Takend") befor the user submits.
-
Tab state in URL - the Home page uses
useSearchParamsto persist the active tab (?tab=random/?tab=custom) in the URL, so the tab survives page refreshes and can be bookmarked or shared. -
Connection pooling - GORM's underlying
sql.DBis configured with max open/idle connections and lifetime limits to prevent connection exhaustion on a hosted DB.
The application includes a dedicated Admin Dashboard that allows priviliged users to manage the entire system.
Only users with
adminrole can access these endpoints and UI features.
| Feature | Description |
|---|---|
| View all Users | Fetch and list all registered users |
| Delete Users | Remove users (except yourself) |
| View All URLs | See every URL shortened URL in the system |
| Delete Any URL | Remove any URL regardless of owner |
| User Status | Check if users are active/inactive |
| Role management | Indentify user roles (admin/user) |
All routes require authentication + admin role
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/admin/users |
Get all Users |
| GET | /api/admin/urls |
Get all URLs |
| DELETE | /api/admin/user/:id |
Delete a user |
| DELETE | /api/admin/url/:code |
Delete any URL |
The app includes a browser-based terminal for power users and developers who prefer a keyboard-driven workflow.
shorten
generate a random short link
shorten --pass
generate a password-protected short link
custom
create a custom short link
check
check if a short code is available or not
expand
expand a short URL to its original URL
clear
clear the terminal
help
show available commands
terminal
help
show available commands
ble commands
- Command history - use the
↑/↓arrow keys to cycle through the previous commands, just like a real terminal - Password-protected links - pass
--passinline; no seperate form neededrd> - Real-time feedback - colored output distinguishes prompts, results, errors and success messages at a glance
- Non-blocking input - The input field is disabled during requests to prevent duplicate submissions
- Auto-Scroll - output automatically scrolls to the latest line as commands run
- Clicks-to-focus - Clicking anywhere on the terminal panel focuses the input
| Color | Meaning |
|---|---|
| Green (prompt) | Your command input |
| Yellow | Short URLs |
| Bright green | Success Messages |
| Red | Errors |
| Blue | Info/banners |
| Gray | Muted / loading text |
Admins cannot delte their own account.
When a user is deleted, all their URLs are deleted first.
Protected by:
AuthMiddleware()→ verifies JWTAdminOnly()→ restricts access to admin only
The frontend includes a clean admin interface with:
- Users Tab
- URLs Tab
- Avatar, Name, Email, Role, Status, Created Date
- Delete action with confirmation modal
- Short Code, Original URL, User ID, Clicks, Created Date
- Delete Action with confirmation modal
- Prevents accidental deletions
- Shows loading state while deleting
To explore the Admin Dashboard, use the following credentials:
- Email: [email protected]
- Password: admin123
⚠️ This is a demo admin account. Do not use it for sensitive data
Built by Jaison David M with love