Direct answers
question-style headings (What…, How…, …?) must be followed by a paragraph or list that answers them, and the first paragraph should be short enough to quote (--max-answer-words, default 60).
GitHub Packages · MIT · Node ≥ 18
Check that your built static site is ready for answer engines and AI search: direct answers, FAQ schema, llms.txt, AI crawler access and E-E-A-T signals.
Check your built static site is ready for answer engines (AEO): question headings with concise direct answers, FAQPage/QAPage/HowTo schema, llms.txt, AI crawler rules in robots.txt (GPTBot, ClaudeBot, PerplexityBot, Google-Extended) and meta tags, and author/date E-E-A-T signals. SARIF, allowlist, GitHub Action. Zero deps.
1 Point the @mrlouiswright scope at GitHub Packages in .npmrc
@mrlouiswright:registry=https://npm.pkg.github.com2 Install
npm i -D @mrlouiswright/answer-beaconPublished to GitHub Packages, not npmjs.com. GitHub Packages needs a GitHub token with read:packages to install, even for public packages: add //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} to .npmrc or run npm login --registry=https://npm.pkg.github.com.
$ npx answer-beacon dist --base-url https://example.comanswer-beacon — https://example.com6 indexable page(s); 5 question heading(s); robots.txt found; llms.txt found HIGH faq.html:1 Question "No answer?" is missing acceptedAnswer.text [faq-schema-invalid] ↳ fix: Each Question needs "name" and acceptedAnswer with "text".HIGH robots.txt robots.txt blocks GPTBot from / [ai-crawler-blocked] ↳ fix: Add "User-agent: GPTBot\nAllow: /" or remove the Disallow, or move GPTBot to blockBots if this is intended.HIGH robots.txt robots.txt blocks OAI-SearchBot from / (via User-agent: *) [ai-crawler-blocked] ↳ fix: Add "User-agent: OAI-SearchBot\nAllow: /" or remove the Disallow, or move OAI-SearchBot to blockBots if this is intended.HIGH robots.txt robots.txt blocks ChatGPT-User from / (via User-agent: *) [ai-crawler-blocked]
Answer engines (ChatGPT search, Perplexity, Claude, Google AI Overviews) quote pages that answer a question in the first sentence, mark it up, let their crawlers in and show who wrote it and when. Sites lose that in small ways: a blanket “User-agent: * Disallow: /” that also blocks GPTBot, FAQ schema whose questions are not on the page, a question heading followed by a 200-word preamble, an llms.txt with broken links. answer-beacon reads the build, robots.txt and llms.txt and reports each gap with the file, line, severity and a concrete fix.
CLI, library and GitHub Action. Node.js 18+, zero runtime dependencies. Works on any static build output (Astro, Next.js “output: 'export'”, Eleventy, Hugo, Jekyll, Docusaurus, VitePress, plain HTML) and runs offline: point it at the folder your build writes. By Louis Wright.
question-style headings (What…, How…, …?) must be followed by a paragraph or list that answers them, and the first paragraph should be short enough to quote (--max-answer-words, default 60).
every Question needs name and acceptedAnswer.text (QAPage also accepts suggestedAnswer), FAQ questions must be visible on the page, HowTo needs steps with text, and pages answering 3+ questions are nudged to add FAQPage.
present, H1 title, ## sections of - name: notes links, and internal links that exist in the build.
GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-SearchBot, PerplexityBot and Google-Extended allowed by default (--allow-bots), with --block-bots for crawlers you want kept out (CCBot, Bytespider, ...). Uses real robots.txt group and longest-match semantics, including User-agent: * fallback.
noai/noimageai and bot-specific <meta name="GPTBot" content="noindex"> on pages you want quoted.
article-like pages need an author and a date; dateModified must not precede datePublished; homepage Organization/Person/WebSite schema; an About or Contact page.
# Example
npx answer-beacon dist# Example
npx answer-beacon dist --block-bots CCBot,Bytespider --fail-on medium# Example
npx answer-beacon public --allow-bots GPTBot,PerplexityBot --max-answer-words 45# Example
npx answer-beacon out --no-llms-txt --not-articles "/docs/**"permissions:
contents: read
security-events: write # only needed for the SARIF upload
jobs:
answer-beacon:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with: { persist-credentials: false }
- run: npm ci && npm run build # produce the static site first
- uses: MrLouisWright/answer-beacon@v1
with:
path: dist
fail-on: high
sarif: answer-beacon.sarif
- uses: github/codeql-action/upload-sarif@v3
if: always()
with: { sarif_file: answer-beacon.sarif }
| Flag | Description |
|---|---|
| Site | |
--base-url <url> | Public URL of the site, e.g. https://example.com (default: inferred from canonical/og:url) |
--include <globs> | Only check these pages (file or URL path globs, comma-separated) |
--exclude <globs> | Skip these pages |
--clean-urls | Pages are served without .html (about.html -> /about) |
| Checks | |
--allow-bots <names> | AI crawlers that must be allowed in robots.txt (default: GPTBot, OAI-SearchBot, |
--block-bots <names> | AI crawlers that must be blocked |
--max-answer-words <n> | Longest acceptable direct answer paragraph (default 60) |
--no-llms-txt | Do not require /llms.txt |
--not-articles <globs> | Pages that should not be checked for author/date |
| Common | |
-c, --config <file> | JSON config (default: .answer-beacon.json or "answerBeacon" in package.json) |
-f, --format <fmt> | text (default) | json | sarif | markdown |
--json <file> | Also write a JSON report |
--sarif <file> | Also write SARIF 2.1.0 |
--markdown <file> | Also write Markdown (e.g. for a job summary) |
--fail-on <sev> | critical | high | medium | low | info | none (default: high) |
--list-rules | Print rules and default severities |
--no-fixes | Hide fix suggestions in text output |
--no-color | Disable colours |
Full reference, config file format and API in the README.
Support this project
I build free, open-source tools that help developers ship safer websites. Every coffee helps keep them maintained, documented and free for everyone.
Buy me a coffee (opens Stripe in a new tab)Secure checkout by Stripe