Skip to content

Commit 6c5b8df

Browse files
committed
feat: upload init extension
1 parent dbe9c32 commit 6c5b8df

File tree

5 files changed

+524
-0
lines changed

5 files changed

+524
-0
lines changed

README.md

-170 Bytes

# Clean URL Slug Generator Chrome Extension A professional Chrome extension that helps you generate clean, SEO-friendly URL slugs from any text input. Perfect for content creators, developers, and SEO professionals. ![Version](https://img.shields.io/badge/version-1.0.0-blue.svg) ![License](https://img.shields.io/badge/license-MIT-green.svg) ![Chrome Web Store](https://img.shields.io/badge/Chrome%20Web%20Store-v1.0.0-blue) ## 🌟 Features - **Smart Slug Generation**: Convert any text into URL-friendly slugs - **Customizable Options**: - Choose between dash (-) or underscore (_) separators - Remove common stop words for cleaner slugs - Option to remove numbers - **User-Friendly Interface**: - Real-time slug generation - One-click copy to clipboard - Clear and Reset functionality - Informative help section - **Professional Design**: - Modern, clean interface - Responsive layout - Smooth animations - Intuitive controls ## 🚀 Installation 1. Clone or download this repository 2. Open Chrome and navigate to `chrome://extensions/` 3. Enable "Developer mode" in the top right corner 4. Click "Load unpacked" and select the extension directory ## 💡 Usage 1. Click the extension icon in your Chrome toolbar 2. Enter your text in the input field 3. Choose your preferred options: - Select separator type (dash or underscore) - Toggle stop words removal - Toggle number removal 4. The slug will be generated automatically as you type 5. Click the copy button to copy the slug to your clipboard ## 🛠️ Development The extension is built with vanilla JavaScript and uses Chrome Extension Manifest V3. ### File Structure ``` clean-url-slug-generator/ ├── manifest.json # Extension configuration ├── popup.html # Extension popup interface ├── popup.js # Main functionality ├── styles.css # Styling ├── icons/ # Extension icons │ ├── icon16.png │ ├── icon48.png │ └── icon128.png └── README.md # Documentation ``` ### Technologies Used - HTML5 - CSS3 - Vanilla JavaScript - Chrome Extension APIs - Font Awesome Icons ## 📝 License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## 👨‍💻 Author **Vulct** - GitHub: [@vulct174](https://github.com/vulct174) - Email: [vulct.it@gmail.com](mailto:vulct.it@gmail.com) ## 🤝 Contributing Contributions, issues, and feature requests are welcome! Feel free to check the [issues page](https://github.com/vulct174/clean-url-slug-generator/issues). ## 📞 Support If you have any questions or need help, please: 1. Check the [issues page](https://github.com/vulct174/clean-url-slug-generator/issues) 2. Contact me via email: [vulct.it@gmail.com](mailto:vulct.it@gmail.com) --- Made with ❤️ by [Vulct](https://github.com/vulct174) # extension-clean-url-slug-generator

Clean URL Slug Generator Chrome Extension

A professional Chrome extension that helps you generate clean, SEO-friendly URL slugs from any text input. Perfect for content creators, developers, and SEO professionals.

Version License Chrome Web Store

🌟 Features

  • Smart Slug Generation: Convert any text into URL-friendly slugs
  • Customizable Options:
    • Choose between dash (-) or underscore (_) separators
    • Remove common stop words for cleaner slugs
    • Option to remove numbers
  • User-Friendly Interface:
    • Real-time slug generation
    • One-click copy to clipboard
    • Clear and Reset functionality
    • Informative help section
  • Professional Design:
    • Modern, clean interface
    • Responsive layout
    • Smooth animations
    • Intuitive controls

🚀 Installation

  1. Clone or download this repository
  2. Open Chrome and navigate to chrome://extensions/
  3. Enable "Developer mode" in the top right corner
  4. Click "Load unpacked" and select the extension directory

💡 Usage

  1. Click the extension icon in your Chrome toolbar
  2. Enter your text in the input field
  3. Choose your preferred options:
    • Select separator type (dash or underscore)
    • Toggle stop words removal
    • Toggle number removal
  4. The slug will be generated automatically as you type
  5. Click the copy button to copy the slug to your clipboard

🛠️ Development

The extension is built with vanilla JavaScript and uses Chrome Extension Manifest V3.

File Structure

clean-url-slug-generator/
├── manifest.json      # Extension configuration
├── popup.html        # Extension popup interface
├── popup.js          # Main functionality
├── styles.css        # Styling
├── icons/            # Extension icons
│   ├── icon16.png
│   ├── icon48.png
│   └── icon128.png
└── README.md         # Documentation

Technologies Used

  • HTML5
  • CSS3
  • Vanilla JavaScript
  • Chrome Extension APIs
  • Font Awesome Icons

📝 License

This project is licensed under the MIT License - see the LICENSE file for details.

👨‍💻 Author

Vulct

🤝 Contributing

Contributions, issues, and feature requests are welcome! Feel free to check the issues page.

📞 Support

If you have any questions or need help, please:

  1. Check the issues page
  2. Contact me via email: vulct.it@gmail.com

Made with ❤️ by Vulct

manifest.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"manifest_version": 3,
3+
"name": "Clean URL Slug Generator",
4+
"version": "1.0.0",
5+
"description": "Smart, fast and easy to use tool to generate search engine friendly and user friendly URL slugs",
6+
"action": {
7+
"default_popup": "popup.html",
8+
"default_icon": {
9+
"16": "icons/icon16.png",
10+
"48": "icons/icon48.png",
11+
"128": "icons/icon128.png"
12+
}
13+
},
14+
"icons": {
15+
"16": "icons/icon16.png",
16+
"48": "icons/icon48.png",
17+
"128": "icons/icon128.png"
18+
},
19+
"permissions": ["storage", "clipboardWrite"]
20+
}

popup.html

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Clean URL Slug Generator</title>
7+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
8+
<link rel="stylesheet" href="styles.css">
9+
</head>
10+
<body>
11+
<div class="container">
12+
<div class="header">
13+
<h1>Clean URL Slug Generator</h1>
14+
<p class="subtitle">Transform titles into SEO-friendly URL slugs</p>
15+
</div>
16+
17+
<div class="input-section">
18+
<label for="inputString">INPUT STRING:</label>
19+
<textarea id="inputString" placeholder="Article title, tutorial title or any web page title"></textarea>
20+
</div>
21+
22+
<div class="options-section">
23+
<div class="option">
24+
<input type="radio" id="dashSeparator" name="separator" value="dash" checked>
25+
<label for="dashSeparator">Separate with dash (-)</label>
26+
</div>
27+
<div class="option">
28+
<input type="radio" id="underscoreSeparator" name="separator" value="underscore">
29+
<label for="underscoreSeparator">Separate with underscore (_)</label>
30+
</div>
31+
<div class="option">
32+
<input type="checkbox" id="removeStopWords">
33+
<label for="removeStopWords">Remove stop words</label>
34+
</div>
35+
<div class="option">
36+
<input type="checkbox" id="removeNumbers">
37+
<label for="removeNumbers">Remove numbers</label>
38+
</div>
39+
</div>
40+
41+
<div class="actions">
42+
<button id="slugifyBtn" class="btn primary-btn">
43+
<i class="fas fa-link"></i> SLUGIFY
44+
</button>
45+
<div class="secondary-actions">
46+
<button id="clearBtn" class="btn secondary-btn">
47+
<i class="fas fa-trash"></i> CLEAR
48+
</button>
49+
<button id="resetBtn" class="btn secondary-btn">
50+
<i class="fas fa-redo"></i> RESET
51+
</button>
52+
</div>
53+
</div>
54+
55+
<div class="output-section">
56+
<label for="outputSlug">OUTPUT:</label>
57+
<div class="output-container">
58+
<input type="text" id="outputSlug" readonly placeholder="Clean URL slug">
59+
<button id="copyBtn" class="copy-btn" title="Copy to clipboard">
60+
<i class="fas fa-copy"></i>
61+
</button>
62+
</div>
63+
</div>
64+
65+
<div class="info-section">
66+
<div class="info-toggle">
67+
<i class="fas fa-info-circle"></i>
68+
<span>What is a URL slug?</span>
69+
<i class="fas fa-chevron-down toggle-icon"></i>
70+
</div>
71+
<div class="info-content hidden">
72+
<p>A URL slug is the part that comes at the very end of a URL and is the exact address of a specific page on your website.</p>
73+
<p>For example - in <code>https://example.com/clean-url-slug</code>, "<code>clean-url-slug</code>" is the slug.</p>
74+
<p>Composing a short but descriptive slug for a URL of the web page can positively affect your page's SEO.</p>
75+
</div>
76+
</div>
77+
78+
<div class="footer">
79+
<div class="attribution">
80+
<p>Created by <a href="https://github.com/vulct174" target="_blank">vulct174</a></p>
81+
<p><a href="mailto:vulct.it@gmail.com">vulct.it@gmail.com</a></p>
82+
</div>
83+
</div>
84+
</div>
85+
<script src="popup.js"></script>
86+
</body>
87+
</html>

popup.js

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
document.addEventListener('DOMContentLoaded', function() {
2+
// Elements
3+
const inputString = document.getElementById('inputString');
4+
const dashSeparator = document.getElementById('dashSeparator');
5+
const underscoreSeparator = document.getElementById('underscoreSeparator');
6+
const removeStopWords = document.getElementById('removeStopWords');
7+
const removeNumbers = document.getElementById('removeNumbers');
8+
const outputSlug = document.getElementById('outputSlug');
9+
const slugifyBtn = document.getElementById('slugifyBtn');
10+
const clearBtn = document.getElementById('clearBtn');
11+
const resetBtn = document.getElementById('resetBtn');
12+
const copyBtn = document.getElementById('copyBtn');
13+
const infoToggle = document.querySelector('.info-toggle');
14+
const infoContent = document.querySelector('.info-content');
15+
const toggleIcon = document.querySelector('.toggle-icon');
16+
17+
// Common English stop words
18+
const stopWords = [
19+
'a', 'an', 'the', 'and', 'or', 'but', 'because', 'as', 'at', 'by', 'for',
20+
'with', 'about', 'against', 'between', 'into', 'through', 'during', 'before',
21+
'after', 'above', 'below', 'to', 'from', 'up', 'down', 'in', 'out', 'on', 'off',
22+
'over', 'under', 'again', 'further', 'then', 'once', 'here', 'there', 'when',
23+
'where', 'why', 'how', 'all', 'any', 'both', 'each', 'few', 'more', 'most',
24+
'other', 'some', 'such', 'no', 'nor', 'not', 'only', 'own', 'same', 'so',
25+
'than', 'too', 'very', 'can', 'will', 'just', 'should', 'now', 'is', 'are',
26+
'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had', 'having', 'do',
27+
'does', 'did', 'doing', 'would', 'could', 'should', 'shall', 'may', 'might',
28+
'must', 'of', 'that', 'this', 'these', 'those', 'am', 'i', 'we', 'our', 'ours',
29+
'you', 'your', 'yours', 'he', 'him', 'his', 'she', 'her', 'hers', 'it', 'its',
30+
'they', 'them', 'their', 'theirs', 'what', 'which', 'who', 'whom', 'whose'
31+
];
32+
33+
// Load saved preferences
34+
chrome.storage.local.get(['options'], function(result) {
35+
if (result.options) {
36+
if (result.options.separator === 'underscore') {
37+
underscoreSeparator.checked = true;
38+
}
39+
removeStopWords.checked = result.options.removeStopWords || false;
40+
removeNumbers.checked = result.options.removeNumbers || false;
41+
}
42+
});
43+
44+
// Generate slug function
45+
function generateSlug() {
46+
let text = inputString.value.trim();
47+
48+
if (!text) {
49+
outputSlug.value = '';
50+
return;
51+
}
52+
53+
// Convert to lowercase
54+
text = text.toLowerCase();
55+
56+
// Replace special characters and symbols
57+
text = text.replace(/&/g, ' and ');
58+
text = text.replace(/[]/g, ' euro ');
59+
text = text.replace(/[$]/g, ' dollar ');
60+
text = text.replace(/[£]/g, ' pound ');
61+
text = text.replace(/[¥]/g, ' yen ');
62+
63+
// Handle numbers
64+
if (removeNumbers.checked) {
65+
text = text.replace(/[0-9]/g, '');
66+
}
67+
68+
// Remove stop words if checked
69+
if (removeStopWords.checked) {
70+
let words = text.split(/\s+/);
71+
words = words.filter(word => !stopWords.includes(word));
72+
text = words.join(' ');
73+
}
74+
75+
// Replace all non-alphanumeric characters with spaces
76+
text = text.replace(/[^a-z0-9\s]/g, ' ');
77+
78+
// Remove multiple spaces and trim
79+
text = text.replace(/\s+/g, ' ').trim();
80+
81+
// Replace spaces with separator
82+
const separator = underscoreSeparator.checked ? '_' : '-';
83+
text = text.replace(/\s/g, separator);
84+
85+
// Remove repeated separators
86+
text = text.replace(new RegExp(`[${separator}]+`, 'g'), separator);
87+
88+
// Trim separators from start and end
89+
text = text.replace(new RegExp(`^${separator}|${separator}$`, 'g'), '');
90+
91+
outputSlug.value = text;
92+
93+
// Save preferences
94+
chrome.storage.local.set({
95+
options: {
96+
separator: underscoreSeparator.checked ? 'underscore' : 'dash',
97+
removeStopWords: removeStopWords.checked,
98+
removeNumbers: removeNumbers.checked
99+
}
100+
});
101+
}
102+
103+
// Event listeners
104+
slugifyBtn.addEventListener('click', generateSlug);
105+
106+
// Auto-generate on input change
107+
inputString.addEventListener('input', debounce(generateSlug, 500));
108+
109+
dashSeparator.addEventListener('change', generateSlug);
110+
underscoreSeparator.addEventListener('change', generateSlug);
111+
removeStopWords.addEventListener('change', generateSlug);
112+
removeNumbers.addEventListener('change', generateSlug);
113+
114+
clearBtn.addEventListener('click', function() {
115+
inputString.value = '';
116+
outputSlug.value = '';
117+
inputString.focus();
118+
});
119+
120+
resetBtn.addEventListener('click', function() {
121+
dashSeparator.checked = true;
122+
removeStopWords.checked = false;
123+
removeNumbers.checked = false;
124+
inputString.value = '';
125+
outputSlug.value = '';
126+
inputString.focus();
127+
128+
// Reset saved preferences
129+
chrome.storage.local.set({
130+
options: {
131+
separator: 'dash',
132+
removeStopWords: false,
133+
removeNumbers: false
134+
}
135+
});
136+
});
137+
138+
copyBtn.addEventListener('click', function() {
139+
if (!outputSlug.value) return;
140+
141+
navigator.clipboard.writeText(outputSlug.value).then(function() {
142+
copyBtn.innerHTML = '<i class="fas fa-check"></i>';
143+
copyBtn.classList.add('copy-success');
144+
145+
setTimeout(function() {
146+
copyBtn.innerHTML = '<i class="fas fa-copy"></i>';
147+
copyBtn.classList.remove('copy-success');
148+
}, 1500);
149+
});
150+
});
151+
152+
infoToggle.addEventListener('click', function() {
153+
infoContent.classList.toggle('hidden');
154+
toggleIcon.style.transform = infoContent.classList.contains('hidden') ? 'rotate(0deg)' : 'rotate(180deg)';
155+
});
156+
157+
// Helper functions
158+
function debounce(func, wait) {
159+
let timeout;
160+
return function() {
161+
const context = this;
162+
const args = arguments;
163+
clearTimeout(timeout);
164+
timeout = setTimeout(() => {
165+
func.apply(context, args);
166+
}, wait);
167+
};
168+
}
169+
});

0 commit comments

Comments
 (0)