squirrelscan
GitHub

Mixed URL conventions: finding the minority form

Half your paths ending in a slash and half not is how canonical bugs start. squirrel computes your site's own norm and reports what deviates.

What URL convention consistency is

Every other URL rule judges one address against a fixed idea of a good address. None of them can see that a site is internally inconsistent: most slugs kebab-case with a pocket of snake_case, most paths bare with a handful slash-terminated.

The mixing is the problem, not the form. /My_Page, /my-page and /my-page/ are three URLs to a crawler even when they serve one document, and a site that applies one convention everywhere has none of that ambiguity regardless of which convention it picked. So this rule computes the site’s own dominant form per dimension and reports only the minority against it.

What squirrel checks

The rule is site-wide and judges five dimensions independently. Three are computed across the whole site: the slug word separator, kebab-case against snake_case against camelCase; the URL letter case, all-lowercase against a path carrying uppercase; and the trailing slash, present against absent, over extensionless paths only. Two are computed per page type: whether the slug carries a date, and the path-segment depth.

Three guards apply in order. The site needs at least 10 crawled pages. A site-wide dimension needs at least 10 pages that vote in it, and a per-page-type dimension at least 8. A dimension’s most common value must hold at least 70% of its votes, or the site legitimately mixes and nothing in it is a deviant.

The rule emits a single check named slug-convention:

  • Skipped when there are no pages at all. Message: No pages available for analysis.
  • Skipped below the page floor. Message: Only 6 page(s) crawled; 10 needed to establish a URL convention norm.
  • Skipped when no dimension clears the agreement floor. Message: No URL convention reaches 70% agreement across enough comparable pages.
  • Pass when no unsuppressed deviation remains. Message: All 240 page(s) follow the site's own URL conventions (URL letter case all-lowercase 100%, trailing slash no trailing slash 100%).
  • Warn when deviants exist and cover under 20% of crawled pages, and fail at or above that share. Message: 14 of 240 page(s) deviate from the site's own URL conventions (slug word separator kebab-case 94%). Each item reads 9 of 210 page(s) use camelCase but the slug word separator norm is kebab-case, with up to 10 example URLs.

Suppression runs one way and is unconditional. A deviant URL whose path contains an uppercase letter is dropped from the case dimension, and one whose path contains an underscore is dropped from the separator dimension, because url/lowercase and url/hyphens own those pages. The test reads the URL characters directly rather than consulting whether those rules ran. A dimension that lost any deviant this way is named in the message tail as (deferred to separator -> url/hyphens), so a snake_case minority stays visible without being reported twice. Reported items are capped at 10, example URLs at 10 per item. Severity warning, weight 3.

How to fix it

Pick the form the majority of the site already uses, migrate the minority onto it, and 301-redirect the old paths. The report names the dominant form and its share, so the decision is already made for you.

A section that deliberately differs, a dated archive or a deeper product tree, is fine. This rule computes date-in-slug and depth per page type for exactly that reason, so a blog with dated URLs and a docs tree without them are judged separately.

Rule IDurl/slug-convention
CategoryURL Structure
ScopeSite-wide
Severitywarning
Weight3/10

Enable / disable

Disable this rule

[rules]
disable = ["url/slug-convention"]

Disable all URL Structure rules

[rules]
disable = ["url/*"]

Enable only this rule

[rules]
enable = ["url/slug-convention"]

enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.

URL Structure findings ship in every audit next to the SEO, performance and agent experience rules. See Fix SEO issues with AI for how an agent works through a report.

References

Check your site

Run squirrel audit https://example.com and open the URL Structure section of the report. Each norm is reported with its agreement share, and each deviant group with example URLs. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.

Type to search…

↑↓ navigate↵ openesc close