Advanced

Custom rules & presets

Write your own checks with defineCheck and ship them as presets or rule packages.
import { defineCheck } from '@ranklint/checks'

customChecks: [
  defineCheck({
    id: 'myteam:no-lorem',          // clashing with a built-in id is an error with a hint
    category: 'meta',
    severity: 'warn',
    scope: 'page',                  // 'page' | 'site'
    docs: 'https://wiki.myteam.dev/seo/no-lorem',
    optionsSchema: z.object({...}), // optional — options validation
    async run(ctx) {
      // ctx: page, pages, document (linkedom DOM), config, site, fetcher
      return [{ checkId: 'myteam:no-lorem', severity: 'warn', message: '...', url: ctx.page!.url }]
    },
  }),
]

Custom rules are first-class: configured via rules, disabled with 'off' and useRanklintIgnore. The CheckContext contract is stable within a major version. Presets — via extends (an npm package or a local file); @ranklint/preset-default pins the built-in rules at their default severities — a "live" snapshot of the installed checks version.

Rule packages. A preset in extends (npm package or local file) may carry customChecks together with rules — that is how a team ships its own rule set: extends: ['@myteam/ranklint-rules']. Layers merge; the config itself wins.