SEO Lens
Real-time SEO linting for HTML, JSX, TSX, Vue, Svelte, Astro, and PHP — right inside VS Code.
SEO Lens runs as you type. It flags issues that hurt your search ranking, highlights every correctly implemented element so you know exactly why your score is great, and can scan your entire project in one click.
✨ Highlights
| Feature |
Detail |
| 🔴🟡🔵 13 SEO rules |
Errors, warnings, and info — all customisable |
| ✅ Passing-check hints |
Even a 100-score file shows green hints explaining why it's correct |
| 📁 Project-wide report |
Scan every web file at once, sorted by worst score |
| 🖱 Clickable rows |
Click any row in the report to jump straight to that line |
| ⚡ Auto-fix |
5 rules have one-click fixes (alt text, canonical, title, meta desc, lang) |
| 📊 Animated score ring |
Live 0–100 score with animated SVG ring in the report panel |
| ⬇ Export to Markdown |
Save seo-report.md to your workspace with one button |
| 🌐 Multi-framework |
HTML · JSX · TSX · Vue · Svelte · Astro · PHP · Nunjucks · Handlebars · Liquid |
🔕 <!-- noSEO --> |
Wrap any block to suppress diagnostics inside it |
Rules Reference
🔴 Errors
| Code |
Rule |
Auto-Fix |
| SEO001 |
Un-Crawlable Link — onclick navigation on non-<a> elements |
— |
| SEO002 |
Missing alt Text on <img> |
✅ Yes |
| SEO008 |
Missing <title> tag in <head> |
✅ Yes |
🟡 Warnings
| Code |
Rule |
Auto-Fix |
| SEO003 |
Vague alt Text ("image", "photo", etc.) |
— |
| SEO004 |
Broken Heading Hierarchy (skipped levels) |
— |
| SEO005 |
Missing <link rel="canonical"> in <head> |
✅ Yes |
| SEO007 |
Multiple <h1> Tags |
— |
| SEO009 |
Missing <meta name="description"> |
✅ Yes |
| SEO010 |
<title> Too Short (< 10 chars) or Too Long (> 60 chars) |
— |
| SEO011 |
Missing lang Attribute on <html> |
✅ Yes |
| SEO012 |
Vague / Dead Link (href="#", javascript:void) |
— |
| SEO013 |
noindex Meta Tag Detected |
— |
🔵 Info
| Code |
Rule |
| SEO006 |
Bare CSR Root (<div id="root"></div>) |
✅ Passing Checks (Hints)
These appear as subtle dotted underlines even on correct code, so you always know why a file scores 100.
| Code |
What it confirms |
| GOOD001 |
Alt text is descriptive |
| GOOD002 |
Canonical tag is present |
| GOOD003 |
Title is present and 10–60 chars |
| GOOD004 |
Meta description is present |
| GOOD005 |
<html lang=""> is set |
| GOOD006 |
Exactly one <h1> tag |
| GOOD007 |
Heading hierarchy has no skips |
Commands
| Command |
Description |
Shortcut |
| SEO Lens: Show File SEO Report |
Full report for the active file |
Ctrl+Shift+P |
| SEO Lens: Show Project SEO Report |
Scans all web files in workspace |
Ctrl+Shift+P |
| SEO Lens: Fix All Auto-Fixable Issues |
Applies all safe fixes in one go |
Ctrl+Shift+P |
The 🔍 icon also appears in the editor title bar for quick access. Right-click the editor for the full context menu.
Settings
{
// Toggle the entire extension
"seoLens.enable": true,
// Show ✅ hints on correctly implemented elements
"seoLens.showPassingChecks": true,
// Debounce delay in milliseconds (lower = faster feedback)
"seoLens.debounceMs": 400,
// Toggle individual rules
"seoLens.rules": {
"uncrawlableLinks": true,
"missingAltText": true,
"brokenHeadingHierarchy": true,
"missingCanonical": true,
"clientSideRendering": true,
"missingTitle": true,
"missingMetaDescription": true,
"missingLang": true,
"vagueLinks": true,
"noIndex": true
}
}
Suppressing Diagnostics
Wrap any block with <!-- noSEO --> and <!-- /noSEO --> to silence all rules inside it:
<!-- noSEO -->
<div onclick="navigate('/home')">Home</div> <!-- no SEO001 here -->
<!-- /noSEO -->
Anti-Patterns Detected
SEO001 — Un-Crawlable Links
<!-- ❌ Crawler dead-end -->
<div onclick="navigateTo('/course/123')">View Course</div>
<!-- ✅ Crawlable -->
<a href="/course/123">View Course</a>
SEO002 / SEO003 — Alt Text
<!-- ❌ Missing -->
<img src="https://github.com/minderfly/seo-lens/hero.jpg" />
<!-- ❌ Vague -->
<img src="https://github.com/minderfly/seo-lens/hero.jpg" alt="image" />
<!-- ✅ Descriptive — gets GOOD001 hint -->
<img src="https://github.com/minderfly/seo-lens/hero.jpg" alt="Dashboard showing weekly analytics" />
SEO004 — Heading Hierarchy
<!-- ❌ Skips h2 and h3 -->
<h1>Courses</h1>
<h4>Advanced Flutter</h4>
<!-- ✅ Sequential — gets GOOD007 hint -->
<h1>Courses</h1>
<h2>Advanced Flutter</h2>
SEO005 — Canonical Tag
<!-- ❌ Missing -->
<head><title>My Page</title></head>
<!-- ✅ Present — gets GOOD002 hint -->
<head>
<title>My Page</title>
<link rel="canonical" href="https://example.com/my-page" />
</head>
SEO008 / SEO010 — Title Tag
<!-- ❌ Missing -->
<head><meta charset="UTF-8"></head>
<!-- ❌ Too long (> 60 chars) -->
<title>The Ultimate Comprehensive Guide to Everything About Flutter Development</title>
<!-- ✅ Well-sized — gets GOOD003 hint -->
<title>Flutter Development Guide — MyApp</title>
SEO011 — HTML lang Attribute
<!-- ❌ Missing -->
<html>
<!-- ✅ Present — gets GOOD005 hint -->
<html lang="en">
SEO012 — Vague Links
<!-- ❌ Not crawlable -->
<a href="#">Learn More</a>
<a href="javascript:void(0)">Click</a>
<!-- ✅ Real destination -->
<a href="/learn-more">Learn More</a>
Supported Frameworks & File Types
| Language |
Extensions |
| HTML |
.html, .htm |
| React |
.jsx, .tsx |
| JavaScript / TypeScript |
.js, .ts |
| Vue |
.vue |
| Svelte |
.svelte |
| Astro |
.astro |
| PHP |
.php |
| Templates |
.njk, .hbs, .ejs, .liquid |
Changelog
1.1.0
- ✅ Passing-check hints — highlights correct elements at all score levels
- 📁 Project-wide report command — scan entire workspace at once
- 🌐 Vue, Svelte, Astro, PHP, and template engine support
- ➕ SEO008–SEO013: Title, Meta Description, Title Length, Lang, Vague Links, noindex
- 📊 Animated SVG score ring in webview report
- 🖱 Clickable report rows that navigate to exact file + line
- ⬇ Export to Markdown button
- 🔕
<!-- noSEO --> block suppression
- 📌 Live status bar item with score + issue counts
- ⚡ Auto-fix extended: title, meta description, lang attribute
1.0.0
- Initial release: SEO001–SEO007, file report, quick fixes for alt + canonical
Built by Minderfly · MIT License