vibecms.docs
Content

SEO and AI-answer checks

Deterministic checks for search engines and AI answers before you publish, on every plan.

Every post is checked for the things search engines and AI answer engines look for: titles and descriptions, heading structure, links, duplicates, an opening that can stand as an answer, sourced numbers, and passages short enough to quote. There are 31 rules, all plain code, and they run on every plan, Try free included. vibecms runs no AI model on your post. The judgment calls a rule can’t make (does the opening actually answer the title? which claims need a source?) are for your own agent, guided by the vibecms-seo skill.

Findings have a stable code, a severity of error, warn, or info, the field they attach to, a plain-language message, and a fix hint. They come back sorted by severity.

Where they show

  • posts.preview returns the findings in its seo field next to warnings, so the existing preview flow sees them for free.
  • posts.seo_check({postId, focusKeyword?}) checks a saved post’s current tip and returns {versionNumber, findings}. REST mirrors it at GET /api/v1/posts/{postId}/seo?focusKeyword=.
  • The editor’s SEO section lists findings grouped by severity, with a focus keyword field saved per browser and one-click jumps to the SEO fields a finding attaches to.
  • The publish dialog lists open error findings. It informs, it does not block.

Previewing unsaved Markdown (contentMarkdown instead of postId) skips the checks that attach to saved metadata — title, description, slug, duplicates, canonical — but still runs site context like site-not-indexable alongside the body checks.

Finding codes

26 rules for search engines (including the five focus keyword rules) and 5 for AI answers.

Title, description, slug

Code Severity Meaning and fix
title-length warn Effective SEO title is outside 15-60 characters — write a more descriptive title or shorten it.
description-missing warn No SEO description or excerpt — write a 50-160 character description.
description-length warn Description is outside 50-160 characters — expand or shorten it.
slug-long warn Slug is over 75 characters — keep the essential words.
slug-format warn Slug has uppercase letters, underscores, or a date — use lowercase hyphenated words.

Headings

Code Severity Meaning and fix
h1-in-body warn Body contains an H1 other than a leading # <post title> — that one is removed before rendering, so demote any other body # headings to ##.
heading-skip warn A heading level jumps (H2 to H4) — use the next level so the outline stays intact.
heading-empty warn A heading has no text — fill it or remove it.
heading-duplicate warn The same heading text appears twice — rename it so each section is unique.
Code Severity Meaning and fix
link-internal-broken error A root-relative or same-host link points to a slug with no published post — publish or fix the target.
link-insecure warn A link uses http:// — switch it to https://.
link-anchor-generic warn Link text like “click here” doesn’t describe the destination — use descriptive text.
link-none-internal info The post links to no other published post — link at least one related post.

Content

Code Severity Meaning and fix
content-thin warn Body is under 300 words — add substance or consolidate with a related post.
paragraph-long info A paragraph runs over 150 words — split it for readability.

Images and sharing

Code Severity Meaning and fix
image-alt-missing warn An image has no alt text — describe it for accessibility and image search.
social-image-default info No cover image — pick one, or the generated social card is used.

Site and duplicates

Code Severity Meaning and fix
duplicate-title warn Another published post uses this title — differentiate it.
duplicate-description warn Another published post uses this description — write a distinct one.
canonical-external info The canonical URL points off-site — remove it unless the post is syndicated from there.
site-not-indexable info The site isn’t indexable (search engines are told to skip it) — upgrade or enable indexing.

Focus keyword

Pass focusKeyword to posts.seo_check (or fill the editor field) to add five warn findings, one for each place the keyword should appear: keyword-title, keyword-slug, keyword-intro (first 100 words), keyword-heading (a subheading; the title does not count), and keyword-description. Hyphens and underscores in a keyword match like spaces.

AI answers

AI answer engines quote short, self-contained passages. These rules check structure only; they can’t tell whether a passage is right or useful.

Code Severity Meaning and fix
answer-intro-missing warn The post opens with a heading, list, or quote instead of a paragraph — start with a short paragraph that answers the title.
answer-intro-long info The opening paragraph runs over 80 words — keep the answer under 80 and move detail to the next paragraph.
answer-claim-unsourced info A paragraph states a percentage, a multiplier (“3x faster”), or a count in millions or more with no link in that paragraph — link the source or say where the number comes from. Footnote references count as links. Plain counts, versions, years, and prices are not flagged.
answer-section-long info The text under one heading runs over 400 words before the next heading — add subheadings so each part makes sense quoted on its own.
answer-steps-prose info A paragraph walks through steps in prose (three or more sentences starting with words like “First”, “Then”, “Finally”), or two or more paragraphs in a row start with “Step 1”, “Step 2” — use a numbered list.

Code blocks never count toward these rules, and a number inside inline code is not a claim.

Agent guidance

Fix error and warn findings before asking for publish approval. error findings are broken promises — a link to a post that doesn’t exist yet; warn findings are things readers and crawlers will notice. info findings are optional improvements. Never invent a source to clear answer-claim-unsourced; say where the number comes from instead.

Then answer the judgment questions in the vibecms-seo skill with your own model before asking the human to approve.