Content audit rules: thin, duplicate and stale content
Audit rules for page text: thin and duplicate content, stale dates, placeholder text, mojibake, broken HTML, readability and keyword stuffing.
Content rules read the words a visitor actually sees. Some of them catch pipeline failures that reach the reader as text: mojibake, literal markdown, lorem ipsum, a development URL, a visible undefined. Others measure the writing itself, its length, its readability and its keyword density. A third group compares pages against each other, finding duplicate titles, thin outliers and titles that break the site’s own template.
Run only these rules
squirrel audit https://example.com --rule-include contentLLM content quality score is retired and never runs. It stays in the table so its page and ID keep working.
Where to start
These carry the highest severity and weight in the category.
- Meta tags in the body: why they are silently ignored: A meta description or robots tag inside body is not read by anything. squirrel finds every meta element that ended up outside the head.
- Duplicate title tags: the same title on several pages: Two pages with the same title compete with each other in search and look identical in results. squirrel groups every crawled page by its title.
- Hidden text and links: what Google’s spam policy covers: Text a crawler reads and a visitor cannot see is a spam policy violation. squirrel finds it while exempting screen-reader and collapsed-UI patterns.
- localhost in production: dev hosts left in the markup: A link or image pointing at localhost or a preview deployment is broken for every visitor. squirrel classifies the host and says whether it is yours.
- Lorem ipsum in production: placeholders and leftovers: Filler copy, unrendered template syntax and a visible undefined all mean something shipped unfinished. squirrel names the family and shows a sample.
Rules
| Rule | What it flags | Severity | Scope |
|---|---|---|---|
| Article link density: how many links an article needs | An article that cites nothing and links nowhere is a dead end. squirrel scales the minimum with the article’s length. | warning | Per-page |
| Author attribution: schema, rel=author and visible bylines | Who wrote a page is part of how a reader decides whether to trust it. squirrel inventories the author markup a page carries. | info | Per-page |
| Duplicate meta descriptions across pages | One description reused across a section describes none of those pages well. squirrel groups every crawled page by its meta description. | warning | Site-wide |
| Duplicate title tags: the same title on several pages | Two pages with the same title compete with each other in search and look identical in results. squirrel groups every crawled page by its title. | warning | Site-wide |
| Fake phone numbers and example.com emails in production | A 555-01xx phone number or an address at example.com means a theme’s contact block shipped unedited. squirrel flags template-default contact details and fails them on contact and checkout pages. | warning | Per-page |
| Flesch reading ease: measuring how hard a page is to read | squirrel computes a Flesch reading ease score and a Flesch-Kincaid grade level from the page text, and reports both without judging them. | info | Per-page |
| Footer copyright year behind the current year | An old year in the footer is the cheapest signal that a site is abandoned. squirrel reads the footer only, so dated body copy is left alone. | warning | Per-page |
| Freshness signals: the dates a page publishes about itself | squirrel inventories the date signals on a page: the Last-Modified header, schema dates, time elements and Open Graph article dates. | info | Per-page |
| Hidden text and links: what Google’s spam policy covers | Text a crawler reads and a visitor cannot see is a spam policy violation. squirrel finds it while exempting screen-reader and collapsed-UI patterns. | warning | Per-page |
| Inconsistent page titles: pages breaking the template | Most sites title pages the same way and then ship a pocket that does not. squirrel infers your template and reports the pages that break it. | warning | Site-wide |
| Keyword stuffing: measuring density around your CTAs | Repeating a term unnaturally is a spam policy violation. squirrel measures density while discounting repeated call-to-action labels. | warning | Per-page |
| Literal bold on the page: markdown that never rendered | Visible asterisks, bracket links or escaped tags mean a value printed as text instead of markup. squirrel reads the prose and names the mistake. | warning | Per-page |
| LLM content quality score: what it measures | A language-model read of the page copy, scored 0 to 100 with written feedback. Retired in this release: it never runs. | info | Per-page |
| localhost in production: dev hosts left in the markup | A link or image pointing at localhost or a preview deployment is broken for every visitor. squirrel classifies the host and says whether it is yours. | warning | Per-page |
| Lorem ipsum in production: placeholders and leftovers | Filler copy, unrendered template syntax and a visible undefined all mean something shipped unfinished. squirrel names the family and shows a sample. | warning | Per-page |
| Malformed HTML: doctype, nesting and deprecated tags | Browsers recover from bad markup silently and other parsers may not. squirrel checks document structure, nesting and deprecated elements. | warning | Per-page |
| Meta tags in the body: why they are silently ignored | A meta description or robots tag inside body is not read by anything. squirrel finds every meta element that ended up outside the head. | error | Per-page |
| Misspellings and doubled words in English copy | A typo in a heading, a price table or a page title is the first thing a visitor notices. squirrel finds known misspellings and doubled words on English pages, and names the correction. | warning | Per-site |
| Mojibake: ’ and other encoding corruption in page text | Strange character sequences in your copy mean the bytes and the declared encoding disagree. squirrel finds them and names which of the two is wrong. | warning | Per-page |
| Placeholder images and camera-default alt text | A placeholder service image, a 1x1 stand-in or an alt of DSC_0001 means the media was never finished. squirrel names the image and why it was flagged. | warning | Per-page |
| Skipped heading levels: h1 to h3 and other outline problems | Headings are the page’s outline, and a skipped level breaks it for anyone navigating by structure. squirrel checks order, emptiness, length and repeats. | warning | Per-page |
| Thin against your own site: outliers by page type | A 200 word product page is normal and a 200 word article is not. squirrel compares each page against the median for its own page type. | warning | Site-wide |
| Thin content: the 300 word floor and what to do below it | A page under a few hundred words rarely answers the question it ranks for. squirrel counts the words and reports against two thresholds. | warning | Per-page |
| Visible date disagrees with schema: which date is wrong | A page states its date in several places and presence checks pass as soon as one exists. squirrel compares the byline, the schema and the URL year. | warning | Per-page |
| Wrong Content-Type: header and extension disagree | A stylesheet served as text/html is refused by the browser under nosniff. squirrel compares the response type against the URL extension. | warning | Per-page |
Key terms
- Author byline: The visible author name on an article, ideally linked to an author page and matched by an author entity in structured data.
- Character encoding: The mapping from bytes to characters (normally UTF-8) declared in the Content-Type header or a meta charset tag; a mismatch produces mojibake.
- Cloaking: Serving search engines or particular user agents different content from what visitors see, a Google spam policy violation.
- Content freshness: How current a page is and how consistently it says so: visible dates, dateModified, sitemap lastmod and copyright year.
- Duplicate content: The same or near-identical content reachable at more than one URL, or repeated titles and descriptions across pages.
- Heading hierarchy: The nesting of h1 to h6 headings that gives a page its outline for readers, screen readers and parsers.
- HTML validity: Whether the markup parses as intended: closed elements, head-only tags in the head, and no raw markup printed as text.
- Keyword stuffing: Repeating a term far beyond natural use in the hope of ranking for it, which Google lists as spam.
- Leaked secrets: Credentials or private keys shipped to the browser in HTML, scripts or source maps.
- Meta description: A
<meta name="description">summary of the page that search engines may use as the result snippet. - Placeholder content: Template filler left in production: lorem ipsum text, stock placeholder images, example phone numbers and emails.
- Readability: How hard a text is to read, estimated from sentence and word length with formulas such as Flesch reading ease.
- Thin content: A page with too little substantive content to be useful, judged here against word count and the site’s own norm.
- Title tag: The
<title>element in the page head; browsers show it in the tab and search engines usually use it as the result headline. - X-Content-Type-Options: The nosniff header that stops browsers guessing a response’s type instead of trusting Content-Type.
Related categories
Core SEO checks each page’s own title, description and H1. E-E-A-T looks for authors, dates and the pages that back up what the text claims, and Security looks for secrets that reached the browser.
Learn more
- SEO for vibe coded sites, the checks that Lovable, v0 and Bolt output tends to miss
- Website audit tool
- Sample report, with the Content section on a real site
Disable all Content rules
[rules]
disable = ["content/*"]