SEO deploy gate — fetch each URL and assert its canonical is present, singular, consistent, and correct, across both the HTML and the HTTP layer.
- HTML ≠ HTTP header —
<link rel="canonical">says one thing, theLink: rel="canonical"response header says another. (CANONICAL_CONFLICT) - Wrong canonical — points at a different URL than expected (by default,
not self-referential). (
CANONICAL_MISMATCH) - No canonical at all — neither source present. (
CANONICAL_MISSING) - More than one
rel="canonical". (CANONICAL_MULTIPLE) - Unreachable URL — non-200 status. (
CANONICAL_FETCH)
- uses: nimajafari/seo-ci/actions/assert-canonicals@v1
with:
urls: |
https://www.example.com/products/widget
https://www.example.com/blog/post -> https://www.example.com/blog/post/
canonical-form: any # trailing_slash | no_trailing_slash | anyBy default each URL must be self-canonical. Use url -> expected to assert
a deliberate cross-URL canonical.
| Input | Default | Description |
|---|---|---|
urls |
— (required) | URLs to check; url or url -> expected per line (JSON array accepted). |
canonical-form |
any |
Trailing-slash policy for comparison. |
user-agent |
Googlebot |
User-agent used for fetching. |
strict |
false |
Treat warnings as errors. |
report-path |
"" |
Write the JSON report to this path. |
passed, errors, warnings, notices, report — see the
top-level README.
Caveat: A starting point, not a drop-in guarantee. Your canonical rules (self vs cross-URL, trailing-slash policy) are specific to your site. And never serve crawlers a different canonical than users — cloaking violates Google's policies.