| name | best-practices |
| description | Apply modern web development best practices for security, compatibility, and code quality. Use when asked to "apply best practices", "security audit", "modernize code", "code quality review", or "check for vulnerabilities". |
| license | MIT |
| metadata | {"author":"web-quality-skills","version":"1.0"} |
Best practices
Modern web development standards based on Lighthouse best practices audits. Covers security, browser
compatibility, and code quality patterns.
Security
HTTPS everywhere
Enforce HTTPS:
<img src="http://example.com/image.jpg">
<script src="http://cdn.example.com/script.js"></script>
<img src="https://example.com/image.jpg">
<script src="https://cdn.example.com/script.js"></script>
<img src="//example.com/image.jpg">
HSTS Header:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content Security Policy (CSP)
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' https://trusted-cdn.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://api.example.com;">
CSP Header (recommended):
Content-Security-Policy:
default-src 'self';
script-src 'self' 'nonce-abc123' https://trusted.com;
style-src 'self' 'nonce-abc123';
img-src 'self' data: https:;
connect-src 'self' https://api.example.com;
frame-ancestors 'self';
base-uri 'self';
form-action 'self';
Using nonces for inline scripts:
<script nonce="abc123">
</script>
Security headers
# Prevent clickjacking
X-Frame-Options: DENY
# Prevent MIME type sniffing
X-Content-Type-Options: nosniff
# Enable XSS filter (legacy browsers)
X-XSS-Protection: 1; mode=block
# Control referrer information
Referrer-Policy: strict-origin-when-cross-origin
# Permissions policy (formerly Feature-Policy)
Permissions-Policy: geolocation=(), microphone=(), camera=()
No vulnerable libraries
npm audit
yarn audit
npm audit fix
npm ls lodash
Keep dependencies updated:
{
"scripts": {
"audit": "npm audit --audit-level=moderate",
"update": "npm update && npm audit fix"
}
}
Known vulnerable patterns to avoid:
Object.assign(target, userInput);
_.merge(target, userInput);
const safeData = JSON.parse(JSON.stringify(userInput));
Input sanitization
element.innerHTML = userInput;
document.write(userInput);
element.textContent = userInput;
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);
Secure cookies
document.cookie = "session=abc123";
Set-Cookie: session=abc123; Secure; HttpOnly; SameSite=Strict; Path=/
Browser compatibility
Doctype declaration
<HTML>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<!DOCTYPE html>
<html lang="en">
Character encoding
<html>
<head>
<title>Page</title>
<meta charset="UTF-8">
</head>
<html>
<head>
<meta charset="UTF-8">
<title>Page</title>
</head>
Viewport meta tag
<head>
<title>Page</title>
</head>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Page</title>
</head>
Feature detection
if (navigator.userAgent.includes('Chrome')) {
}
if ('IntersectionObserver' in window) {
} else {
}
@supports (display: grid) {
.container {
display: grid;
}
}
@supports not (display: grid) {
.container {
display: flex;
}
}
Polyfills (when needed)
<script>
if (!('fetch' in window)) {
document.write('<script src="/polyfills/fetch.js"><\/script>');
}
</script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=fetch,IntersectionObserver"></script>
Deprecated APIs
Avoid these
document.write('<script src="..."></script>');
const script = document.createElement('script');
script.src = '...';
document.head.appendChild(script);
const xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
const response = await fetch(url);
<html manifest="cache.manifest">
// ✅ Service Workers
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
Event listener passive
element.addEventListener('touchstart', handler);
element.addEventListener('wheel', handler);
element.addEventListener('touchstart', handler, { passive: true });
element.addEventListener('wheel', handler, { passive: true });
element.addEventListener('touchstart', handler, { passive: false });
Console & errors
No console errors
console.log('Debug info');
throw new Error('Unhandled');
try {
riskyOperation();
} catch (error) {
errorTracker.captureException(error);
showErrorMessage('Something went wrong. Please try again.');
}
Error boundaries (React)
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, info) {
errorTracker.captureException(error, { extra: info });
}
render() {
if (this.state.hasError) {
return <FallbackUI />;
}
return this.props.children;
}
}
<ErrorBoundary>
<App />
</ErrorBoundary>
Global error handler
window.addEventListener('error', (event) => {
errorTracker.captureException(event.error);
});
window.addEventListener('unhandledrejection', (event) => {
errorTracker.captureException(event.reason);
});
Source maps
Production configuration
module.exports = {
devtool: 'source-map',
};
module.exports = {
devtool: 'hidden-source-map',
};
module.exports = {
devtool: process.env.NODE_ENV === 'production' ? false : 'source-map',
};
Performance best practices
Avoid blocking patterns
<script src="heavy-library.js"></script>
<script defer src="heavy-library.js"></script>
@import url('other-styles.css');
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="other-styles.css">
Efficient event handlers
items.forEach(item => {
item.addEventListener('click', handleClick);
});
container.addEventListener('click', (e) => {
if (e.target.matches('.item')) {
handleClick(e);
}
});
Memory management
const handler = () => { };
window.addEventListener('resize', handler);
const handler = () => { };
window.addEventListener('resize', handler);
window.removeEventListener('resize', handler);
const controller = new AbortController();
window.addEventListener('resize', handler, { signal: controller.signal });
controller.abort();
Code quality
Valid HTML
<div id="header">
<div id="header">
<ul>
<div>Item</div>
</ul>
<a href="/"><button>Click</button></a>
<header id="site-header">
</header>
<ul>
<li>Item</li>
</ul>
<a href="/" class="button">Click</a>
Semantic HTML
<div class="header">
<div class="nav">
<div class="nav-item">Home</div>
</div>
</div>
<div class="main">
<div class="article">
<div class="title">Headline</div>
</div>
</div>
<header>
<nav>
<a href="/">Home</a>
</nav>
</header>
<main>
<article>
<h1>Headline</h1>
</article>
</main>
Image aspect ratios
<img src="photo.jpg" width="300" height="100">
<img src="photo.jpg" width="300" height="225">
<img src="photo.jpg" style="width: 300px; height: 200px; object-fit: cover;">
Permissions & privacy
Request permissions properly
navigator.geolocation.getCurrentPosition(success, error);
findNearbyButton.addEventListener('click', async () => {
if (await showPermissionExplanation()) {
navigator.geolocation.getCurrentPosition(success, error);
}
});
Permissions policy
<meta http-equiv="Permissions-Policy"
content="geolocation=(), camera=(), microphone=()">
<meta http-equiv="Permissions-Policy"
content="geolocation=(self 'https://maps.example.com')">
Audit checklist
Security (critical)
Compatibility
Code quality
UX
Tools
References