Google Lighthouse scores your website on four metrics: Performance, Accessibility, Best Practices, and SEO. Most developers focus on Performance and ignore the rest. That's a mistake.
In my previous articles, I covered Performance optimization in detail—how to achieve 100/100 on PageSpeed and why professional websites often score poorly. Those techniques handle the Performance pillar.
This guide completes the picture. We'll cover the three remaining pillars: SEO, Accessibility, and Best Practices. Together with the Performance techniques from the earlier articles, you'll have everything needed to achieve 100/100 across all four metrics.
Why all four matter:
- Performance affects load times and user experience
- SEO determines whether Google can find and rank your site
- Accessibility ensures everyone can use your site, including people with disabilities
- Best Practices covers security, modern standards, and technical correctness
On every demo site I've built, SEO, Accessibility, and Best Practices score 100/100—no exceptions. Performance occasionally dips a few points on mobile (Nuxt overhead, Cloudflare scripts), but typically hits 100 as well. Seven out of eight scores are always perfect; often all eight are. This guide documents exactly how.
SEO: Making Your Site Discoverable
The Foundation Files
Before Google indexes your site, it checks two files: robots.txt and sitemap.xml. Missing these doesn't break your site, but it slows discovery significantly.
robots.txt tells crawlers which pages to index. Place it at your site root:
User-agent: *
Allow: /
Sitemap: https://yoursite.com/sitemap.xml
Common mistakes:
- Using
Disallow: /(blocks all crawlers—your site won't be indexed) - Forgetting the sitemap reference
- Wrong file location (must be at root, not in a subfolder)
sitemap.xml maps all your pages. For small sites, write it manually:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://yoursite.com/</loc>
<lastmod>2025-12-07</lastmod>
<priority>1.0</priority>
</url>
<url>
<loc>https://yoursite.com/about</loc>
<priority>0.8</priority>
</url>
</urlset>
Strategy tip: Less is more. Don't index everything. Your Terms of Service page doesn't need to rank.
Meta Tags That Matter
Search engines and social platforms read specific HTML tags. Missing these means broken-looking links when shared.
Essential tags in your <head>:
<!-- Page basics -->
<html lang="en">
<title>Your Page Title - Under 60 Characters</title>
<meta name="description" content="150-160 characters. Shows in search results.">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" href="https://yoursite.com/page-url">
<!-- Open Graph (Facebook, LinkedIn, Slack) -->
<meta property="og:title" content="Your Page Title">
<meta property="og:description" content="Same as meta description">
<meta property="og:url" content="https://yoursite.com/page-url">
<meta property="og:image" content="https://yoursite.com/og-image.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:type" content="website">
<!-- Twitter/X -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Your Page Title">
<meta name="twitter:image" content="https://yoursite.com/og-image.jpg">
Common mistakes:
- Title over 60 characters (Google truncates with "...")
- Missing OG image dimensions (Facebook won't show preview)
- Forgetting the
langattribute on<html>(fails Lighthouse accessibility check)
Structured Data (JSON-LD)
Structured data tells Google what type of content you have, enabling rich results in search:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Your Company",
"url": "https://yoursite.com",
"logo": "https://yoursite.com/logo.png",
"sameAs": [
"https://twitter.com/yourcompany",
"https://linkedin.com/company/yourcompany"
]
}
</script>
Other useful types: Person (portfolios), LocalBusiness (physical locations), Article (blog posts), FAQPage (can display directly in search results).
Testing: Use Google's Rich Results Test to validate your JSON-LD.
Cloudflare Users: Check Scrape Shield
If you're on Cloudflare, check your Scrape Shield settings. The default "Email Address Obfuscation" injects a 500ms render-blocking script into every page. I lost 8 points on multiple demos before catching this.
Fix: Security → Scrape Shield → Disable "Email Address Obfuscation"
Accessibility: Building for Everyone
Accessibility isn't charity—it's good engineering. An accessible site works better for everyone: keyboard users, screen reader users, people with slow connections, and users on mobile devices.
Semantic HTML Structure
Lighthouse checks for proper HTML landmarks. Missing these fails the accessibility audit.
Required landmarks:
<header>
<nav><!-- Navigation here --></nav>
</header>
<main>
<!-- All primary content MUST be inside <main> -->
<article>
<h1>Page Title</h1>
<!-- Content -->
</article>
</main>
<footer>
<!-- Footer content -->
</footer>
The <main> element is critical. Lighthouse specifically checks for it. Screen readers use it to skip navigation and jump directly to content.
Heading Hierarchy
Use one <h1> per page. Follow logical order: h1 → h2 → h3. Never skip levels (no h1 → h3).
Why this matters: Screen reader users navigate by headings. Skipped levels confuse navigation.
Color Contrast
WCAG AA requires minimum contrast ratios:
- Normal text (< 18px): 4.5:1 contrast ratio
- Large text (≥ 18px or ≥ 14px bold): 3:1 contrast ratio
- UI components: 3:1 contrast ratio
Links require special attention. Color alone isn't sufficient to distinguish links from surrounding text. Use underlines or other visual indicators.
Testing: Chrome DevTools → Inspect element → Accessibility tab shows contrast ratios. Or use WebAIM Contrast Checker.
Image Alt Text
Every image needs an alt attribute:
<!-- Meaningful image: describe the content -->
<img src="team-photo.jpg" alt="Team at the 2025 developer conference">
<!-- Decorative image: use empty alt (not missing) -->
<img src="decorative-line.svg" alt="">
Common mistakes:
- Missing alt attributes entirely (fails audit)
- Using "image of..." prefix (redundant)
- Empty alt on meaningful images
Form Accessibility
Every input needs an associated label:
<!-- Correct: label linked via 'for' attribute -->
<label for="email">Email Address</label>
<input type="email" id="email" name="email">
Interactive Elements
Icon-only buttons need ARIA labels:
<!-- Icon button: needs aria-label -->
<button aria-label="Open menu">
<svg><!-- hamburger icon --></svg>
</button>
<!-- Decorative icons: hide from screen readers -->
<span aria-hidden="true">★</span> 4.8 rating
Keyboard navigation: All interactive elements must be reachable via Tab key. Focus indicators must be visible.
Best Practices: Security and Standards
Best Practices covers security, modern web standards, and technical correctness. Most failures here are easy to fix.
HTTPS Everywhere
Serve all content over HTTPS. No mixed content (HTTP resources on HTTPS pages).
Safe External Links
External links should use rel="noopener":
<a href="https://external-site.com" target="_blank" rel="noopener">
External Link
</a>
This prevents the external page from accessing your window.opener object—a security vulnerability.
No Console Errors
Open DevTools Console before deploying. Fix all errors. Common culprits:
- Missing resources (404s)
- JavaScript errors
- Deprecated API warnings
Zero tolerance: Any console error can fail the Best Practices audit.
Image Aspect Ratios
Images need explicit dimensions to prevent layout shift:
<img src="photo.jpg" width="1200" height="800" alt="Description">
Modern Standards
Avoid deprecated APIs:
- Use
fetch()instead ofXMLHttpRequest - Use
addEventListener()instead of inlineonclick - Never use
document.write()
Icons and Favicons
The finishing touches:
Required files:
-
favicon.ico(32×32, legacy browsers) -
favicon.svg(scalable, modern browsers) -
apple-touch-icon.png(180×180, iOS) -
icon-192.pngandicon-512.png(Android, PWA)
HTML tags:
<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/manifest.json">
Tool: RealFaviconGenerator.net generates all sizes from one image.
The Complete Checklist
Performance (covered in Articles 1 & 2):
- ✅ Critical CSS inlining
- ✅ AVIF/WebP images with explicit dimensions
- ✅ Deferred JavaScript loading
- ✅ Zero layout shift
SEO:
- ✅ robots.txt and sitemap.xml
- ✅ Title, description, canonical URL
- ✅ Open Graph and Twitter meta tags
- ✅ Structured data (JSON-LD)
- ✅ Google Search Console verification
Accessibility:
- ✅ Semantic HTML landmarks (
<main>,<nav>,<header>,<footer>) - ✅ Proper heading hierarchy (single h1, no skipped levels)
- ✅ WCAG color contrast (4.5:1 for text)
- ✅ Alt text on all images
- ✅ Form labels properly associated
- ✅ ARIA labels for icon buttons
Best Practices:
- ✅ HTTPS everywhere
- ✅
rel="noopener"on external links - ✅ Zero console errors
- ✅ Explicit image dimensions
- ✅ No deprecated APIs
The Expert Take
On every demo in my portfolio, SEO, Accessibility, and Best Practices hit 100/100. Performance usually does too, though it occasionally dips a few points on mobile due to framework overhead or CDN scripts. You can verify this yourself—click "PageSpeed Me" on any of our sites at codecrank.ai.
Time investment: First-time setup takes 4-6 hours. Once you know the patterns, subsequent sites take 1-2 hours.
Most agencies don't publish their Lighthouse scores. I put a verification button on every site I build. The work should speak for itself.
My side business DCTSoft builds custom websites for small businesses in record time, implementing all these techniques and often achieving perfect scores across the board.
This completes my PageSpeed series. For performance optimization techniques, see How to Achieve 100/100 on PageSpeed.
Top comments (0)