MCPRemote MCP server for Cursor and Claude Code, on your existing API key→ Read the docs
QuikSEO.com

Free SEO tool

Site Contract SEO Validator

Paste a quikseo.config.json file and this SEO validator checks it against the site contract format, listing every error at once: invalid JSON, unknown types or parameters, broken CSS selectors and unsafe regular expressions. Add a URL to run the valid contract on that page and see each assertion as CTR-<id> with its state.

0 out of 5 from 0 ratings
Paste the whole file. Every error is listed at once; the format is described in the site contract documentation.
Show the preset contract to copy
{
    "version": 1,
    "assertions": [
        {
            "id": "url-no-trailing-slash",
            "type": "urlPolicy",
            "severity": "warning",
            "scope": [],
            "title": "URLs without a trailing slash",
            "trailingSlash": "never",
            "lowercase": true,
            "noIndexHtml": true
        },
        {
            "id": "title-length",
            "type": "titlePattern",
            "severity": "warning",
            "scope": [],
            "title": "Title between 30 and 65 characters",
            "minLength": 30,
            "maxLength": 65
        },
        {
            "id": "head-order",
            "type": "headOrder",
            "severity": "info",
            "scope": [],
            "title": "Head order",
            "order": [
                "charset",
                "viewport",
                "title",
                "description",
                "canonical"
            ]
        },
        {
            "id": "one-h1",
            "type": "required",
            "severity": "error",
            "scope": [],
            "title": "Exactly one h1",
            "selector": "h1",
            "count": 1
        },
        {
            "id": "one-canonical",
            "type": "required",
            "severity": "error",
            "scope": [],
            "title": "Exactly one canonical",
            "selector": "link[rel~=\"canonical\"]",
            "count": 1
        },
        {
            "id": "no-generator",
            "type": "forbidden",
            "severity": "info",
            "scope": [],
            "title": "No generator meta tag",
            "selector": "meta[name=\"generator\"]"
        },
        {
            "id": "no-inline-style",
            "type": "forbidden",
            "severity": "info",
            "scope": [],
            "title": "No style attributes",
            "selector": "[style]"
        },
        {
            "id": "no-html-comments",
            "type": "forbidden",
            "severity": "info",
            "scope": [],
            "title": "No HTML comments",
            "htmlComments": true
        },
        {
            "id": "no-faq-schema",
            "type": "forbidden",
            "severity": "warning",
            "scope": [],
            "title": "No FAQPage structured data",
            "jsonLdType": "FAQPage"
        },
        {
            "id": "canonical-clean",
            "type": "canonicalPolicy",
            "severity": "error",
            "scope": [],
            "title": "Absolute canonical on the same host, without a query string",
            "absolute": true,
            "noQuery": true,
            "sameHost": true
        },
        {
            "id": "headings-title-case",
            "type": "headingCase",
            "severity": "warning",
            "scope": [],
            "title": "Headings in Title Case",
            "style": "title",
            "levels": [
                1,
                2,
                3
            ]
        }
    ]
}
Leave empty to validate the contract only. With a URL, the valid contract runs on that page.

How to Use the SEO Validator Online

Paste the contract, optionally add a URL, and submit: the errors, or the result of every assertion, appear below the form.

  1. Paste the content of your quikseo.config.json into the contract box, or copy the preset shown under it as a starting point.
  2. Leave the URL empty to validate the contract only, or enter a full URL, including https://, to run the contract on that page.
  3. Submit the form.
  4. If the contract has errors, fix every listed problem and submit again; nothing is requested from the site until the contract is valid.
  5. If you entered a URL, read the state of each CTR assertion; a failed one shows its message and, when it helps, an excerpt of the page.

SEO Validator Results Explained

An invalid contract returns the list of its errors; a valid one returns its assertions and, with a URL, the state of each one on that page.

Contract Errors

Each error names the assertion it belongs to, by its id or its position, and the field at fault. The validator checks JSON syntax, the version, ids, types, severities, parameters, scope patterns, CSS selectors and regular expressions in one pass, so one submission shows everything to fix. An expression such as (a+)+$ that exhausts the backtracking budget is refused.

Valid Contract and Its Hash

A valid contract lists every assertion with its type, severity, parameters and scope. The hash is computed from the normalized contract, so two files with the same assertions get the same hash whatever their spacing. Audits store this hash to name the contract version they applied.

Pass and Fail

Pass means the page meets the assertion. Fail means it breaks it, with the severity you chose, a message such as the number of matching elements, and an excerpt of the page when one helps. Contract results never change an audit score.

Not Applicable and Not Checked

An assertion is not applicable when its scope does not include the URL path, when the response is not HTML (only urlPolicy runs then), or when it has nothing to judge, such as a canonical policy on a page without a canonical. Not checked means the assertion could not be evaluated, and the message says why.

Automated SEO Testing With a Site Contract

A site contract turns your own SEO conventions into assertions that every audit and every build checks the same way.

SEO Testing Examples: Sample Contract Assertions

A required assertion with the selector h1 and count 1 fails when a page has no h1 or several. A urlPolicy with trailingSlash set to never fails on /about/, and a forbidden assertion with jsonLdType FAQPage fails when the page carries FAQPage structured data. The preset under the contract box shows eleven assertions you can copy and edit.

Turning an SEO Testing Checklist Into Assertions

Write one assertion per checklist item, with a short id, the type that matches the check and the severity it deserves. Seven types are available: urlPolicy, titlePattern, headOrder, forbidden, required, headingCase and canonicalPolicy. Use scope, such as /blog/*, when an item applies only to part of the site.

Running the Contract in Your SEO Testing Software or CI

Keep quikseo.config.json in your repository and the QuikSEO CLI applies it to every build, so a pull request that newly breaks a convention of error severity or higher fails before it is deployed. The GitHub Action runs the same CLI. Validate the file here first so the build does not stop on a syntax error.

SEO Validator FAQ

What Is SEO Testing?

SEO testing checks pages against rules that affect how search engines crawl, index and display them, such as titles, canonicals and headings. A site contract adds your own rules to that list, written as assertions. This validator runs those assertions on one page; a full audit runs them with every built-in rule.

How to Do SEO Testing Before Every Deploy?

Commit quikseo.config.json to the repository and run the QuikSEO CLI or the GitHub Action on each build. The build reports every assertion as CTR-<id> and, by default, fails on a new failure of error severity or higher; --fail-on and --threshold change that. Validating the contract here first catches format errors before the pipeline runs.

What Are the Limits of a Site Contract?

A contract holds at most 100 assertions and 64 KB. CSS selectors and regular expressions are limited to 300 characters, a selector must parse and an expression must compile. Nothing in a contract runs code.

Is My Contract Stored When I Validate It?

No. The pasted contract is parsed for this response only and never placed in a URL. When you add a URL, only that URL is kept in your own last submissions list.

Why Is an Assertion Not Applicable on My Page?

The most common cause is a scope that does not match the URL path: /blog/* covers /blog/post but not /blog/2026/post, which needs /blog/**. A response that is not HTML also makes every assertion except urlPolicy not applicable. Check the message under the assertion for the exact reason.

Share