From hypervibe
Audit and optimize SEO for a Next.js project. Checks metadata, sitemap, robots.txt, Open Graph, structured data, performance, and accessibility. Use when the user wants to improve their site's search engine visibility.
How this skill is triggered — by the user, by Claude, or both
Slash command
/hypervibe:seoThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You audit the project's search engine optimization and propose concrete improvements. You explain why each optimization matters.
You audit the project's search engine optimization and propose concrete improvements. You explain why each optimization matters.
The report must be readable by someone who is neither a developer nor an SEO expert. The user is often someone who just put their site online and simply wants to be found on Google, not a search optimization consultant.
Concrete rules:
<title> tag) is too short" rather than "Title tag under-optimized".<h1> tag). Consequence: Google doesn't clearly understand what this page is about, and it has less chance of showing up when someone searches for 'contact [your company]'."This rule applies to the report (step 2) and to the optimization proposals. In your internal scan (step 1), you can stay brief and technical.
Analyze the project and check each point below. For each point, indicate ✅ (OK), ⚠️ (needs improvement), or ❌ (missing).
<title> (50-60 characters)?meta description (150-160 characters)?<meta name="viewport"> tag present?lang attribute set on <html>?Check in the main layout and in each page that exports a metadata or generateMetadata.
/public (1200x630px recommended)?<h1> per page?<main>, <nav>, <section>, <article>, <footer>?alt attributes on images?Scan the route tree (src/app/**/page.tsx or apps/web/src/app/**/page.tsx) and audit each slug.
For each route, check:
mon-article)? Flag if camelCase (monArticle), snake_case (mon_article), CamelCase, or if it contains uppercase letters / special characters / non-ASCII accents[id] where a [slug] would be preferable. Also look at routes like /blog/123-mon-titre (id + slug)[slug] vs [id] prefix: for dynamic routes, if an [id] is used, recommend [slug] (with explanation: Google prefers URLs that contain a keyword from the content, not an opaque identifier)/services-pro = bad; /ia-entreprise = good)Present as a table:
Route Current slug Problem Proposed slug /blog/[id]/page.tsx[id]Numeric ID in the URL ( /blog/123)[slug](/blog/mon-titre)/aProposDeNous/page.tsxaProposDeNouscamelCase /a-propos/services_premium/page.tsxservices_premiumsnake_case /services-premium
Accessibility influences Google ranking (Core Web Vitals + quality signals). Audit the following points by static grep, no browser needed:
<img> without alt: grep <img[^>]*(?<!alt=["'][^"']+["']). Each <img> MUST have a descriptive alt (or an explicit alt="" for decorative images)<Image> without alt: same for the next/image component<Button> whose content is only an icon component (e.g. <Trash2 />, <X />) with no text and no aria-label. These buttons are invisible to screen readers<a>, <Link>, <LinkButton> whose text is "cliquez ici", "en savoir plus", "ici", "lire la suite", "voir plus", "click here", "read more". Bad for SEO (Google uses the anchor text as a signal) AND for accessibility. Propose descriptive rewordings:focus-visible in globals.css: grep :focus-visible in src/app/globals.css. If absent, keyboard navigation has no visual feedback → flag. Propose a default snippet#main or skip.*content in the main layout. Standard pattern: <a href="#main" className="sr-only focus:not-sr-only">Skip to content</a> at the start of <body>. If absent, flag as an improvement<Input> in a form must have an associated <Label htmlFor=> (not just a placeholder, which disappears as soon as you type and is not read by screen readers). Grep <Input> / <Textarea> / <Select> without an associated <Label><main>, <nav>, <header>, <footer> in the layout. Flag if absent (especially <main>, which is the main landmark for screen readers)text-gray-400 bg-white, text-gray-300, text-yellow-300 bg-white, text-blue-300 bg-white. Do not compute the real ratio (not possible without rendering), just detect the combinations known to fail<Image> from next/image (lazy loading, automatic optimization)?next/font (no flash of text)?WebSite schema present in the layout?sameAs (social networks)?<link rel="alternate" hreflang="..."> tags present (via metadata.alternates.languages)?alternates?This step analyzes content quality for search optimization: positioning, keywords, tag text, and overall consistency.
Read the site content in depth to understand the project:
CLAUDE.md, the spec (*.md at the root), and the textual content of each page (h1, h2, paragraphs, CTA)messages/*.json) if i18n is configuredPresent the inference at the start of the report:
Detected positioning:
- Offer: [what the site offers]
- Target: [to whom]
- Goal: [conversion, awareness, leads, etc.]
- Semantic universe: [the 3-5 main themes of the site]
From the inferred positioning:
Propose 10-15 main keywords the site should target, ranked by priority:
Use Google Suggest to validate and enrich: for each main keyword, do a WebFetch on https://suggestqueries.google.com/complete/search?client=firefox&hl=fr&q=MOT_CLE to retrieve real search suggestions. Add the relevant suggestions to the list.
Check the presence of the keywords in the current site:
<title> of the home page?h1?meta description?Present as a table:
Keyword Estimated volume Present in title Present in h1 Present in description Targeted page keyword 1 high ✅ ✅ ❌ / keyword 2 medium ❌ ❌ ❌ none
For each page, evaluate the <title>:
For each title to improve, propose a rewrite:
Page /conferences:
- Current: "Conférences" (11 chars - too short, no keyword, no hook)
- Proposed: "Conférences IA en entreprise | [Your name / brand]" (keyword + author + context)
For each page, evaluate the meta description:
For each description to improve, propose a rewrite.
Check the consistency between each page's content and its metadata:
h1 reflect the title and the description?Measure the reading ease of each page's textual content. Google prefers accessible content (better engagement, longer reading time).
For each important page, extract the visible text (h1, h2, h3, paragraphs, lists, ignore code, button labels, navs) and compute the Flesch score adapted to French:
Score FR = 207 - 1.015 × (words / sentences) - 73.6 × (syllables / words)
Simple inline node implementation:
node -e "
const fs = require('fs');
const text = fs.readFileSync(process.argv[1], 'utf8')
.replace(/<[^>]+>/g, ' ') // strip HTML/JSX tags
.replace(/\{[^}]+\}/g, ' ') // strip JSX expressions
.replace(/\s+/g, ' ').trim();
const sentences = text.split(/[.!?]+/).filter(s => s.trim().length > 0).length;
const words = text.split(/\s+/).filter(w => w.length > 0);
const wordCount = words.length;
const syllables = words.reduce((acc, w) => acc + Math.max(1, (w.match(/[aeiouyéèêëàâôöûüîï]+/gi) || []).length), 0);
const score = 207 - 1.015 * (wordCount / Math.max(1, sentences)) - 73.6 * (syllables / Math.max(1, wordCount));
console.log('Flesch FR:', score.toFixed(1), '| Words:', wordCount, '| Sentences:', sentences);
" <path-to-file>
Scale (FR):
In the report, flag the pages whose score does not match the target detected in Step 1b.1:
"Your
/servicespage targets 'small and medium businesses' but its readability score is 28 (very technical). Sentences too long (22 words on average). I recommend cutting into shorter sentences and removing the jargon."
For each important page, check that the content covers the semantic field around the target keyword, not just the keyword itself. Google expects to see related terms to consider that a topic is covered in depth (the "LSI keywords" / latent semantic indexing concept).
Method:
https://suggestqueries.google.com/complete/search?client=firefox&hl=fr&q=<keyword> → extract the 10 suggestions (these are the most frequent associated queries)Present:
Page /services targets "AI in business":
- Expected semantic terms (Google Suggest): digital transformation, automation, ROI, use cases, productivity, training, adoption, benefits, implementation, governance
- Found in your content: 3/10 (automation, productivity, training)
- Missing: digital transformation, ROI, use cases, adoption, benefits, implementation, governance
- Suggested action: enrich your page with 2-3 paragraphs covering the most relevant missing terms (digital transformation, ROI, use cases) to show Google that you cover the topic in depth.
Google prefers recent content (especially for YMYL topics: Your Money Your Life - health, finance, news - and for "time-sensitive" queries). Check the freshness signals:
<time datetime="..."> on article/blog type pages: present?<time> in the article templates. Flag if an article has no visible dateArticle schemas exist, do they check datePublished AND dateModified?lastmod: does sitemap.ts generate a lastModified for each URL (or is it a fixed / absent date)? A real dynamic lastmod signals recently updated pages to GoogleIn the report:
"Your article
/blog/mon-posthas no visible date in the HTML. Google can't know when it was written, and neither can the readers. Add a line<time dateTime=\"2026-04-19\">Publié le 19 avril 2026</time>at the top of the article."
Present the content report separately:
Content audit - Results
Positioning: [1-line summary]
Recommended main keywords: [list of the 5 priorities]
✅ Well optimized: [pages whose title + description + h1 are consistent and contain the keyword]
⚠️ To optimize:
- Page /xxx: title too generic, keyword missing from the description
- Page /yyy: description too short (80 chars), no CTA
- Page /services: readability 28 (very technical) for a small-business target
- Page /accueil: 3/10 expected semantic terms found (weak topical depth)
❌ Problems:
- 2 pages target the same keyword (cannibalization)
- Page /zzz has only 50 words of content
- No blog article shows its date (no freshness signal for Google)
Present the two reports together:
First the content report (step 1b.9 - positioning, keywords, titles, descriptions, readability, topical depth, freshness).
Then the technical report:
Technical audit - Results
✅ OK (X points): viewport, language, favicon, ...
⚠️ To improve (X points):
- Description too short on the home page (currently 80 characters, recommended 150-160)
- OG image missing (shares on social networks will have no visual preview)
❌ Missing (X points):
- No sitemap.xml
- No robots.txt
- No alt attribute on 3 images
Overall score: X/Y
Ask the user:
Do you want me to fix all this now? I can handle the ⚠️ and ❌ points automatically.
If the user accepts, fix in this order:
If none of the three files src/app/sitemap.ts, public/robots.txt, or an enriched metadata with metadataBase exists → run the plugin's init script:
node "${CLAUDE_SKILL_DIR}/../../scripts/setup-seo.mjs" \
--name "<Site Name>" \
--description "<150-160 char description>" \
--locale fr_FR
The script creates/updates layout.tsx (metadata + minimal JSON-LD WebSite + html lang), public/robots.txt, src/app/sitemap.ts. It is idempotent.
If a part already exists but is incomplete → manually patch only the missing piece (the script preserves existing files).
The script creates the sitemap with just /. Update it to reflect the real state:
page.tsx to list the routesalternates.languages for the hreflangIf public/og-image.png does not exist, create a placeholder and note in the summary that the user will need to replace it with a real image (1200×630).
Go through the components and fix the problems identified in step 1 (missing alt, broken h1/h2/h3 hierarchy, non-semantic tags).
If the fonts are not loaded via next/font (the T3 scaffold does it by default with Geist, so this is rare), migrate to next/font/google or next/font/local.
The script in 3a adds a minimal WebSite schema. Depending on the project context, add:
Person schema (name, url, jobTitle, sameAs with the social networks found in the footer)Organization schema (name, url, logo, sameAs)Event schemaProduct schemaLook for the social links in the footer/components to fill sameAs.
For the routes flagged in Step 1 (camelCase, snake_case, numeric IDs, [id] instead of [slug], stop words), do NOT rename automatically, it is too risky:
Instead, list the recommendations in the final report with an explicit note:
⚠️ URL renaming: to be done manually and gradually
If you decide to rename routes, remember to set up 301 redirects from the old URLs to the new ones (in
next.config.js, theredirects()section) to preserve the SEO already earned and avoid 404s.
Propose adding the redirects automatically in next.config.js if the user approves the renaming.
For each a11y problem flagged in Step 1:
<img> / <Image> without alt: fix by adding a descriptive alt (infer from the file name, the context, or ask the user if not obvious). For purely decorative images, use alt="" (explicit empty).aria-label. E.g. <Button><Trash2 /></Button> → <Button aria-label="Supprimer"><Trash2 /></Button>.:focus-visible: add a default block to globals.css:
:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
<body> in layout.tsx:
<a href="#main" className="sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 bg-background px-4 py-2 rounded">
Skip to content
</a>
And add id="main" to the <main> of each page.text-gray-400 → text-gray-600 on a light background).After the fixes, re-run the audit quickly and display the new score.
✅ SEO audit complete. Score: X/Y → X/Y
One manual point remains: replace the placeholder Open Graph image (
/public/og-image.png) with a real image from your site (1200x630px).
The audit above is static (reading the code). We can go further and measure the real performance of the deployed site with PageSpeed Insights (Google's official tool, which runs a real Lighthouse): real speed, Core Web Vitals, and fixes prioritized by measured impact. This is the measurement layer the static audit cannot provide (numbers on the live build, not a deduction from the code).
This is optional and takes a few minutes. Ask via AskUserQuestion:
Do you want me to measure your site's real speed with PageSpeed Insights (Google's tool)? I load a few representative pages like a real visitor, give you the numbers (speed, Core Web Vitals), and propose fixes sorted by real impact. It takes a few minutes. If it's the first time, you'll need to create a free Google key (2 min, just once for all your projects).
seo-perf skill in integrated mode (pass --from-seo). Since /seo just asked the opt-in question, seo-perf skips its own and goes straight to the audit. Follow its flow (key preflight, representative pages, audit, report, bounded improvement pass, deployment then re-verification)./seo-perf.Sequencing note: seo-perf measures the live site. The SEO fixes made in Step 3 that are not yet deployed will only appear in the measurement after deployment. seo-perf handles the order itself (deployment then re-verification), so let it drive that part.
The audit we just did prepares you for classic Google. Two complementary directions for what comes next:
Today, people also search via ChatGPT, Claude, Perplexity, Google AI Overviews, Bing Chat. The signals for being cited by AIs are not quite the same as for showing up in Google results. The /geo skill does a dedicated audit (llms.txt, rules for AI crawlers, FAQPage schema, Q&A format, citability signals), no need to wait for the site to have traffic.
Google Search Console (GSC) gives you the real Google data: which queries bring traffic, which pages are indexed, your real CTR. The best is to connect the site now (so Google starts collecting right away) and come back to see the data in 2 to 4 weeks. The /gsc skill handles it from A to Z: adding the property, automatic DNS verification, sitemap submission, and first audit.
Add this block to the final summary of the audit:
🚀 Next steps
Optimize for AIs - run
/geofor an audit dedicated to AI engines (ChatGPT, Claude, Perplexity, Google AI Overviews...). It is complementary to what we just did.Connect to Google Search Console - run
/gscto connect your site and see what Google really sees. You might as well do it now: Google starts collecting data as soon as you connect, and in 2-4 weeks you'll have a real overview.Tell me "run /geo" or "connect to Google Search Console" and I'll take care of it.
npx claudepluginhub flavien-ia/hypervibe-harness --plugin hypervibeScans websites for SEO issues including meta tags, headings, broken links, images, Core Web Vitals, and structured data, producing a prioritized fix list.
Optimizes technical SEO including crawlability, robots.txt, meta robots, canonical URLs, XML sitemaps, and URL structure. Use when asked to improve SEO or fix meta tags.
Analyzes and optimizes HTML/CSS websites for search engine visibility. Runs SEO audits, fixes meta tags, adds schema markup, generates sitemaps, and optimizes Core Web Vitals.