Skip to content

This only links to pages of the documentation. It does not write answers.

Write a custom rule

How-to guide

A rule asks typed questions about a page and turns the answers into findings. This guide writes an audience rule for sites whose pages declare an audience frontmatter field, and reports pages written for a different audience than they declare.

If a built-in rule already covers your case, use it instead. Rules are also the way to review the frontmatter of other plugins, like the built-in tags() rule does.

  1. Create a function returning a CompassRule object. The rule asks which audience a page is written for, and compares the answer with the declared one:

    compass-rules.ts
    import type { CompassRule } from "starlight-compass";
    export function audience(): CompassRule {
    return {
    name: "audience",
    getQuestions(page) {
    if (!page.data["audience"]) return;
    return {
    audience: {
    type: "choice",
    instructions: "Which audience is this page written for?",
    options: {
    advanced: "Readers who know the basics and want details, trade-offs or edge cases.",
    beginner: "Readers who are new to the topic and need terms explained.",
    },
    },
    };
    },
    getResult(page, answers) {
    const answer = answers["audience"];
    if (answer?.type !== "choice") return { findings: [] };
    const { choice, confidence } = answer;
    if (choice === page.data["audience"] || confidence < 0.7) {
    return { findings: [] };
    }
    return {
    findings: [
    {
    level: "warning",
    message: `Declared for the audience \`${page.data["audience"]}\` but reads like it is written for \`${choice}\`.`,
    },
    ],
    };
    },
    };
    }

    Ask narrow questions and check the answer’s confidence before reporting a finding, so that uncertain answers don’t produce noise. Returning undefined from getQuestions() skips the page.

  2. Add the rule to your configuration. Keep the built-in rules you want to use, as setting rules replaces the defaults:

    astro.config.mjs
    import starlightCompass, { diataxis, typesafe } from "starlight-compass";
    import { audience } from "./compass-rules";
    export default defineConfig({
    integrations: [
    starlight({
    plugins: [
    starlightCompass({
    provider: typesafe(),
    rules: [diataxis(), audience()],
    }),
    ],
    }),
    ],
    });
  3. Open a page that declares an audience and check the new audience section in the Compass window of the dev toolbar.

The questions of all rules are sent to the provider in a single request, so adding a rule adds almost no latency.

  • Return an empty object from getQuestions() to report findings that need no provider, like a missing frontmatter field. metadata() does this for missing descriptions.
  • Use the context argument to compare a page with all other pages, like duplicates() does.
  • Use score questions for rubrics, and boolean questions for yes-or-no decisions. See Questions and answers.