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-links
div 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