CDN & Browser
Direct browser usage with CDN links, no-build setups, and vanilla HTML/JavaScript integration
Use Glin-Profanity directly in the browser without build tools, perfect for prototyping, static sites, and simple integrations.
CDN Installation
ES Modules (Recommended)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Glin-Profanity Browser Demo</title>
</head>
<body>
<div id="app">
<h2>Profanity Filter Demo</h2>
<textarea
id="textInput"
placeholder="Type your message here..."
rows="4"
cols="50"
></textarea>
<br><br>
<button onclick="checkProfanity()">Check Content</button>
<button onclick="clearResults()">Clear</button>
<div id="results" style="margin-top: 20px;"></div>
</div>
<script type="module">
import { checkProfanity, isWordProfane } from 'https://cdn.skypack.dev/glin-profanity';
// Make functions global for onclick handlers
window.checkProfanity = async function() {
const text = document.getElementById('textInput').value;
const resultsDiv = document.getElementById('results');
if (!text.trim()) {
resultsDiv.innerHTML = '<p style="color: orange;">Please enter some text</p>';
return;
}
try {
const result = checkProfanity(text, {
languages: ['english'],
enableContextAware: true,
autoReplace: true
});
displayResults(result);
} catch (error) {
resultsDiv.innerHTML = `<p style="color: red;">Error: ${error.message}</p>`;
}
};
window.clearResults = function() {
document.getElementById('textInput').value = '';
document.getElementById('results').innerHTML = '';
};
function displayResults(result) {
const resultsDiv = document.getElementById('results');
const isClean = !result.containsProfanity;
const statusColor = isClean ? 'green' : 'red';
const status = isClean ? 'Clean' : 'Contains Profanity';
let html = `
<div style="border: 1px solid ${statusColor}; padding: 15px; border-radius: 5px;">
<h3 style="color: ${statusColor}; margin-top: 0;">Status: ${status}</h3>
`;
if (!isClean) {
html += `
<p><strong>Violations:</strong> ${result.profaneWords.join(', ')}</p>
`;
if (result.processedText) {
html += `
<p><strong>Clean Version:</strong></p>
<div style="background: #f5f5f5; padding: 10px; border-radius: 3px;">
${result.processedText}
</div>
`;
}
}
html += '</div>';
resultsDiv.innerHTML = html;
}
</script>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Glin-Profanity Global</title>
</head>
<body>
<h2>Real-time Profanity Checking</h2>
<form id="commentForm">
<label for="comment">Comment:</label><br>
<textarea
id="comment"
name="comment"
rows="4"
cols="50"
placeholder="Write your comment..."
></textarea>
<br><br>
<div id="feedback" style="margin: 10px 0;"></div>
<button type="submit" id="submitBtn">Submit Comment</button>
</form>
<!-- Load Glin-Profanity as global variable -->
<script src="https://cdn.skypack.dev/glin-profanity?min" crossorigin></script>
<script>
// Use global GlinProfanity object
const { checkProfanity } = window.GlinProfanity || {};
const commentTextarea = document.getElementById('comment');
const feedbackDiv = document.getElementById('feedback');
const submitBtn = document.getElementById('submitBtn');
const form = document.getElementById('commentForm');
let checkTimeout;
// Real-time checking as user types
commentTextarea.addEventListener('input', function() {
clearTimeout(checkTimeout);
checkTimeout = setTimeout(() => {
checkContent(this.value);
}, 500); // Debounce for 500ms
});
function checkContent(text) {
if (!text.trim()) {
feedbackDiv.innerHTML = '';
submitBtn.disabled = false;
return;
}
try {
const result = checkProfanity(text, {
languages: ['english', 'spanish'],
enableContextAware: true
});
updateFeedback(result);
} catch (error) {
console.error('Profanity check failed:', error);
feedbackDiv.innerHTML = '<span style="color: orange;">⚠️ Unable to check content</span>';
}
}
function updateFeedback(result) {
const isClean = !result.containsProfanity;
if (isClean) {
feedbackDiv.innerHTML = '<span style="color: green;">✅ Content looks good</span>';
submitBtn.disabled = false;
} else {
feedbackDiv.innerHTML = `
<span style="color: red;">❌ Please review your content</span>
<br><small>Issues detected: ${result.profaneWords.join(', ')}</small>
`;
submitBtn.disabled = true;
}
}
// Form submission handling
form.addEventListener('submit', function(e) {
e.preventDefault();
const text = commentTextarea.value;
const result = checkProfanity(text);
if (result.containsProfanity) {
alert('Please remove inappropriate language before submitting.');
return;
}
// Simulate form submission
alert('Comment submitted successfully!');
form.reset();
feedbackDiv.innerHTML = '';
submitBtn.disabled = false;
});
</script>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dynamic Import Example</title>
</head>
<body>
<h2>Chat Application with Profanity Filter</h2>
<div id="chatBox" style="border: 1px solid #ccc; height: 300px; overflow-y: auto; padding: 10px; margin-bottom: 10px;">
<div class="message">Welcome to the chat! Messages are automatically filtered.</div>
</div>
<div>
<input
type="text"
id="messageInput"
placeholder="Type your message..."
style="width: 70%;"
>
<button onclick="sendMessage()" style="width: 25%;">Send</button>
</div>
<div id="status" style="margin-top: 10px; height: 20px;"></div>
<script>
let profanityChecker = null;
// Lazy load profanity checker
async function loadProfanityChecker() {
if (!profanityChecker) {
const statusDiv = document.getElementById('status');
statusDiv.innerHTML = 'Loading profanity filter...';
try {
const module = await import('https://cdn.skypack.dev/glin-profanity');
profanityChecker = module.checkProfanity;
statusDiv.innerHTML = 'Profanity filter ready ✅';
setTimeout(() => statusDiv.innerHTML = '', 2000);
} catch (error) {
statusDiv.innerHTML = 'Failed to load profanity filter ❌';
console.error('Failed to load profanity checker:', error);
}
}
return profanityChecker;
}
async function sendMessage() {
const input = document.getElementById('messageInput');
const message = input.value.trim();
if (!message) return;
// Load profanity checker if not already loaded
const checker = await loadProfanityChecker();
if (!checker) {
addMessageToChat('System: Unable to verify message safety', 'system-error');
return;
}
try {
const result = checker(message, {
enableContextAware: true,
autoReplace: true,
languages: ['english']
});
let displayMessage = message;
let messageClass = 'user-message';
if (result.containsProfanity) {
if (result.processedText) {
displayMessage = result.processedText;
messageClass = 'filtered-message';
addMessageToChat(`System: Message was automatically filtered`, 'system-info');
} else {
addMessageToChat('System: Message blocked due to inappropriate content', 'system-warning');
input.value = '';
return;
}
}
addMessageToChat(`You: ${displayMessage}`, messageClass);
input.value = '';
} catch (error) {
console.error('Message filtering failed:', error);
addMessageToChat('System: Message could not be verified', 'system-error');
}
}
function addMessageToChat(message, className = '') {
const chatBox = document.getElementById('chatBox');
const messageDiv = document.createElement('div');
messageDiv.className = `message ${className}`;
messageDiv.textContent = message;
// Style different message types
switch (className) {
case 'system-error':
messageDiv.style.color = 'red';
messageDiv.style.fontStyle = 'italic';
break;
case 'system-warning':
messageDiv.style.color = 'orange';
messageDiv.style.fontStyle = 'italic';
break;
case 'system-info':
messageDiv.style.color = 'blue';
messageDiv.style.fontStyle = 'italic';
break;
case 'filtered-message':
messageDiv.style.backgroundColor = '#fff3cd';
messageDiv.style.padding = '5px';
messageDiv.style.borderRadius = '3px';
break;
}
chatBox.appendChild(messageDiv);
chatBox.scrollTop = chatBox.scrollHeight;
}
// Allow Enter key to send message
document.getElementById('messageInput').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
sendMessage();
}
});
</script>
</body>
</html>CDN Providers
Primary CDNs
Skypack (Recommended for ES Modules)
<!-- Latest version -->
<script type="module">
import { checkProfanity } from 'https://cdn.skypack.dev/glin-profanity';
</script>
<!-- Specific version -->
<script type="module">
import { checkProfanity } from 'https://cdn.skypack.dev/glin-profanity@2.3.2';
</script>
<!-- Optimized build -->
<script type="module">
import { checkProfanity } from 'https://cdn.skypack.dev/glin-profanity?optimize';
</script>Features:
- ✅ Native ES modules support
- ✅ Automatic TypeScript definitions
- ✅ Tree-shaking optimization
- ✅ HTTP/2 optimized
- ✅ Built-in caching
jsDelivr (Global Distribution)
<!-- Latest version -->
<script src="https://cdn.jsdelivr.net/npm/glin-profanity@latest/dist/index.umd.js"></script>
<!-- Specific version -->
<script src="https://cdn.jsdelivr.net/npm/glin-profanity@2.3.2/dist/index.umd.js"></script>
<!-- Minified -->
<script src="https://cdn.jsdelivr.net/npm/glin-profanity@2.3.2/dist/index.umd.min.js"></script>
<!-- ES Module -->
<script type="module">
import { checkProfanity } from 'https://cdn.jsdelivr.net/npm/glin-profanity@2.3.2/dist/index.esm.js';
</script>Features:
- ✅ Global CDN network
- ✅ Multiple format support
- ✅ Version pinning
- ✅ China-friendly
- ✅ GitHub integration
UNPKG (npm Mirror)
<!-- Latest version -->
<script src="https://unpkg.com/glin-profanity/dist/index.umd.js"></script>
<!-- Specific version -->
<script src="https://unpkg.com/glin-profanity@2.3.2/dist/index.umd.js"></script>
<!-- ES Module -->
<script type="module">
import { checkProfanity } from 'https://unpkg.com/glin-profanity@2.3.2/dist/index.esm.js';
</script>
<!-- Browse package contents -->
<!-- Visit: https://unpkg.com/glin-profanity/ -->Features:
- ✅ Direct npm package serving
- ✅ Package exploration
- ✅ Version selection
- ✅ Automatic redirects
- ✅ Simple URLs
No-Build Integration
Static HTML Pages
Create a basic HTML file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Content Moderation Tool</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
line-height: 1.6;
}
.container {
background: #f9f9f9;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
}
.clean { border-left: 4px solid green; }
.violation { border-left: 4px solid red; }
.warning { border-left: 4px solid orange; }
textarea {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
button {
background: #007cba;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
margin: 5px;
}
button:hover {
background: #005a87;
}
button:disabled {
background: #ccc;
cursor: not-allowed;
}
.config-panel {
background: white;
padding: 15px;
border: 1px solid #ddd;
border-radius: 4px;
margin: 10px 0;
}
.config-panel label {
display: block;
margin: 10px 0 5px 0;
font-weight: bold;
}
.config-panel select,
.config-panel input {
margin: 5px 0;
padding: 5px;
}
</style>
</head>
<body>
<h1>📝 Content Moderation Tool</h1>
<p>Test profanity detection with real-time feedback and customizable settings.</p>
<div class="config-panel">
<h3>⚙️ Configuration</h3>
<label for="languages">Languages:</label>
<select id="languages" multiple size="3">
<option value="english" selected>English</option>
<option value="spanish">Spanish</option>
<option value="french">French</option>
<option value="german">German</option>
<option value="italian">Italian</option>
</select>
<label>
<input type="checkbox" id="contextAware" checked>
Enable Context-Aware Filtering
</label>
<label>
<input type="checkbox" id="autoReplace">
Auto-Replace Profanity
</label>
<label for="severity">Minimum Severity:</label>
<select id="severity">
<option value="MILD">Mild</option>
<option value="MODERATE" selected>Moderate</option>
<option value="SEVERE">Severe</option>
</select>
</div>
<div>
<label for="textInput"><strong>📝 Content to Check:</strong></label>
<textarea
id="textInput"
rows="6"
placeholder="Type or paste content here to check for profanity..."
></textarea>
</div>
<div>
<button onclick="checkContent()">🔍 Check Content</button>
<button onclick="clearAll()">🗑️ Clear All</button>
<button onclick="loadExample()">📄 Load Example</button>
</div>
<div id="results"></div>
<script type="module">
import { checkProfanity, isWordProfane } from 'https://cdn.skypack.dev/glin-profanity';
// Make functions available globally
window.checkContent = checkContent;
window.clearAll = clearAll;
window.loadExample = loadExample;
function getConfiguration() {
const languageSelect = document.getElementById('languages');
const selectedLanguages = Array.from(languageSelect.selectedOptions)
.map(option => option.value);
return {
languages: selectedLanguages.length > 0 ? selectedLanguages : ['english'],
enableContextAware: document.getElementById('contextAware').checked,
autoReplace: document.getElementById('autoReplace').checked,
severityLevels: true
};
}
function checkContent() {
const text = document.getElementById('textInput').value.trim();
const resultsDiv = document.getElementById('results');
if (!text) {
showResult('Please enter some content to check.', 'warning');
return;
}
try {
const config = getConfiguration();
const result = checkProfanity(text, config);
displayDetailedResults(result, config);
} catch (error) {
showResult(`Error: ${error.message}`, 'violation');
}
}
function displayDetailedResults(result, config) {
const isClean = !result.containsProfanity;
const className = isClean ? 'clean' : 'violation';
const status = isClean ? '✅ Content is clean' : '❌ Issues detected';
let html = `
<div class="container ${className}">
<h3>${status}</h3>
`;
if (!isClean) {
html += `
<p><strong>Violations found:</strong> ${result.profaneWords.join(', ')}</p>
`;
if (result.severityMap) {
html += '<p><strong>Severity breakdown:</strong></p><ul>';
for (const [word, severity] of Object.entries(result.severityMap)) {
html += `<li>${word}: ${severity}</li>`;
}
html += '</ul>';
}
if (config.autoReplace && result.processedText) {
html += `
<p><strong>Auto-replaced version:</strong></p>
<div style="background: white; padding: 10px; border: 1px solid #ddd; border-radius: 4px;">
${result.processedText}
</div>
`;
}
}
if (result.contextScore !== undefined) {
html += `
<p><strong>Context confidence:</strong> ${(result.contextScore * 100).toFixed(1)}%</p>
`;
}
html += `
<p><strong>Languages checked:</strong> ${config.languages.join(', ')}</p>
<p><strong>Total words analyzed:</strong> ${text.split(/\s+/).length}</p>
</div>
`;
document.getElementById('results').innerHTML = html;
}
function showResult(message, type = 'clean') {
document.getElementById('results').innerHTML = `
<div class="container ${type}">
<p>${message}</p>
</div>
`;
}
function clearAll() {
document.getElementById('textInput').value = '';
document.getElementById('results').innerHTML = '';
}
function loadExample() {
const examples = [
"This is a perfectly clean message with no issues.",
"That movie was absolutely amazing and fantastic!",
"I disagree with your opinion, but I respect your viewpoint.",
"The food at that restaurant was terrible and disappointing.",
"This gaming tutorial is really helpful for beginners."
];
const randomExample = examples[Math.floor(Math.random() * examples.length)];
document.getElementById('textInput').value = randomExample;
checkContent();
}
// Auto-check on typing (debounced)
let checkTimeout;
document.getElementById('textInput').addEventListener('input', function() {
clearTimeout(checkTimeout);
checkTimeout = setTimeout(() => {
if (this.value.trim()) {
checkContent();
} else {
document.getElementById('results').innerHTML = '';
}
}, 1000);
});
</script>
</body>
</html>Open the file in any modern browser (Chrome, Firefox, Safari, Edge)
Test the functionality:
- Type content in the textarea
- Adjust configuration settings
- Click "Load Example" to test with sample content
- Try different languages and settings
WordPress Integration
<!-- Add to WordPress theme functions.php -->
<script>
function glin_profanity_shortcode($atts) {
$atts = shortcode_atts(array(
'placeholder' => 'Enter your comment...',
'languages' => 'english',
'button_text' => 'Check Content'
), $atts);
$languages_array = "'" . str_replace(',', "','", $atts['languages']) . "'";
return "
<div class='glin-profanity-widget'>
<textarea id='glin-text-input' placeholder='{$atts['placeholder']}' rows='4' style='width: 100%; margin-bottom: 10px;'></textarea>
<button onclick='checkProfanityContent()' style='padding: 10px 20px; background: #0073aa; color: white; border: none; border-radius: 3px; cursor: pointer;'>{$atts['button_text']}</button>
<div id='glin-results' style='margin-top: 15px;'></div>
</div>
<script type='module'>
import { checkProfanity } from 'https://cdn.skypack.dev/glin-profanity';
window.checkProfanityContent = async function() {
const text = document.getElementById('glin-text-input').value;
const resultsDiv = document.getElementById('glin-results');
if (!text.trim()) {
resultsDiv.innerHTML = '<p style=\"color: orange;\">Please enter some text to check.</p>';
return;
}
try {
const result = checkProfanity(text, {
languages: [{$languages_array}],
enableContextAware: true
});
const isClean = !result.containsProfanity;
const statusColor = isClean ? 'green' : 'red';
const status = isClean ? 'Content approved ✅' : 'Content needs review ❌';
let html = `<div style=\"border: 1px solid $statusColor; padding: 10px; border-radius: 5px;\">`;
html += `<p style=\"color: $statusColor; font-weight: bold;\">$status</p>`;
if (!isClean) {
html += `<p>Issues detected: $result.profaneWords.join(', ')</p>`;
}
html += '</div>';
resultsDiv.innerHTML = html;
} catch (error) {
resultsDiv.innerHTML = `<p style=\"color: red;\">Error checking content: $error.message</p>`;
}
};
</script>
";
}
add_shortcode('glin_profanity', 'glin_profanity_shortcode');
</script>
<!-- Usage in WordPress posts/pages -->
[glin_profanity placeholder="Write your review..." languages="english,spanish" button_text="Validate Content"]Vanilla JavaScript SPA
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Comment System SPA</title>
<style>
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
.comment { background: #f9f9f9; padding: 15px; margin: 10px 0; border-radius: 5px; }
.comment.moderated { background: #fff3cd; border-left: 4px solid #ffc107; }
.comment-form { background: white; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
.form-group { margin: 15px 0; }
.form-group label { display: block; margin-bottom: 5px; font-weight: bold; }
.form-group input, .form-group textarea { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 3px; }
.btn { padding: 10px 20px; background: #007cba; color: white; border: none; border-radius: 3px; cursor: pointer; }
.btn:disabled { background: #ccc; cursor: not-allowed; }
.error { color: red; margin: 5px 0; }
.success { color: green; margin: 5px 0; }
</style>
</head>
<body>
<h1>💬 Comment System</h1>
<div class="comment-form">
<h3>Add a Comment</h3>
<form id="commentForm">
<div class="form-group">
<label for="authorName">Name:</label>
<input type="text" id="authorName" required>
</div>
<div class="form-group">
<label for="commentText">Comment:</label>
<textarea id="commentText" rows="4" required placeholder="Share your thoughts..."></textarea>
<div id="realTimeCheck"></div>
</div>
<button type="submit" class="btn" id="submitBtn">Post Comment</button>
<div id="formMessages"></div>
</form>
</div>
<div id="commentsContainer">
<h3>Comments</h3>
<div id="commentsList"></div>
</div>
<script type="module">
import { checkProfanity } from 'https://cdn.skypack.dev/glin-profanity';
// Application state
const state = {
comments: [],
currentCheckResult: null
};
// Initialize app
document.addEventListener('DOMContentLoaded', function() {
loadSampleComments();
setupEventListeners();
});
function setupEventListeners() {
const form = document.getElementById('commentForm');
const commentText = document.getElementById('commentText');
// Real-time content checking
let checkTimeout;
commentText.addEventListener('input', function() {
clearTimeout(checkTimeout);
checkTimeout = setTimeout(() => {
if (this.value.trim()) {
checkContentRealTime(this.value);
} else {
document.getElementById('realTimeCheck').innerHTML = '';
}
}, 500);
});
// Form submission
form.addEventListener('submit', function(e) {
e.preventDefault();
handleCommentSubmission();
});
}
async function checkContentRealTime(text) {
const checkDiv = document.getElementById('realTimeCheck');
const submitBtn = document.getElementById('submitBtn');
try {
const result = checkProfanity(text, {
languages: ['english'],
enableContextAware: true,
autoReplace: true
});
state.currentCheckResult = result;
if (result.containsProfanity) {
checkDiv.innerHTML = `
<div class="error">
⚠️ Content may need review: ${result.profaneWords.join(', ')}
</div>
`;
submitBtn.disabled = true;
} else {
checkDiv.innerHTML = '<div class="success">✅ Content looks good</div>';
submitBtn.disabled = false;
}
} catch (error) {
checkDiv.innerHTML = '<div class="error">Unable to verify content</div>';
console.error('Content check failed:', error);
}
}
async function handleCommentSubmission() {
const authorName = document.getElementById('authorName').value.trim();
const commentText = document.getElementById('commentText').value.trim();
const messagesDiv = document.getElementById('formMessages');
if (!authorName || !commentText) {
messagesDiv.innerHTML = '<div class="error">Please fill in all fields</div>';
return;
}
try {
// Final profanity check
const result = checkProfanity(commentText, {
enableContextAware: true,
autoReplace: true
});
let finalText = commentText;
let isModerated = false;
if (result.containsProfanity) {
if (result.processedText) {
// Auto-moderate with replacement
finalText = result.processedText;
isModerated = true;
} else {
// Block comment
messagesDiv.innerHTML = `
<div class="error">
Comment blocked due to inappropriate content: ${result.profaneWords.join(', ')}
</div>
`;
return;
}
}
// Add comment to state
const comment = {
id: Date.now(),
author: authorName,
text: finalText,
isModerated: isModerated,
timestamp: new Date().toLocaleString(),
originalViolations: isModerated ? result.profaneWords : []
};
state.comments.unshift(comment);
renderComments();
// Reset form
document.getElementById('commentForm').reset();
document.getElementById('realTimeCheck').innerHTML = '';
document.getElementById('submitBtn').disabled = false;
messagesDiv.innerHTML = isModerated
? '<div class="success">Comment posted (content was auto-moderated)</div>'
: '<div class="success">Comment posted successfully!</div>';
setTimeout(() => messagesDiv.innerHTML = '', 3000);
} catch (error) {
messagesDiv.innerHTML = '<div class="error">Failed to post comment. Please try again.</div>';
console.error('Comment submission failed:', error);
}
}
function renderComments() {
const listDiv = document.getElementById('commentsList');
if (state.comments.length === 0) {
listDiv.innerHTML = '<p>No comments yet. Be the first to comment!</p>';
return;
}
const html = state.comments.map(comment => `
<div class="comment ${comment.isModerated ? 'moderated' : ''}">
<strong>${comment.author}</strong>
<small style="color: #666; margin-left: 10px;">${comment.timestamp}</small>
${comment.isModerated ? '<span style="color: #856404; font-size: 12px; margin-left: 10px;">[Moderated]</span>' : ''}
<p>${comment.text}</p>
${comment.isModerated && comment.originalViolations.length > 0 ?
`<small style="color: #856404;">Original content contained: ${comment.originalViolations.join(', ')}</small>` : ''}
</div>
`).join('');
listDiv.innerHTML = html;
}
function loadSampleComments() {
state.comments = [
{
id: 1,
author: 'Alice',
text: 'This is a great article! Thanks for sharing.',
isModerated: false,
timestamp: new Date(Date.now() - 3600000).toLocaleString(),
originalViolations: []
},
{
id: 2,
author: 'Bob',
text: 'I completely disagree with this viewpoint, but I appreciate the discussion.',
isModerated: false,
timestamp: new Date(Date.now() - 7200000).toLocaleString(),
originalViolations: []
}
];
renderComments();
}
</script>
</body>
</html>Performance Considerations
Bundle Size Optimization
Bundle Size
Full Package: ~850KB (includes 23 language dictionaries)
Core Only: ~120KB (basic functionality)
Single Language: ~180KB (core + one language)
<script type="module">
// Load only what you need
import { checkProfanity } from 'https://cdn.skypack.dev/glin-profanity/core';
// Or use dynamic imports for lazy loading
async function loadProfanityChecker() {
const { checkProfanity } = await import('https://cdn.skypack.dev/glin-profanity');
return checkProfanity;
}
// Use with reduced configuration for smaller bundle
const result = checkProfanity(text, {
languages: ['english'], // Single language
enableContextAware: false, // Disable NLP features
severityLevels: false // Disable severity classification
});
</script>Caching Strategy
<script>
// Register service worker for CDN caching
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
</script>
<script>
// sw.js - Service Worker
const CACHE_NAME = 'glin-profanity-v1';
const CDN_URLS = [
'https://cdn.skypack.dev/glin-profanity',
'https://cdn.jsdelivr.net/npm/glin-profanity@2.3.2/dist/index.umd.min.js'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(CDN_URLS))
);
});
self.addEventListener('fetch', event => {
if (CDN_URLS.some(url => event.request.url.includes(url))) {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
}
});
</script>Browser Compatibility
| Browser | ES Modules | Import Maps | Dynamic Import | Support Level |
|---|---|---|---|---|
| Chrome 89+ | ✅ | ✅ | ✅ | Full |
| Firefox 89+ | ✅ | ✅ | ✅ | Full |
| Safari 14+ | ✅ | ✅ | ✅ | Full |
| Edge 89+ | ✅ | ✅ | ✅ | Full |
| Chrome 61-88 | ✅ | ❌ | ✅ | Partial |
| Firefox 60-88 | ✅ | ❌ | ✅ | Partial |
| IE 11 | ❌ | ❌ | ❌ | Polyfill needed |
Legacy Browser Support
<script>
// Feature detection and fallback
if (!('import' in document.createElement('script'))) {
// Load UMD version for older browsers
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/glin-profanity@2.3.2/dist/index.umd.min.js';
script.onload = function() {
// Use global GlinProfanity object
const { checkProfanity } = window.GlinProfanity;
window.profanityChecker = checkProfanity;
};
document.head.appendChild(script);
} else {
// Modern browsers - use ES modules
import('https://cdn.skypack.dev/glin-profanity')
.then(module => {
window.profanityChecker = module.checkProfanity;
});
}
</script>Next Steps
After browser integration:
- Configuration: Explore Configuration Options for customizing behavior
- Advanced Features: Learn about Context-Aware Filtering and Severity Levels
- Production: Consider Framework Integration for larger applications
- API Reference: Complete method documentation in API Reference
Development Tip: For production applications, consider using a build tool like Vite, Webpack, or Parcel instead of CDN links for better performance, tree-shaking, and dependency management.