World
# aeo.js — Answer Engine Optimization for the Modern Web - Complete Documentation
This file contains all documentation concatenated into a single file for easy consumption by LLMs.
> Make your website discoverable by ChatGPT, Claude, Perplexity & AI search engines. Auto-generates llms.txt, robots.txt, sitemap, JSON-LD structured data & more.
## Table of Contents
This document includes all content from this project.
Each section is separated by a horizontal rule (---) for easy parsing.
---
# Contributors
URL: https://aeojs.org/contributors
> The people who make aeo.js possible.
## Contributors
7 contributors have shaped aeo.js. Thank you.
- [rubenmarcus43 commits](https://github.com/rubenmarcus)
- [KimHyeongRae07 commits](https://github.com/KimHyeongRae0)
- [FabioRocha2313 commits](https://github.com/FabioRocha231)
- [ribeiroevandro2 commits](https://github.com/ribeiroevandro)
- [mhanelia2 commits](https://github.com/mhanelia)
- [olucasleitedev1 commit](https://github.com/olucasleitedev)
- [HusseinAdeiza1 commit](https://github.com/HusseinAdeiza)
Want to join them?[Open a PR](https://github.com/rubenmarcus/aeo.js).
Built by[rubenmarcus](https://rubenmarcus.dev)
---
# Audit & Citability
URL: https://aeojs.org/features/audit
> Audit your AEO setup and measure your site
## Audit & Citability
## Site Audit
[Section titled “Site Audit”](#site-audit)
The auditSite function checks your site for AEO best practices and returns a detailed report:
-
import { auditSite, formatAuditReport, getGrade, resolveConfig } from 'aeo.js';
const config = resolveConfig({
title: 'My Site',
url: 'https://mysite.com',
pages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],
});
const result = auditSite(config);
console.log(formatAuditReport(result));
console.log('Grade:', getGrade(result.score));
The audit checks for:
Presence of robots.txt, llms.txt, llms-full.txt
- Sitemap accessibility
- Structured data (JSON-LD)
- Open Graph meta tags
- AI crawler accessibility
You can also run it from the CLI:
Terminal window
npx aeo.js check
## Citability Score
[Section titled “Citability Score”](#citability-score)
Measure how likely AI engines are to cite your content:
import { formatPageCitability, resolveConfig, scorePageCitability, scoreSiteCitability } from 'aeo.js';
// Score a single page
const pageScore = scorePageCitability({
pathname: '/',
title: 'Home',
content: '# Home\n\nMy site publishes practical guides for AI-ready content.',
});
console.log(formatPageCitability(pageScore));
// Score the whole site
const config = resolveConfig({
title: 'My Site',
url: 'https://mysite.com',
pages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],
});
const siteScore = scoreSiteCitability(config);
The citability score evaluates:
- Content structure and headings
- Factual density and specificity
- Source attribution
- Unique data and statistics
- Clear definitions and explanations
## Reports
[Section titled “Reports”](#reports)
Generate a comprehensive AEO report:
import { formatReportJson, formatReportMarkdown, generateReport, resolveConfig } from 'aeo.js';
const config = resolveConfig({
title: 'My Site',
url: 'https://mysite.com',
pages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],
});
const report = generateReport(config);
// Get as markdown
console.log(formatReportMarkdown(report));
// Get as JSON
console.log(formatReportJson(report));
## Platform Hints
[Section titled “Platform Hints”](#platform-hints)
Get platform-specific optimization suggestions:
import { auditSite, generatePlatformHints, resolveConfig, scoreSiteCitability } from 'aeo.js';
const config = resolveConfig({
title: 'My Site',
url: 'https://mysite.com',
pages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],
});
const audit = auditSite(config);
const citability = scoreSiteCitability(config);
const hints = generatePlatformHints(audit, citability);
// Returns platform-specific optimization hints for ChatGPT, Perplexity, Google AI, and Bing Copilot
[Previous
JSON-LD Recipes](/features/json-ld/)[Next
MCP Server](/features/mcp/)
Built by[rubenmarcus](https://rubenmarcus.dev)
---
# CLI
URL: https://aeojs.org/features/cli
> Run aeo.js from the command line without any framework integration.
## CLI
## Usage
[Section titled “Usage”](#usage)
-
Terminal window
npx aeo.js
World
:
: "> ## Programmatic usage [Section titled “Programmatic usage”](#programmatic-usage) Generate AEO files from source routes without a build — files land in public/: import { generate } from 'aeo.js/remix'; await generate({ title: 'My Site', url: 'https://mysite.com' }); ## Configuration [Section titled “Configuration”](#configuration) Pass any [AeoConfig](/reference/configuration/) options to postBuild or generate: import { postBuild } from 'aeo.js/remix'; await postBuild({ title: 'My Site', url: 'https://mysite.com', description: 'A site optimized for AI discovery', schema: { organization: { name: 'My Company' } }, }); [Previous Nuxt](/frameworks/nuxt/)[Next SvelteKit](/frameworks/sveltekit/) Built by[rubenmarcus](https://rubenmarcus.dev) --- # SvelteKit URL: https://aeojs.org/frameworks/sveltekit > Use aeo.js with SvelteKit. ## SvelteKit ## Setup [Section titled “Setup”](#setup) - Install the package: Terminal window npm install aeo.js - Add a post-build step to your package.json: { "scripts": { "postbuild": "node -e \"import('aeo.js/sveltekit').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\"" } } m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\"" }}"> - Build your app: Terminal window npm run build ## How it works [Section titled “How it works”](#how-it-works) The SvelteKit plugin: - Detects the build output: build/ for adapter-static, or .svelte-kit/output for other adapters - Scans prerendered HTML pages for titles, descriptions, and full text content - Scans src/routes for +page.svelte (and mdsvex +page.md/+page.svx) routes — route groups like (marketing) are transparent, dynamic segments like [slug] are skipped - Generates all AEO files (robots.txt, llms.txt, sitemap.xml, ai-index.json, …) into the output directory - Injects the Human/AI widget into every prerendered page Tip For the best results, prerender as much as possible (export const prerender = true in your root +layout.ts). aeo.js extracts content from prerendered HTML — server-rendered-only routes are still listed from source scanning, but without page content. ## Programmatic usage [Section titled “Programmatic usage”](#programmatic-usage) Generate AEO files from source routes without a build — files land in static/ so any adapter ships them: import { generate } from 'aeo.js/sveltekit'; await generate({ title: 'My Site', url: 'https://mysite.com' }); ## Configuration [Section titled “Configuration”](#configuration) Pass any [AeoConfig](/reference/configuration/) options to postBuild or generate: import { postBuild } from 'aeo.js/sveltekit'; await postBuild({ title: 'My Site', url: 'https://mysite.com', description: 'A site optimized for AI discovery', widget: { enabled: true, position: 'bottom-right' }, // Skip widget injection into prerendered HTML: // injectWidget: false, }); [Previous Remix](/frameworks/remix/)[Next TanStack Start](/frameworks/tanstack-start/) Built by[rubenmarcus](https://rubenmarcus.dev) --- # TanStack Start URL: https://aeojs.org/frameworks/tanstack-start > Use aeo.js with TanStack Start and TanStack Router. ## TanStack Start ## Setup [Section titled “Setup”](#setup) - Install the package: Terminal window npm install aeo.js - Add a post-build step to your package.json: { "scripts": { "postbuild": "node -e \"import('aeo.js/tanstack-start').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\"" } } m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\"" }}"> - Build your app: Terminal window npm run build ## How it works [Section titled “How it works”](#how-it-works) The TanStack Start plugin: - Scans src/routes (falling back to app/routes) using the [TanStack Router file conventions](https://tanstack.com/router/latest/docs/routing/file-naming-conventions): flat (.) and directory nesting, index tokens, route.tsx layout tokens, pathless _layout segments, and trailing-underscore un-nesting - Skips routes that can’t be enumerated statically — dynamic params ($postId), splats ($), the __root layout, and -prefixed files - Scans prerendered HTML from the build output (.output/public, dist/client, or dist) for titles, descriptions, and full text content - Generates all AEO files (robots.txt, llms.txt, sitemap.xml, ai-index.json, …) alongside the static assets so they’re served from the site root Tip Dynamic routes are skipped because they can’t be listed at build time. Add them explicitly via the [pages](/reference/configuration/) option — your entries always win over auto-discovered ones. ## Widget [Section titled “Widget”](#widget) TanStack Start renders HTML on the server, so add the widget script once in your root document (src/routes/__root.tsx): src/routes/__root.tsx import { getWidgetScript } from 'aeo.js/tanstack-start'; const widgetScript = getWidgetScript({ title: 'My Site', url: 'https://mysite.com', }); // In your root document body, before :
: "> ## Programmatic usage [Section titled “Programmatic usage”](#programmatic-usage) No build output yet? Generate AEO files from source routes only — files land in public/: import { generate } from 'aeo.js/tanstack-start'; await generate({ title: 'My Site', url: 'https://mysite.com' }); ## Configuration [Section titled “Configuration”](#configuration) Pass any [AeoConfig](/reference/configuration/) options to postBuild or generate: import { postBuild } from 'aeo.js/tanstack-start'; await postBuild({ title: 'My Site', url: 'https://mysite.com', description: 'A site optimized for AI discovery', schema: { organization: { name: 'My Company' } }, }); [Previous SvelteKit](/frameworks/sveltekit/)[Next Angular](/frameworks/angular/) Built by[rubenmarcus](https://rubenmarcus.dev) --- # Vanilla JS / Static HTML URL: https://aeojs.org/frameworks/vanilla > Use aeo.js with a plain HTML site, hand-rolled JS, or any static-site generator — no framework required. ## Vanilla JS / Static HTML aeo.js works on any project that produces static HTML. Use the CLI directly — no plugin, no module, no framework. ## Quick Start [Section titled “Quick Start”](#quick-start) - [Zero-install (npx)](#tab-panel-4) - [Installed](#tab-panel-5) - Terminal window npx aeo.js generate --url https://mysite.com --title "My Site" --out public ** Terminal window npm install --save-dev aeo.js npx aeo.js generate --url https://mysite.com --title "My Site" --out public generate walks your output directory, extracts page content, and emits robots.txt, llms.txt, sitemap.xml, ai-index.json, and schema.json next to your HTML. Caution The standalone CLI configures itself from flags only** — it does not load aeo.config.{ts,js}. Pass --url / --title / --out on the command line, or call the package’s API programmatically (see “Calling the API directly” below) to access richer options like contentDir and pages. ## How aeo.js Discovers Your Pages [Section titled “How aeo.js Discovers Your Pages”](#how-aeojs-discovers-your-pages) Source How to set Use when **Built HTML in outDir** --out public (CLI) You have a built static site with *.html files **contentDir** programmatic only — see below You have handwritten .md / .mdx files **pages array** programmatic only — see below Explicit control for runtime-only routes The CLI exposes --out for outDir. For the richer options (contentDir, pages), call the package’s API directly: scripts/aeo.mjs import { generateAEOFiles, resolveConfig } from 'aeo.js'; await generateAEOFiles(resolveConfig({ title: 'My Site', url: 'https://mysite.com', contentDir: 'content', outDir: 'public', pages: [{ pathname: '/', title: 'Home' }], })); ## Common Setups [Section titled “Common Setups”](#common-setups) ### Hand-rolled HTML site [Section titled “Hand-rolled HTML site”](#hand-rolled-html-site) package.json { "scripts": { "build:aeo": "aeo.js generate --url https://mysite.com --title \"My Site\" --out ." } } ### Eleventy / Hugo / Jekyll [Section titled “Eleventy / Hugo / Jekyll”](#eleventy--hugo--jekyll) package.json { "scripts": { "build": "eleventy", "postbuild": "aeo.js generate --url https://mysite.com --title \"My Site\" --out _site" } } For Hugo use --out public; for Jekyll --out _site. The postbuild script runs automatically after npm run build. ### Markdown blog (no framework) [Section titled “Markdown blog (no framework)”](#markdown-blog-no-framework) The CLI’s --out flag covers built HTML; to also pull .md front-matter and bodies from a contentDir, use the programmatic API: scripts/aeo.mjs import { generateAEOFiles, resolveConfig } from 'aeo.js'; await generateAEOFiles(resolveConfig({ title: 'My Blog', url: 'https://myblog.dev', contentDir: 'content', // pull post bodies from here outDir: 'public', // write generated files here })); package.json { "scripts": { "build:aeo": "node scripts/aeo.mjs" } } ## Adding the Widget [Section titled “Adding the Widget”](#adding-the-widget) Or install and bundle locally with import { AeoWidget } from 'aeo.js/widget'. ## CI Integration [Section titled “CI Integration”](#ci-integration) - run: npx aeo.js check --json | tee audit.json - run: | SCORE=$(jq '.audit.score' audit.json) ["$SCORE" -ge 70] || { echo "GEO score $SCORE below 70"; exit 1; } Note Full walkthrough with deployment recipes (Vercel, Netlify, Cloudflare, GitHub Pages) is in the [Vanilla Guide on GitHub](https://github.com/rubenmarcus/aeo.js/blob/main/docs/vanilla.md). ## Further Reading [Section titled “Further Reading”](#further-reading) [CLI Reference](/features/cli/) — every command, every flag - [JSON-LD Recipes](/features/json-ld/) — FAQ, HowTo, Product, Article, Recipe, Event - [Configuration Reference](/reference/configuration/) [Previous Webpack](/frameworks/webpack/)[Next Generated Files](/features/generated-files/) Built by[rubenmarcus](https://rubenmarcus.dev) --- # Vite URL: https://aeojs.org/frameworks/vite > Use aeo.js with Vite (React, Vue, Svelte, etc.). ## Vite ## Setup [Section titled “Setup”](#setup) - Install the package: Terminal window npm install aeo.js - Add the plugin to your Vite config: vite.config.ts import { defineConfig } from 'vite'; import { aeoVitePlugin } from 'aeo.js/vite'; export default defineConfig({ plugins: [aeoVitePlugin({ title: 'My Site', description: 'A site optimized for AI discovery', url: 'https://mysite.com', }),], }); ## How it works [Section titled “How it works”](#how-it-works) The Vite plugin: - Generates AEO files on both vite dev and vite build - Injects the Human/AI widget automatically via HTML transform - Serves dynamic .md files during development (extracts content from your running app) - Detects SPA shells and falls back to client-side DOM extraction - Works with React, Vue, Svelte, or any Vite-based framework ## Configuration [Section titled “Configuration”](#configuration) Pass any [AeoConfig](/reference/configuration/) options to the plugin: aeoVitePlugin({ title: 'My Site', url: 'https://mysite.com', widget: { position: 'top-right', theme: { background: 'rgba(0, 0, 0, 0.85)', accent: '#f59e0b', }, }, }); [Previous Next.js](/frameworks/nextjs/)[Next Nuxt](/frameworks/nuxt/) Built by[rubenmarcus](https://rubenmarcus.dev) --- # VitePress URL: https://aeojs.org/frameworks/vitepress > Use aeo.js with VitePress documentation sites. ## VitePress ## Setup [Section titled “Setup”](#setup) - Install the package: Terminal window npm install aeo.js ** - Wrap your config in .vitepress/config.ts: import { defineConfig } from 'vitepress'; import { withAeo } from 'aeo.js/vitepress'; export default defineConfig( withAeo( { title: 'My Docs', description: 'My documentation site', // …the rest of your VitePress config… }, { url: 'https://mysite.com' } ) ); - Build your site: Terminal window npm run docs:build ## How it works [Section titled “How it works”](#how-it-works) withAeo(config, options) wraps your VitePress config and composes two build hooks: - transformHtml** — runs per page during the build. It collects each page’s URL, title, description, and rendered text content, and injects the AEO widget before . - **buildEnd** — after the build, generates all AEO files (robots.txt, llms.txt, sitemap.xml, ai-index.json, …) into the VitePress output directory. url, title, and description default from your VitePress site config (and sitemap.hostname) when omitted. Tip Any transformHtml or buildEnd hooks you already define are preserved — they run first, then aeo.js adds its behavior. These hooks only run during vitepress build, not the dev server. ## Configuration [Section titled “Configuration”](#configuration) Pass any [AeoConfig](/reference/configuration/) options as the second argument. Add pages VitePress doesn’t emit via pages — your entries always win: withAeo(config, { url: 'https://mysite.com', title: 'My Docs', schema: { organization: { name: 'My Company' } }, }); [Previous Eleventy](/frameworks/eleventy/)[Next Webpack](/frameworks/webpack/) Built by[rubenmarcus](https://rubenmarcus.dev) --- # Webpack URL: https://aeojs.org/frameworks/webpack > Use aeo.js with Webpack. ## Webpack ## Setup [Section titled “Setup”](#setup) - Install the package: Terminal window npm install aeo.js - Add the plugin to your Webpack config: webpack.config.js const { AeoWebpackPlugin } = require('aeo.js/webpack'); module.exports = { plugins: [new AeoWebpackPlugin({ title: 'My Site', description: 'A site optimized for AI discovery', url: 'https://mysite.com', }),], }; ## How it works [Section titled “How it works”](#how-it-works) The Webpack plugin: - Runs during the emit phase of the Webpack compilation - Generates all AEO files in your output directory - Injects the widget into your HTML entry point ## Configuration [Section titled “Configuration”](#configuration) Pass any [AeoConfig](/reference/configuration/) options to the plugin: new AeoWebpackPlugin({ title: 'My Site', url: 'https://mysite.com', widget: { enabled: true, position: 'bottom-right', }, }); [Previous VitePress](/frameworks/vitepress/)[Next Vanilla JS / Static HTML](/frameworks/vanilla/) Built by[rubenmarcus](https://rubenmarcus.dev) --- # Installation URL: https://aeojs.org/getting-started/installation > Install aeo.js in your project. ## Installation ## Install the package [Section titled “Install the package”](#install-the-package) - [npm](#tab-panel-6) - [pnpm](#tab-panel-7) - [yarn](#tab-panel-8) - Terminal window npm install aeo.js ** Terminal window pnpm add aeo.js Terminal window yarn add aeo.js ## Or use the CLI directly [Section titled “Or use the CLI directly”](#or-use-the-cli-directly) No installation needed — run it with npx: Terminal window npx aeo.js generate ## Requirements [Section titled “Requirements”](#requirements) Node.js** 18 or later - A framework with a build step that outputs HTML (or use the CLI for any static site) ## Next steps [Section titled “Next steps”](#next-steps) Head to [Quick Start](/getting-started/quick-start/) to add aeo.js to your project, or jump to your framework’s guide: - [Astro](/frameworks/astro/) - [Next.js](/frameworks/nextjs/) - [Vite](/frameworks/vite/) - [Nuxt](/frameworks/nuxt/) - [Angular](/frameworks/angular/) - [Webpack](/frameworks/webpack/) [Previous Introduction](/getting-started/introduction/)[Next Quick Start](/getting-started/quick-start/) Built by[rubenmarcus](https://rubenmarcus.dev) --- # Introduction URL: https://aeojs.org/getting-started/introduction > What is aeo.js and why you need Answer Engine Optimization. ## Introduction ## What is Answer Engine Optimization? [Section titled “What is Answer Engine Optimization?”](#what-is-answer-engine-optimization) Answer Engine Optimization (AEO) is the practice of making your website discoverable and citable by AI-powered answer engines like **ChatGPT**, **Claude**, **Perplexity**, and **SearchGPT**. Unlike traditional SEO which focuses on search engine result pages (SERPs), AEO ensures your content is understood and referenced by Large Language Models (LLMs) when they generate answers. ## Why aeo.js? [Section titled “Why aeo.js?”](#why-aeojs) AI crawlers and LLMs look for specific files and formats that most websites don’t provide: - **llms.txt** — A concise summary of your site written for LLMs - **llms-full.txt** — Full content concatenated for deep ingestion - **ai-index.json** — Structured content optimized for RAG pipelines - **docs.json** — Documentation manifest for content discovery - **Raw Markdown** — Per-page .md files for clean content extraction **aeo.js** generates all of these automatically from your existing pages — no manual work required. ## How it works [Section titled “How it works”](#how-it-works) - **Install** the package and add the plugin for your framework - **Build** your site as usual - **aeo.js** scans your output, extracts content, and generates all AEO files - The optional **widget** lets visitors toggle between human and AI views of your pages ## Scope: what aeo.js does and doesn’t influence [Section titled “Scope: what aeo.js does and doesn’t influence”](#scope-what-aeojs-does-and-doesnt-influence) AEO is the **on-site** half of being discoverable by AI engines — there’s an off-site half that aeo.js cannot reach. Setting expectations upfront so you can plan a full strategy: What aeo.js does well Improves machine-readable access to **your own site**: - generates llms.txt, llms-full.txt, ai-index.json, raw markdown copies, JSON-LD schema, and a sitemap - structures content so AI crawlers can fetch, parse, and quote it - audits and scores your page-level citability so you know where to improve What aeo.js cannot influence Off-site signals that AI engines also weigh: - **third-party mentions and reviews** of your product across the web - **inbound links** and how reputable the linking domains are - **community discussions** (Reddit, Hacker News, X, niche forums) and how often you’re cited there - **model training data** — what an LLM “already knows” about you from its pre-training cutoff - **freshness signals** outside your control (independent news, blog roundups, podcasts) Think of aeo.js as a strong foundation — necessary but not sufficient. For full AEO coverage, pair it with the off-site work above: PR, community engagement, and being mentioned where your customers research. ## Supported Frameworks [Section titled “Supported Frameworks”](#supported-frameworks) Framework Import Astro aeo.js/astro Next.js aeo.js/next Vite (React, Vue, Svelte) aeo.js/vite Nuxt aeo.js/nuxt Angular aeo.js/angular Webpack aeo.js/webpack Any (CLI) npx aeo.js generate [Next Installation](/getting-started/installation/) Built by[rubenmarcus](https://rubenmarcus.dev) --- # Quick Start URL: https://aeojs.org/getting-started/quick-start > Get aeo.js running in under 2 minutes. ## Quick Start The fastest way to add AEO to your site depends on your framework. ## Astro [Section titled “Astro”](#astro) - Install the package: Terminal window npm install aeo.js - Add the integration to your Astro config: astro.config.mjs import { defineConfig } from 'astro/config'; import { aeoAstroIntegration } from 'aeo.js/astro'; export default defineConfig({ site: 'https://mysite.com', integrations: [aeoAstroIntegration({ title: 'My Site', description: 'A site optimized for AI discovery', url: 'https://mysite.com', }),], }); - Build your site — all AEO files are generated automatically. ## Next.js [Section titled “Next.js”](#nextjs) - Install the package: Terminal window npm install aeo.js - Wrap your Next.js config: next.config.mjs import { withAeo } from 'aeo.js/next'; export default withAeo({ aeo: { title: 'My Site', description: 'A site optimized for AI discovery', url: 'https://mysite.com', }, }); - Add the post-build step to package.json: { "scripts": { "postbuild": "node -e \"import('aeo.js/next').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\"" } } m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\"" }}"> ## Vite [Section titled “Vite”](#vite) - Install the package: Terminal window npm install aeo.js - Add the plugin to your Vite config: vite.config.ts import { defineConfig } from 'vite'; import { aeoVitePlugin } from 'aeo.js/vite'; export default defineConfig({ plugins: [aeoVitePlugin({ title: 'My Site', description: 'A site optimized for AI discovery', url: 'https://mysite.com', }),], }); ## CLI (any site) [Section titled “CLI (any site)”](#cli-any-site) No framework integration needed: Terminal window npx aeo.js generate --url https://mysite.com --title "My Site" See [CLI docs](/features/cli/) for all commands and options. [Previous Installation](/getting-started/installation/)[Next Astro](/frameworks/astro/) Built by[rubenmarcus](https://rubenmarcus.dev) --- # aeo.js — Answer Engine Optimization for the Modern Web URL: https://aeojs.org > Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs. ## aeo.js [Get Started](/getting-started/introduction/) **InstallAuditGenerateConfig $▌ added 1 package in 2s Ready — run npx aeo.js init to get started $▌ GEO Readiness Score: 92/100 (Excellent) ══════════════════════════════════════ AI Access: 20/20 Content Structure: 20/20 Schema Presence: 20/20 Meta Quality: 16/20 Citability: 16/20 $▌ [aeo.js] Generating AEO files... robots.txt — AI crawler directives llms.txt — LLM summary llms-full.txt — full content for LLMs sitemap.xml — sitemap schema.json — JSON-LD structured data ai-index.json — AI content index Generated 6 files in 42ms // aeo.config.ts import { defineConfig } from 'aeo.js' export default defineConfig({ title: 'My Site', url: 'https://mysite.com', schema: { organization: { name: 'My Co' } }, widget: { size: 'small' }, }); - [Quick Start](#quick-start) - [What is AEO?](#what-is-aeo) - [Why AEO](#why-aeo-matters) - [Widget](#widget) - [Configuration](#configuration) - [Generated Files](#generated-files) - [Checker](#checker) ## Quick Start [Section titled “Quick Start”](#quick-start) - Terminal window npm install aeo.js [Astro](#tab-panel-9) - [Next.js](#tab-panel-10) - [Vite](#tab-panel-11) - [Nuxt](#tab-panel-12) - [Angular](#tab-panel-13) - [Webpack](#tab-panel-14) - [CLI](#tab-panel-15) astro.config.mjs import { defineConfig } from 'astro/config'; import { aeoAstroIntegration } from 'aeo.js/astro'; export default defineConfig({ site: 'https://mysite.com', integrations: [aeoAstroIntegration({ title: 'My Site', description: 'A site optimized for AI discovery', url: 'https://mysite.com', }),], }); next.config.mjs import { withAeo } from 'aeo.js/next'; export default withAeo({ aeo: { title: 'My Site', description: 'A site optimized for AI discovery', url: 'https://mysite.com', }, }); Add the post-build step to package.json: { "scripts": { "postbuild": "node -e \"import('aeo.js/next').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\"" } } m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\"" }}"> vite.config.ts import { defineConfig } from 'vite'; import { aeoVitePlugin } from 'aeo.js/vite'; export default defineConfig({ plugins: [aeoVitePlugin({ title: 'My Site', description: 'A site optimized for AI discovery', url: 'https://mysite.com', }),], }); nuxt.config.ts export default defineNuxtConfig({ modules: ['aeo.js/nuxt'], aeo: { title: 'My Site', description: 'A site optimized for AI discovery', url: 'https://mysite.com', }, }); Add a post-build step to package.json: { "scripts": { "postbuild": "node -e \"import('aeo.js/angular').then(m => m.postBuild({ title: 'My App', url: 'https://myapp.com' }))\"" } } m.postBuild({ title: 'My App', url: 'https://myapp.com' }))\"" }}"> Or generate programmatically: import { generate } from 'aeo.js/angular'; await generate({ title: 'My App', url: 'https://myapp.com' }); webpack.config.js const { AeoWebpackPlugin } = require('aeo.js/webpack'); module.exports = { plugins: [new AeoWebpackPlugin({ title: 'My Site', description: 'A site optimized for AI discovery', url: 'https://mysite.com', }),], }; No framework needed — run standalone: Terminal window # Generate all AEO files npx aeo.js generate --url https://mysite.com --title "My Site" # Scaffold a config file npx aeo.js init # Check your setup npx aeo.js check ## What is AEO? [Section titled “What is AEO?”](#what-is-aeo) Answer Engine Optimization (AEO) is the practice of making your website discoverable and citable by AI-powered answer engines like ChatGPT, Claude, Perplexity, and SearchGPT. aeo.js** auto-generates the files these engines look for and provides a drop-in widget that shows visitors how your site appears to AI. First-class support for Astro, Next.js, Vite, Nuxt, Angular, and Webpack — or run standalone via CLI. ## Why AEO matters [Section titled “Why AEO matters”](#why-aeo-matters) 58% of searches end without a click — AI gives the answer directly 40% of Gen Z prefer AI assistants over traditional search engines 97% of sites have no llms.txt or structured data for AI crawlers 1 min to set up aeo.js generates robots.txt, llms.txt, schema & more If your site isn’t optimized for AI engines, you’re invisible to a growing share of users who never open a search results page. AEO is the new SEO. ## Widget [Section titled “Widget”](#widget) The Human/AI widget lets visitors toggle between the normal page and its AI-readable markdown version. Framework plugins inject it automatically — for Next.js or manual setups: 'use client'; import { useEffect } from 'react'; export function AeoWidgetLoader() { useEffect(() => { import('aeo.js/widget').then(({ AeoWidget }) => { new AeoWidget({ config: { title: 'My Site', url: 'https://mysite.com', widget: { enabled: true, position: 'bottom-right' }, }, }); }); }, []); return null; } { import('aeo.js/widget').then(({ AeoWidget }) => { new AeoWidget({ config: { title: 'My Site', url: 'https://mysite.com', widget: { enabled: true, position: 'bottom-right' }, }, }); }); }, []); return null;}"> React and Vue wrapper components are also available: - [React](#tab-panel-16) - [Vue](#tab-panel-17) import { AeoReactWidget } from 'aeo.js/react'; <AeoReactWidget config={{ title: 'My Site', url: 'https://mysite.com' }} /> "> <script setup> import { AeoVueWidget } from 'aeo.js/vue'; </script> <template> <AeoVueWidget :config="{ title: 'My Site', url: 'https://mysite.com' }" /> </template> "> ## Configuration [Section titled “Configuration”](#configuration) All frameworks use the same config shape — [see full reference](/reference/configuration/): import { defineConfig } from 'aeo.js'; export default defineConfig({ title: 'My Site', url: 'https://mysite.com', description: 'A site optimized for AI discovery', generators: { robotsTxt: true, llmsTxt: true, llmsFullTxt: true, rawMarkdown: true, sitemap: true, aiIndex: true, schema: true, }, schema: { enabled: true, organization: { name: 'My Company', url: 'https://mysite.com' }, defaultType: 'WebPage', }, og: { enabled: true, image: 'https://mysite.com/og.png', twitterHandle: '@mycompany', }, widget: { enabled: true, position: 'bottom-right', theme: { accent: '#4ADE80', badge: '#4ADE80' }, }, }); ## Generated Files [Section titled “Generated Files”](#generated-files) After building, your output directory contains: public/ ├── robots.txt # AI-crawler directives ├── llms.txt # Short LLM-readable summary ├── llms-full.txt # Full content for LLMs ├── sitemap.xml # Standard sitemap ├── docs.json # Documentation manifest ├── ai-index.json # AI content index ├── index.md # Markdown for / └── about.md # Markdown for /about ## Checker [Section titled “Checker”](#checker) Scan Free — no signup required. Powered by [AEO Checker](https://check.aeojs.org) ## Built by [](https://github.com/rubenmarcus)[](https://github.com/KimHyeongRae0)[](https://github.com/FabioRocha231)[](https://github.com/ribeiroevandro)[](https://github.com/mhanelia)[](https://github.com/olucasleitedev)[](https://github.com/HusseinAdeiza) [View all 7 contributors →](/contributors/) Built by[rubenmarcus](https://rubenmarcus.dev) --- # API Reference URL: https://aeojs.org/reference/api > Programmatic API for aeo.js. ## API Reference ## Core [Section titled “Core”](#core) ### defineConfig(config) [Section titled “defineConfig(config)”](#defineconfigconfig) Type-safe configuration helper: import { defineConfig } from 'aeo.js'; export default defineConfig({ title: 'My Site', url: 'https://mysite.com', }); ** ### generateAll(config) [Section titled “generateAll(config)”](#generateallconfig) Generate all AEO files programmatically: import { generateAll } from 'aeo.js'; await generateAll({ title: 'My Site', url: 'https://mysite.com', outDir: 'dist', }); ### resolveConfig(config) [Section titled “resolveConfig(config)”](#resolveconfigconfig) Resolve a partial config into a fully resolved config with defaults: import { resolveConfig } from 'aeo.js'; const resolved = resolveConfig({ title: 'My Site' }); // All fields now have defaults The examples below use resolvedConfig for a config object returned by resolveConfig. ### validateConfig(config) [Section titled “validateConfig(config)”](#validateconfigconfig) Validate a config object and return any errors: import { validateConfig } from 'aeo.js'; const errors = validateConfig(config); ### detectFramework() [Section titled “detectFramework()”](#detectframework) Auto-detect the framework used in the current project: import { detectFramework } from 'aeo.js'; const info = detectFramework(); // { framework: 'next', contentDir: 'pages', outDir: '.next' } ## HTML Extraction [Section titled “HTML Extraction”](#html-extraction) ### htmlToMarkdown(html, pagePath, config) [Section titled “htmlToMarkdown(html, pagePath, config)”](#htmltomarkdownhtml-pagepath-config) Convert HTML to clean markdown: import { htmlToMarkdown } from 'aeo.js'; const md = htmlToMarkdown( '