Introduction
Have you ever wanted to create your own URL shortener like Bitly or TinyURL? In this beginner-friendly project, we’ll build a simple URL shortener using just HTML, CSS, and JavaScript—no backend, no database, no API.
Instead of actually shortening the link server-side, we’ll simulate the experience using the browser's local storage. This is a great mini-project to practice DOM manipulation, local storage, and event handling.
Whether you're a beginner learning frontend development or looking for a fun portfolio project, this one’s for you.
🔧 Project Overview
Here’s what we’ll build:
- A form to enter long URLs
- A “shorten” button to create a fake short link
- A list of saved links (stored in localStorage)
- Copy-to-clipboard feature
Let’s break this down snippet by snippet.
1️⃣ HTML Structure – The Skeleton
We’ll start by creating the basic structure of our app.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Simple URL Shortener</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<h1>URL Shortener</h1>
<form id="url-form">
<input type="url" id="long-url" placeholder="Enter a long URL..." required />
<button type="submit">Shorten</button>
</form>
<div id="shortened-links"></div>
</div>
<script src="script.js"></script>
</body>
</html>
🧠 What’s Happening?
- The form with
id="url-form"will handle our input. - The input field accepts valid URLs (
type="url"). - The
#shortened-linksdiv will display our list of short links. - We’ll link our stylesheet and JS file for styling and logic.
2️⃣ CSS Styling – Keep It Clean and Simple
Now let’s add some simple styles for layout and readability.
/* style.css */
body {
font-family: Arial, sans-serif;
background: #f4f4f4;
margin: 0;
padding: 20px;
}
.container {
max-width: 500px;
margin: auto;
background: #fff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
input[type="url"] {
width: 100%;
padding: 12px;
margin: 10px 0;
box-sizing: border-box;
}
button {
padding: 10px 20px;
background: #007bff;
color: #fff;
border: none;
cursor: pointer;
}
button:hover {
background: #0056b3;
}
#shortened-links div {
margin-top: 15px;
padding: 10px;
background: #eee;
border-radius: 4px;
display: flex;
justify-content: space-between;
}
🎨 Style Tips
- We keep a light, modern feel with padding and rounded corners.
- Each shortened URL will be displayed in a clean box with spacing.
3️⃣ JavaScript Logic – Handle Form Submission
Let’s begin the functionality by capturing the form submit event.
// script.js
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('url-form');
const input = document.getElementById('long-url');
const output = document.getElementById('shortened-links');
form.addEventListener('submit', (e) => {
e.preventDefault();
const longUrl = input.value.trim();
if (longUrl) {
const shortCode = Math.random().toString(36).substring(2, 8);
const shortUrl = `https://short.ly/${shortCode}`;
saveToStorage(shortUrl, longUrl);
displayLinks();
input.value = '';
}
});
displayLinks();
});
🔍 Breakdown
- We prevent the default form behavior.
- A random 6-character short code is generated.
- The new "short link" is saved to localStorage using a helper function (coming next).
displayLinks()renders all stored links each time.
4️⃣ Save to localStorage
We now add the helper function to save our URL pairs in localStorage.
function saveToStorage(shortUrl, longUrl) {
let links = JSON.parse(localStorage.getItem('shortLinks')) || [];
links.push({ shortUrl, longUrl });
localStorage.setItem('shortLinks', JSON.stringify(links));
}
🧠 Why localStorage?
This allows the shortened links to persist even after a page refresh—perfect for simulating a real app experience without a backend.
5️⃣ Displaying Shortened Links
Now let’s render the list dynamically inside our #shortened-links container.
function displayLinks() {
const output = document.getElementById('shortened-links');
const links = JSON.parse(localStorage.getItem('shortLinks')) || [];
output.innerHTML = '';
links.forEach(link => {
const div = document.createElement('div');
div.innerHTML = `
<span><a href="${link.shortUrl}" target="_blank">${link.shortUrl}</a></span>
<button onclick="copyToClipboard('${link.shortUrl}')">Copy</button>
`;
output.appendChild(div);
});
}
🔗 Link Rendering
- Each link is clickable and opens in a new tab.
- There’s also a “Copy” button beside each one.
6️⃣ Copy to Clipboard Function
Finally, let’s make that copy button actually work.
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
alert('Link copied to clipboard!');
});
}
✂️ Clipboard API
This uses the modern navigator.clipboard API to copy the shortened URL when clicked.
🙌 Putting It All Together
Once you’ve added each of these snippets in your HTML, CSS, and JS files, your URL shortener will be ready to use!
🔗 Friendly Reminder
To make this app work, combine all snippets in their respective files (index.html, style.css, script.js) and open the index.html in your browser. Simple as that!
✅ Best Practices & Tips
- Keep your JavaScript modular by separating helper functions.
- Add input validation to check for proper URL formats.
- Try improving the UX with a tooltip instead of an alert when copying.
- Clear localStorage manually if needed (for debugging).
🌐 SEO Tie-In
A fast, minimal front-end URL shortener like this improves your understanding of DOM performance and local storage, which are important for building SEO-optimized single-page apps. A responsive, lightweight UI also improves site speed and user experience, two key factors in SEO.
🎯 Conclusion
Congrats! You've just built a simple yet powerful front-end URL shortener without any backend.
This project is a great stepping stone to:
- Build real-world tools
- Learn local storage
- Practice event-driven programming
👉 Try extending it with a backend (Node.js + MongoDB?) later — or even deploy it using Netlify or GitHub Pages.
And hey, if you loved this project, check out more from our projects category — or dive into related topics like Frontend Lab tutorials or Automation with Python.

0 Comments