{
  "version": "1.0",
  "generated": "2026-05-14T14:44:15.540Z",
  "site": {
    "title": "aeo.js — Answer Engine Optimization for the Modern Web",
    "description": "Make your website discoverable by ChatGPT, Claude, Perplexity & AI search engines. Auto-generates llms.txt, robots.txt, sitemap, JSON-LD structured data & more.",
    "url": "https://aeojs.org"
  },
  "entries": [
    {
      "id": "0816ca1a8e7bd810",
      "url": "https://aeojs.org/getting-started/installation",
      "title": "Installation",
      "content": "## Installation\n\n## Install the package\n\n[Section titled “Install the package”](#install-the-package)\n\n- [npm](#tab-panel-6)\n- [pnpm](#tab-panel-7)\n- [yarn](#tab-panel-8)\n\n-\n\nTerminal window\n\nnpm install aeo.js\n\n**\n\nTerminal window\n\npnpm add aeo.js\n\nTerminal window\n\nyarn add aeo.js\n\n## Or use the CLI directly\n\n[Section titled “Or use the CLI directly”](#or-use-the-cli-directly)\n\nNo installation needed — run it with npx:\n\nTerminal window\n\nnpx aeo.js generate\n\n## Requirements\n\n[Section titled “Requirements”](#requirements)\n\nNode.js** 18 or later\n\n- A framework with a build step that outputs HTML (or use the CLI for any static site)\n\n## Next steps\n\n[Section titled “Next steps”](#next-steps)\n\nHead to [Quick Start](/getting-started/quick-start/) to add aeo.js to your project, or jump to your framework’s guide:\n\n- [Astro](/frameworks/astro/)\n\n- [Next.js](/frameworks/nextjs/)\n\n- [Vite](/frameworks/vite/)\n\n- [Nuxt](/frameworks/nuxt/)\n\n- [Angular](/frameworks/angular/)\n\n- [Webpack](/frameworks/webpack/)\n\n[Previous\nIntroduction](/getting-started/introduction/) [Next\nQuick Start](/getting-started/quick-start/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Install aeo.js in your project.",
      "keywords": [
        "frameworks",
        "next",
        "install",
        "section",
        "titled",
        "terminal",
        "window",
        "quick",
        "start",
        "package"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "/getting-started/installation"
      }
    },
    {
      "id": "08b80cf6344e0500",
      "url": "https://aeojs.org/docs/index",
      "title": "aeo.js (Part 1)",
      "content": "import { Tabs, TabItem } from '@astrojs/starlight/components';\nimport StickyNav from '../../components/StickyNav.astro';\nimport HomepageContributors from '../../components/HomepageContributors.astro';\n\n<StickyNav />\n\n## Quick Start\n\n```bash\nnpm install aeo.js\n```\n\n<Tabs>\n  <TabItem label=\"Astro\">\n    ```js\n    // astro.config.mjs\n    import { defineConfig } from 'astro/config';\n    import { aeoAstroIntegration } from 'aeo.js/astro';\n\n    export default defineConfig({\n      site: 'https://mysite.com',\n      integrations: [\n        aeoAstroIntegration({\n          title: 'My Site',\n          description: 'A site optimized for AI discovery',\n          url: 'https://mysite.com',\n        }),\n      ],\n    });\n    ```\n  </TabItem>\n  <TabItem label=\"Next.js\">\n    ```js\n    // next.config.mjs\n    import { withAeo } from 'aeo.js/next';\n\n    export default withAeo({\n      aeo: {\n        title: 'My Site',\n        description: 'A site optimized for AI discovery',\n        url: 'https://mysite.com',\n      },\n    });\n    ```\n\n    Add the post-build step to `package.json`:\n\n    ```json\n    {\n      \"scripts\": {\n        \"postbuild\": \"node -e \\\"import('aeo.js/next').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\\\"\"\n      }\n    }\n    ```\n  </TabItem>\n  <TabItem label=\"Vite\">\n    ```js\n    // vite.config.ts\n    import { defineConfig } from 'vite';\n    import { aeoVitePlugin } from 'aeo.js/vite';",
      "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
      "keywords": [
        "class",
        "site",
        "tabitem",
        "https",
        "import",
        "mysite",
        "from",
        "label",
        "title",
        "config"
      ],
      "metadata": {
        "title": "aeo.js",
        "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
        "template": "splash",
        "head": "",
        "- tag": "title",
        "content": "aeo.js — Answer Engine Optimization for the Modern Web",
        "hero": "",
        "tagline": "Make your site discoverable by ChatGPT, Claude, Perplexity, and every AI answer engine, automatically.",
        "actions": "",
        "- text": "Get Started",
        "link": "/getting-started/introduction/",
        "icon": "right-arrow",
        "variant": "primary",
        "chunkIndex": 0,
        "totalChunks": 5,
        "sourcePath": "docs/index.mdx"
      }
    },
    {
      "id": "09292d6d1c3a1639",
      "url": "https://aeojs.org/frameworks/vanilla",
      "title": "Vanilla JS / Static HTML (Part 1)",
      "content": "## Vanilla JS / Static HTML\n\naeo.js works on any project that produces static HTML. Use the CLI directly — no plugin, no module, no framework.\n\n## Quick Start\n\n[Section titled “Quick Start”](#quick-start)\n\n- [Zero-install (npx)](#tab-panel-4)\n- [Installed](#tab-panel-5)\n\n-\n\nTerminal window\n\nnpx aeo.js generate --url https://mysite.com --title \"My Site\" --out public\n\n**\n\nTerminal window\n\nnpm install --save-dev aeo.js\n\nnpx aeo.js generate --url https://mysite.com --title \"My Site\" --out public\n\ngenerate 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.\n\nCaution\n\nThe 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.\n\n## How aeo.js Discovers Your Pages\n\n[Section titled “How aeo.js Discovers Your Pages”](#how-aeojs-discovers-your-pages)\n\nSource\n\nHow to set\n\nUse when\n\n**Built HTML in outDir**\n\n--out public (CLI)\n\nYou have a built static site with *.html files\n\n**contentDir**\n\nprogrammatic only — see below\n\nYou have handwritten .md / .mdx files\n\n**pages array**\n\nprogrammatic only — see below\n\nExplicit control for runtime-only routes\n\nThe CLI exposes --out for outDir. For the richer options (contentDir, pages), call the package’s API directly:\n\nscripts/aeo.mjs\n\nimport { generateAEOFiles, resolveConfig } from 'aeo.js';\n\nawait generateAEOFiles(resolveConfig({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\ncontentDir: 'content',\n\noutDir: 'public',\n\npages: [{ pathname: '/', title: 'Home' }],\n\n}));\n\n## Common Setups\n\n[Section titled “Common Setups”](#common-setups)\n\n### Hand-rolled HTML site\n\n[Section titled “Hand-rolled HTML site”](#hand-rolled-html-site)\n\npackage.json\n\n{\n\n\"scripts\": {",
      "description": "Use aeo.js with a plain HTML site, hand-rolled JS, or any static-site generator — no framework required.",
      "keywords": [
        "site",
        "https",
        "json",
        "html",
        "section",
        "titled",
        "title",
        "pages",
        "from",
        "mysite"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 3,
        "sourcePath": "/frameworks/vanilla"
      }
    },
    {
      "id": "0afad6fbf6fcf829",
      "url": "https://aeojs.org",
      "title": "aeo.js — Answer Engine Optimization for the Modern Web (Part 1)",
      "content": "## aeo.js\n\n[Get Started](/getting-started/introduction/)\n\n**Install Audit Generate Config\n\n$ ▌\n\nadded 1 package in 2s\n\nReady — run npx aeo.js init to get started\n\n$ ▌\n\nGEO Readiness Score: 92/100 (Excellent)\n\n══════════════════════════════════════\n\nAI Access: 20/20\n\nContent Structure: 20/20\n\nSchema Presence: 20/20\n\nMeta Quality: 16/20\n\nCitability: 16/20\n\n$ ▌\n\n[aeo.js] Generating AEO files...\n\nrobots.txt — AI crawler directives\n\nllms.txt — LLM summary\n\nllms-full.txt — full content for LLMs\n\nsitemap.xml — sitemap\n\nschema.json — JSON-LD structured data\n\nai-index.json — AI content index\n\nGenerated 6 files in 42ms\n\n// aeo.config.ts\n\nimport { defineConfig } from 'aeo.js'\n\nexport default defineConfig({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\nschema: { organization: { name: 'My Co' } },\n\nwidget: { size: 'small' },\n\n});\n\n- [Quick Start](#quick-start)\n- [What is AEO?](#what-is-aeo)\n- [Why AEO](#why-aeo-matters)\n- [Widget](#widget)\n- [Configuration](#configuration)\n- [Generated Files](#generated-files)\n- [Checker](#checker)\n\n## Quick Start\n\n[Section titled “Quick Start”](#quick-start)\n\n-\n\nTerminal window\n\nnpm install aeo.js\n\n[Astro](#tab-panel-9)\n- [Next.js](#tab-panel-10)\n- [Vite](#tab-panel-11)\n- [Nuxt](#tab-panel-12)\n- [Angular](#tab-panel-13)\n- [Webpack](#tab-panel-14)\n- [CLI](#tab-panel-15)\n\nastro.config.mjs\n\nimport { defineConfig } from 'astro/config';\n\nimport { aeoAstroIntegration } from 'aeo.js/astro';\n\nexport default defineConfig({\n\nsite: 'https://mysite.com',\n\nintegrations: [aeoAstroIntegration({\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n}),],\n\n});\n\nnext.config.mjs\n\nimport { withAeo } from 'aeo.js/next';\n\nexport default withAeo({\n\naeo: {\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n},\n\n});\n\nAdd the post-build step to package.json:\n\n{\n\n\"scripts\": {",
      "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
      "keywords": [
        "https",
        "site",
        "title",
        "mysite",
        "import",
        "config",
        "widget",
        "true",
        "from",
        "files"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 4,
        "sourcePath": "/"
      }
    },
    {
      "id": "161a43e79cc6ec42",
      "url": "https://aeojs.org/docs/reference/configuration",
      "title": "Configuration (Part 3)",
      "content": "| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `enabled` | `boolean` | `false` | Enable schema generation |\n| `organization.name` | `string` | `''` | Organization name |\n| `organization.url` | `string` | `''` | Organization URL |\n| `organization.logo` | `string` | `''` | Organization logo URL |\n| `organization.sameAs` | `string[]` | `[]` | Social profile URLs |\n| `defaultType` | `'Article' \\| 'WebPage'` | `'WebPage'` | Default schema type for pages |\n\n### `og`\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `enabled` | `boolean` | `false` | Enable OG tag generation |\n| `image` | `string` | `''` | Default OG image URL |\n| `twitterHandle` | `string` | `''` | Twitter handle (e.g. `@company`) |\n| `type` | `'website' \\| 'article'` | `'website'` | Default OG type |\n\n### `widget`\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `enabled` | `boolean` | `true` | Enable the widget |\n| `position` | `string` | `'bottom-right'` | Widget position |\n| `humanLabel` | `string` | `'Human'` | Label for human view |\n| `aiLabel` | `string` | `'AI'` | Label for AI view |\n| `showBadge` | `boolean` | `true` | Show the AEO badge |\n| `theme.background` | `string` | `'rgba(18, 18, 24, 0.9)'` | Widget background |\n| `theme.text` | `string` | `'#C0C0C5'` | Text color |\n| `theme.accent` | `string` | `'#E8E8EA'` | Accent color |\n| `theme.badge` | `string` | `'#4ADE80'` | Badge color |",
      "description": "Full configuration reference for aeo.js.",
      "keywords": [
        "true",
        "string",
        "boolean",
        "default",
        "description",
        "type",
        "organization",
        "generate",
        "sitemap",
        "option"
      ],
      "metadata": {
        "title": "Configuration",
        "description": "Full configuration reference for aeo.js.",
        "chunkIndex": 2,
        "totalChunks": 3,
        "sourcePath": "docs/reference/configuration.mdx"
      }
    },
    {
      "id": "1723a3fa6d3c26d2",
      "url": "https://aeojs.org/getting-started/quick-start",
      "title": "Quick Start (Part 1)",
      "content": "## Quick Start\n\nThe fastest way to add AEO to your site depends on your framework.\n\n## Astro\n\n[Section titled “Astro”](#astro)\n\n-\nInstall the package:\n\nTerminal window\n\nnpm install aeo.js\n\n-\nAdd the integration to your Astro config:\n\nastro.config.mjs\n\nimport { defineConfig } from 'astro/config';\n\nimport { aeoAstroIntegration } from 'aeo.js/astro';\n\nexport default defineConfig({\n\nsite: 'https://mysite.com',\n\nintegrations: [aeoAstroIntegration({\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n}),],\n\n});\n\n-\nBuild your site — all AEO files are generated automatically.\n\n## Next.js\n\n[Section titled “Next.js”](#nextjs)\n\n-\nInstall the package:\n\nTerminal window\n\nnpm install aeo.js\n\n-\nWrap your Next.js config:\n\nnext.config.mjs\n\nimport { withAeo } from 'aeo.js/next';\n\nexport default withAeo({\n\naeo: {\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n},\n\n});\n\n-\nAdd the post-build step to package.json:\n\n{\n\n\"scripts\": {\n\n\"postbuild\": \"node -e \\\"import('aeo.js/next').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\\\"\"\n\n}\n\n}\n\nm.postBuild({ title: &#x27;My Site&#x27;, url: &#x27;https://mysite.com&#x27; }))\\&#x22;&#x22; }}\">\n\n## Vite\n\n[Section titled “Vite”](#vite)\n\n-\nInstall the package:\n\nTerminal window\n\nnpm install aeo.js\n\n-\nAdd the plugin to your Vite config:\n\nvite.config.ts\n\nimport { defineConfig } from 'vite';\n\nimport { aeoVitePlugin } from 'aeo.js/vite';\n\nexport default defineConfig({\n\nplugins: [aeoVitePlugin({\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n}),],\n\n});\n\n## CLI (any site)\n\n[Section titled “CLI (any site)”](#cli-any-site)\n\nNo framework integration needed:\n\nTerminal window\n\nnpx aeo.js generate --url https://mysite.com --title \"My Site\"\n\nSee [CLI docs](/features/cli/) for all commands and options.",
      "description": "Get aeo.js running in under 2 minutes.",
      "keywords": [
        "site",
        "astro",
        "https",
        "config",
        "mysite",
        "next",
        "vite",
        "your",
        "install",
        "import"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "/getting-started/quick-start"
      }
    },
    {
      "id": "17dc64cc0a6f3b8e",
      "url": "https://aeojs.org/docs/frameworks/astro",
      "title": "Astro",
      "content": "import { Steps } from '@astrojs/starlight/components';\n\n## Setup\n\n<Steps>\n1. Install the package:\n   ```bash\n   npm install aeo.js\n   ```\n\n2. Add the integration to your Astro config:\n   ```js\n   // astro.config.mjs\n   import { defineConfig } from 'astro/config';\n   import { aeoAstroIntegration } from 'aeo.js/astro';\n\n   export default defineConfig({\n     site: 'https://mysite.com',\n     integrations: [\n       aeoAstroIntegration({\n         title: 'My Site',\n         description: 'A site optimized for AI discovery',\n         url: 'https://mysite.com',\n       }),\n     ],\n   });\n   ```\n\n3. Build your site:\n   ```bash\n   npm run build\n   ```\n</Steps>\n\n## How it works\n\nThe Astro integration:\n\n- Hooks into the Astro build pipeline via `astro:build:done`\n- Scans all rendered HTML pages for content extraction\n- Generates all AEO files in your output directory\n- Automatically injects the Human/AI widget\n- Persists the widget across View Transitions\n\n## Configuration\n\nPass any [AeoConfig](/reference/configuration/) options to the integration:\n\n```js\naeoAstroIntegration({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  generators: {\n    robotsTxt: true,\n    llmsTxt: true,\n    sitemap: false, // Astro has its own sitemap\n  },\n  widget: {\n    position: 'bottom-left',\n    theme: {\n      accent: '#6366f1',\n    },\n  },\n});\n```",
      "description": "Use aeo.js with Astro.",
      "keywords": [
        "astro",
        "site",
        "build",
        "import",
        "steps",
        "from",
        "integration",
        "your",
        "config",
        "aeoastrointegration"
      ],
      "metadata": {
        "title": "Astro",
        "description": "Use aeo.js with Astro.",
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "docs/frameworks/astro.mdx"
      }
    },
    {
      "id": "1a327206d18bdd23",
      "url": "https://aeojs.org/frameworks/nextjs",
      "title": "Next.js (Part 1)",
      "content": "## Next.js\n\n## Setup\n\n[Section titled “Setup”](#setup)\n\n-\nInstall the package:\n\nTerminal window\n\nnpm install aeo.js\n\n-\nWrap your Next.js config with withAeo:\n\nnext.config.mjs\n\nimport { withAeo } from 'aeo.js/next';\n\nexport default withAeo({\n\naeo: {\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n},\n\n});\n\n-\nAdd the post-build step to your package.json:\n\n{\n\n\"scripts\": {\n\n\"postbuild\": \"node -e \\\"import('aeo.js/next').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\\\"\"\n\n}\n\n}\n\nm.postBuild({ title: &#x27;My Site&#x27;, url: &#x27;https://mysite.com&#x27; }))\\&#x22;&#x22; }}\">\n\nTip\n\nThe postbuild step is needed because Next.js pre-renders pages during build. The post-build step scans the rendered HTML to extract full page content.\n\n## Widget\n\n[Section titled “Widget”](#widget)\n\nFor Next.js, add the widget manually as a client component:\n\n// app/layout.tsx (or any client component)\n\n'use client';\n\nimport { useEffect } from 'react';\n\nexport function AeoWidgetLoader() {\n\nuseEffect(() => {\n\nimport('aeo.js/widget').then(({ AeoWidget }) => {\n\nnew AeoWidget({\n\nconfig: {\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\nwidget: { enabled: true, position: 'bottom-right' },\n\n},\n\n});\n\n});\n\n}, []);\n\nreturn null;\n\n}\n\n{ import(&#x27;aeo.js/widget&#x27;).then(({ AeoWidget }) => { new AeoWidget({ config: { title: &#x27;My Site&#x27;, url: &#x27;https://mysite.com&#x27;, widget: { enabled: true, position: &#x27;bottom-right&#x27; }, }, }); }); }, []); return null;}\">\n\n## Configuration\n\n[Section titled “Configuration”](#configuration)\n\nPass any [AeoConfig](/reference/configuration/) options in the aeo key:\n\nexport default withAeo({\n\naeo: {\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\ngenerators: {\n\nrobotsTxt: true,\n\nllmsTxt: true,\n\nschema: true,\n\n},\n\nwidget: {\n\nenabled: true,\n\nposition: 'bottom-right',\n\n},\n\n},\n\n});",
      "description": "Use aeo.js with Next.js.",
      "keywords": [
        "widget",
        "next",
        "https",
        "site",
        "title",
        "mysite",
        "true",
        "import",
        "config",
        "withaeo"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "/frameworks/nextjs"
      }
    },
    {
      "id": "1af9241ac9f9261d",
      "url": "https://aeojs.org/contributors",
      "title": "Contributors",
      "content": "## Contributors\n\n6 contributors have shaped aeo.js. Thank you.\n\n- [rubenmarcus 77 commits](https://github.com/rubenmarcus)\n- [KimHyeongRae0 4 commits](https://github.com/KimHyeongRae0)\n- [FabioRocha231 3 commits](https://github.com/FabioRocha231)\n- [ribeiroevandro 2 commits](https://github.com/ribeiroevandro)\n- [HusseinAdeiza 1 commit](https://github.com/HusseinAdeiza)\n- [mhanelia 1 commit](https://github.com/mhanelia)\n\nWant to join them?\n[Open a PR](https://github.com/multivmlabs/aeo.js)\n.\n\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "The people who make aeo.js possible.",
      "keywords": [
        "https",
        "github",
        "rubenmarcus",
        "commits",
        "multivmlabs",
        "contributors",
        "kimhyeongrae0",
        "fabiorocha231",
        "ribeiroevandro",
        "husseinadeiza"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "/contributors"
      }
    },
    {
      "id": "217405d59066b758",
      "url": "https://aeojs.org/features/cli",
      "title": "CLI (Part 1)",
      "content": "## CLI\n\n## Usage\n\n[Section titled “Usage”](#usage)\n\nTerminal window\n\nnpx aeo.js &#x3C;command> [options]\n\n** [options]\">\n\n## Commands\n\n[Section titled “Commands”](#commands)\n\n### generate\n\n[Section titled “generate”](#generate)\n\nGenerate all AEO files (robots.txt, llms.txt, sitemap.xml, etc.):\n\nTerminal window\n\nnpx aeo.js generate\n\nnpx aeo.js generate --url https://mysite.com --title \"My Site\" --out public\n\n### init\n\n[Section titled “init”](#init)\n\nCreate an aeo.config.ts configuration file in your project:\n\nTerminal window\n\nnpx aeo.js init\n\nThis generates a starter config with all options documented.\n\n### check\n\n[Section titled “check”](#check)\n\nValidate your AEO setup and get a GEO readiness score (0–100). Does not write any files — safe to run in CI:\n\nTerminal window\n\nnpx aeo.js check # formatted output\n\nnpx aeo.js check --json # machine-readable JSON for scripting\n\nFail a CI build if the score drops below a threshold:\n\nTerminal window\n\nSCORE=$(npx aeo.js check --json | jq '.audit.score')\n\n[\"$SCORE\" -ge 70] || { echo \"GEO score $SCORE below 70\"; exit 1; }\n\n### report\n\n[Section titled “report”](#report)\n\nDeeper analysis than check: per-page citability scores, platform-specific hints (ChatGPT, Claude, Perplexity, Google AI Overviews, Bing Copilot), and a prioritized fix list.\n\nTerminal window\n\nnpx aeo.js report > aeo-report.md\n\nnpx aeo.js report --json > aeo-report.json\n\naeo-report.mdnpx aeo.js report --json > aeo-report.json\">\n\n## Options\n\n[Section titled “Options”](#options)\n\nFlag\n\nDescription\n\n--out &#x3C;dir>\n\nOutput directory (default: auto-detected)\n\n--url &#x3C;url>\n\nSite URL\n\n--title &#x3C;title>\n\nSite title\n\n--no-widget\n\nDisable widget generation\n\n--json\n\nJSON output (for check and report)\n\n--help, -h\n\nShow help\n\n--version, -v\n\nShow version\n\nBoth --flag value and --flag=value forms are supported.\n\n## Configuration file\n\n[Section titled “Configuration file”](#configuration-file)\n\nCaution",
      "description": "Run aeo.js from the command line without any framework integration.",
      "keywords": [
        "report",
        "json",
        "section",
        "titled",
        "check",
        "terminal",
        "window",
        "options",
        "generate",
        "site"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "/features/cli"
      }
    },
    {
      "id": "25a0f604f5876b44",
      "url": "https://aeojs.org/docs/reference/configuration",
      "title": "Configuration (Part 2)",
      "content": "| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `title` | `string` | `''` | Site title |\n| `description` | `string` | `''` | Site description |\n| `url` | `string` | `''` | Site URL (used for absolute URLs in generated files) |\n| `contentDir` | `string` | `'docs'` | Directory with handwritten markdown files |\n| `outDir` | `string` | auto-detected | Output directory for generated files |\n| `pages` | `PageEntry[]` | `[]` | Manually specify pages to include |\n\n### `generators`\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `robotsTxt` | `boolean` | `true` | Generate `robots.txt` |\n| `llmsTxt` | `boolean` | `true` | Generate `llms.txt` |\n| `llmsFullTxt` | `boolean` | `true` | Generate `llms-full.txt` |\n| `rawMarkdown` | `boolean` | `true` | Generate per-page `.md` files |\n| `manifest` | `boolean` | `true` | Generate `docs.json` |\n| `sitemap` | `boolean` | `true` | Generate `sitemap.xml` |\n| `aiIndex` | `boolean` | `true` | Generate `ai-index.json` |\n| `schema` | `boolean` | `false` | Generate JSON-LD structured data |\n\n### `aiIndex`\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `maxChunkLength` | `number` | `2000` | Target chunk length (soft limit). Chunks split on `\\n\\n` paragraph boundaries, so a single long paragraph can exceed this value. Set with embedding-model token limits in mind. |\n| `maxKeywords` | `number` | `10` | Maximum number of keywords extracted per `ai-index.json` entry. |\n\n### `robots`\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `allow` | `string[]` | `['/']` | Allowed paths |\n| `disallow` | `string[]` | `[]` | Disallowed paths |\n| `crawlDelay` | `number` | `0` | Crawl delay in seconds |\n| `sitemap` | `string` | auto | Sitemap URL |\n\n### `schema`",
      "description": "Full configuration reference for aeo.js.",
      "keywords": [
        "true",
        "string",
        "boolean",
        "default",
        "description",
        "type",
        "organization",
        "generate",
        "sitemap",
        "option"
      ],
      "metadata": {
        "title": "Configuration",
        "description": "Full configuration reference for aeo.js.",
        "chunkIndex": 1,
        "totalChunks": 3,
        "sourcePath": "docs/reference/configuration.mdx"
      }
    },
    {
      "id": "25feab72c45816b9",
      "url": "https://aeojs.org/docs/reference/api",
      "title": "API Reference (Part 3)",
      "content": "const report = generateReport(resolvedConfig);\nconsole.log(formatReportMarkdown(report));\n```\n\n## Platform Hints\n\n### `generatePlatformHints(audit, citability)`\n\nGenerate platform-specific optimization hints from audit and citability results:\n\n```ts\nimport { auditSite, generatePlatformHints, scoreSiteCitability } from 'aeo.js';\n\nconst audit = auditSite(resolvedConfig);\nconst citability = scoreSiteCitability(resolvedConfig);\nconst hints = generatePlatformHints(audit, citability);\n```\n\n## Types\n\nAll types are exported from the main entry:\n\n```ts\nimport type {\n  AeoConfig,\n  ResolvedAeoConfig,\n  PageEntry,\n  DocEntry,\n  AeoManifest,\n  MarkdownFile,\n  ManifestEntry,\n  AIIndexEntry,\n  FrameworkType,\n  FrameworkInfo,\n  AuditResult,\n  AuditCategory,\n  AuditIssue,\n  MetaTag,\n  PageCitabilityResult,\n  SiteCitabilityResult,\n  CitabilityDimension,\n  ContentHint,\n  AeoReport,\n  PlatformHint,\n} from 'aeo.js';\n```",
      "description": "Programmatic API for aeo.js.",
      "keywords": [
        "config",
        "from",
        "const",
        "import",
        "html",
        "title",
        "site",
        "resolvedconfig",
        "generate",
        "resolveconfig"
      ],
      "metadata": {
        "title": "API Reference",
        "description": "Programmatic API for aeo.js.",
        "chunkIndex": 2,
        "totalChunks": 3,
        "sourcePath": "docs/reference/api.mdx"
      }
    },
    {
      "id": "26e49de01bc2590b",
      "url": "https://aeojs.org/docs/frameworks/webpack",
      "title": "Webpack",
      "content": "import { Steps } from '@astrojs/starlight/components';\n\n## Setup\n\n<Steps>\n1. Install the package:\n   ```bash\n   npm install aeo.js\n   ```\n\n2. Add the plugin to your Webpack config:\n   ```js\n   // webpack.config.js\n   const { AeoWebpackPlugin } = require('aeo.js/webpack');\n\n   module.exports = {\n     plugins: [\n       new AeoWebpackPlugin({\n         title: 'My Site',\n         description: 'A site optimized for AI discovery',\n         url: 'https://mysite.com',\n       }),\n     ],\n   };\n   ```\n</Steps>\n\n## How it works\n\nThe Webpack plugin:\n\n- Runs during the `emit` phase of the Webpack compilation\n- Generates all AEO files in your output directory\n- Injects the widget into your HTML entry point\n\n## Configuration\n\nPass any [AeoConfig](/reference/configuration/) options to the plugin:\n\n```js\nnew AeoWebpackPlugin({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  widget: {\n    enabled: true,\n    position: 'bottom-right',\n  },\n});\n```",
      "description": "Use aeo.js with Webpack.",
      "keywords": [
        "webpack",
        "steps",
        "plugin",
        "your",
        "aeowebpackplugin",
        "site",
        "install",
        "config",
        "title",
        "https"
      ],
      "metadata": {
        "title": "Webpack",
        "description": "Use aeo.js with Webpack.",
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "docs/frameworks/webpack.mdx"
      }
    },
    {
      "id": "2708b2aec0639c0f",
      "url": "https://aeojs.org/docs/index",
      "title": "aeo.js (Part 2)",
      "content": "export default defineConfig({\n      plugins: [\n        aeoVitePlugin({\n          title: 'My Site',\n          description: 'A site optimized for AI discovery',\n          url: 'https://mysite.com',\n        }),\n      ],\n    });\n    ```\n  </TabItem>\n  <TabItem label=\"Nuxt\">\n    ```ts\n    // nuxt.config.ts\n    export default defineNuxtConfig({\n      modules: ['aeo.js/nuxt'],\n      aeo: {\n        title: 'My Site',\n        description: 'A site optimized for AI discovery',\n        url: 'https://mysite.com',\n      },\n    });\n    ```\n  </TabItem>\n  <TabItem label=\"Angular\">\n    Add a post-build step to `package.json`:\n\n    ```json\n    {\n      \"scripts\": {\n        \"postbuild\": \"node -e \\\"import('aeo.js/angular').then(m => m.postBuild({ title: 'My App', url: 'https://myapp.com' }))\\\"\"\n      }\n    }\n    ```\n\n    Or generate programmatically:\n\n    ```ts\n    import { generate } from 'aeo.js/angular';\n    await generate({ title: 'My App', url: 'https://myapp.com' });\n    ```\n  </TabItem>\n  <TabItem label=\"Webpack\">\n    ```js\n    // webpack.config.js\n    const { AeoWebpackPlugin } = require('aeo.js/webpack');\n\n    module.exports = {\n      plugins: [\n        new AeoWebpackPlugin({\n          title: 'My Site',\n          description: 'A site optimized for AI discovery',\n          url: 'https://mysite.com',\n        }),\n      ],\n    };\n    ```\n  </TabItem>\n  <TabItem label=\"CLI\">\n    No framework needed — run standalone:\n\n    ```bash\n    # Generate all AEO files\n    npx aeo.js generate --url https://mysite.com --title \"My Site\"\n\n    # Scaffold a config file\n    npx aeo.js init\n\n    # Check your setup\n    npx aeo.js check\n    ```\n  </TabItem>\n</Tabs>\n\n## What is AEO?\n\nAnswer Engine Optimization (AEO) is the practice of making your website discoverable and citable by AI-powered answer engines like ChatGPT, Claude, Perplexity, and SearchGPT.",
      "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
      "keywords": [
        "class",
        "site",
        "tabitem",
        "https",
        "import",
        "mysite",
        "from",
        "label",
        "title",
        "config"
      ],
      "metadata": {
        "title": "aeo.js",
        "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
        "template": "splash",
        "head": "",
        "- tag": "title",
        "content": "aeo.js — Answer Engine Optimization for the Modern Web",
        "hero": "",
        "tagline": "Make your site discoverable by ChatGPT, Claude, Perplexity, and every AI answer engine, automatically.",
        "actions": "",
        "- text": "Get Started",
        "link": "/getting-started/introduction/",
        "icon": "right-arrow",
        "variant": "primary",
        "chunkIndex": 1,
        "totalChunks": 5,
        "sourcePath": "docs/index.mdx"
      }
    },
    {
      "id": "282027e140b0079b",
      "url": "https://aeojs.org/features/json-ld",
      "title": "JSON-LD Recipes (Part 2)",
      "content": "{ '@type': 'HowToStep', position: 2, name: 'Login', text: 'Run `vercel login`.' },\n\n{ '@type': 'HowToStep', position: 3, name: 'Deploy', text: 'Run `vercel --prod`.' },],\n\n};\n\n**\n\naeo.js auto-detects** Step 1: / Step 2: heading patterns.\n\n## Article / BlogPosting\n\n[Section titled “Article / BlogPosting”](#article--blogposting)\n\nconst articleSchema = {\n\n'@context': 'https://schema.org',\n\n'@type': 'BlogPosting',\n\nheadline: 'Optimizing your site for AI search engines in 2026',\n\nimage: 'https://mysite.com/og/article-cover.png',\n\ndatePublished: '2026-05-14T10:00:00Z',\n\ndateModified: '2026-05-14T10:00:00Z',\n\nauthor: { '@type': 'Person', name: 'Jane Author' },\n\npublisher: {\n\n'@type': 'Organization',\n\nname: 'My Site',\n\nlogo: { '@type': 'ImageObject', url: 'https://mysite.com/logo.png' },\n\n},\n\n};\n\n**\n\nCaution\n\nAlways use ISO-8601 strings for datePublished / dateModified. A raw Date object passed through a template literal renders as \"Thu May 14 2026 ...\" and breaks validators. Wrap with new Date(d).toISOString().\n\n## Product\n\n[Section titled “Product”](#product)\n\nconst productSchema = {\n\n'@context': 'https://schema.org',\n\n'@type': 'Product',\n\nname: 'Acme Espresso Machine',\n\ndescription: 'A semi-automatic espresso machine with built-in grinder.',\n\nimage: ['https://mysite.com/products/espresso/cover.jpg'],\n\nsku: 'ACM-ESP-001',\n\nbrand: { '@type': 'Brand', name: 'Acme' },\n\noffers: {\n\n'@type': 'Offer',\n\nurl: 'https://mysite.com/products/espresso',\n\npriceCurrency: 'USD',\n\nprice: '899.00',\n\navailability: 'https://schema.org/InStock',\n\n},\n\naggregateRating: {\n\n'@type': 'AggregateRating',\n\nratingValue: '4.7',\n\nreviewCount: '142',\n\n},\n\n};\n\n## BreadcrumbList\n\n[Section titled “BreadcrumbList”](#breadcrumblist)\n\nconst breadcrumbSchema = {\n\n'@context': 'https://schema.org',\n\n'@type': 'BreadcrumbList',\n\nitemListElement: [{ '@type': 'ListItem', position: 1, name: 'Home', item: 'https://mysite.com/' },\n\n{ '@type': 'ListItem', position: 2, name: 'Blog', item: 'https://mysite.com/blog' },",
      "description": "Copy-paste structured-data recipes for FAQ, HowTo, Product, Article, Recipe, Event, VideoObject, and BreadcrumbList — each paired with an XSS-safe serializer.",
      "keywords": [
        "type",
        "https",
        "schema",
        "json",
        "name",
        "section",
        "titled",
        "script",
        "replace",
        "const"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 3,
        "sourcePath": "/features/json-ld"
      }
    },
    {
      "id": "28510963a60458b8",
      "url": "https://aeojs.org/docs/features/schema-og",
      "title": "Schema & Open Graph (Part 1)",
      "content": "import { Aside } from '@astrojs/starlight/components';\n\naeo.js can generate JSON-LD structured data and Open Graph meta tags for your pages.\n\n## JSON-LD Schema\n\nEnable schema generation in your config:\n\n```js\n{\n  schema: {\n    enabled: true,\n    organization: {\n      name: 'My Company',\n      url: 'https://mysite.com',\n      logo: 'https://mysite.com/logo.png',\n      sameAs: [\n        'https://twitter.com/mycompany',\n        'https://github.com/mycompany',\n      ],\n    },\n    defaultType: 'WebPage', // or 'Article'\n  },\n}\n```\n\nThis generates `<script type=\"application/ld+json\">` blocks with:\n\n- **Organization** schema for your site\n- **WebPage** or **Article** schema for each page\n- Proper `@context`, `@type`, `name`, `description`, and `url` fields\n\n## Open Graph tags\n\nEnable OG tag generation:\n\n```js\n{\n  og: {\n    enabled: true,\n    image: 'https://mysite.com/og.png',\n    twitterHandle: '@mycompany',\n    type: 'website', // or 'article'\n  },\n}\n```\n\nThis generates meta tags like:\n\n```html\n<meta property=\"og:title\" content=\"Page Title\" />\n<meta property=\"og:description\" content=\"Page description\" />\n<meta property=\"og:image\" content=\"https://mysite.com/og.png\" />\n<meta property=\"og:url\" content=\"https://mysite.com/page\" />\n<meta name=\"twitter:card\" content=\"summary_large_image\" />\n<meta name=\"twitter:site\" content=\"@mycompany\" />\n```\n\n## Programmatic API\n\nThe lower-level helpers expect a resolved config and a page entry.\n\n```ts\nimport {\n  generateJsonLdScript,\n  generateOGTags,\n  generateOGTagsHtml,\n  generateSchemaObjects,\n  resolveConfig,\n} from 'aeo.js';\n\nconst page = {\n  pathname: '/page',\n  title: 'Page Title',\n  description: 'Page description',\n  content: 'Page content',\n};\n\nconst resolvedConfig = resolveConfig({\n  title: 'My Company',\n  description: 'My company website',\n  url: 'https://mysite.com',\n  pages: [page],\n});\n\n// Get schema objects\nconst schemas = generateSchemaObjects(resolvedConfig);",
      "description": "Auto-generated JSON-LD structured data and Open Graph meta tags.",
      "keywords": [
        "page",
        "meta",
        "https",
        "content",
        "schema",
        "mysite",
        "description",
        "const",
        "tags",
        "title"
      ],
      "metadata": {
        "title": "Schema & Open Graph",
        "description": "Auto-generated JSON-LD structured data and Open Graph meta tags.",
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "docs/features/schema-og.mdx"
      }
    },
    {
      "id": "29049040c18c4049",
      "url": "https://aeojs.org/docs/index",
      "title": "aeo.js (Part 4)",
      "content": "<AeoReactWidget config={{ title: 'My Site', url: 'https://mysite.com' }} />\n    ```\n  </TabItem>\n  <TabItem label=\"Vue\">\n    ```vue\n    <script setup>\n    import { AeoVueWidget } from 'aeo.js/vue';\n    </script>\n\n    <template>\n      <AeoVueWidget :config=\"{ title: 'My Site', url: 'https://mysite.com' }\" />\n    </template>\n    ```\n  </TabItem>\n</Tabs>\n\n## Configuration\n\nAll frameworks use the same config shape — [see full reference](/reference/configuration/):\n\n```ts\nimport { defineConfig } from 'aeo.js';\n\nexport default defineConfig({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  description: 'A site optimized for AI discovery',\n\n  generators: {\n    robotsTxt: true,\n    llmsTxt: true,\n    llmsFullTxt: true,\n    rawMarkdown: true,\n    sitemap: true,\n    aiIndex: true,\n    schema: true,\n  },\n\n  schema: {\n    enabled: true,\n    organization: { name: 'My Company', url: 'https://mysite.com' },\n    defaultType: 'WebPage',\n  },\n\n  og: {\n    enabled: true,\n    image: 'https://mysite.com/og.png',\n    twitterHandle: '@mycompany',\n  },\n\n  widget: {\n    enabled: true,\n    position: 'bottom-right',\n    theme: { accent: '#4ADE80', badge: '#4ADE80' },\n  },\n});\n```\n\n## Generated Files\n\nAfter building, your output directory contains:\n\n```\npublic/\n├── robots.txt          # AI-crawler directives\n├── llms.txt            # Short LLM-readable summary\n├── llms-full.txt       # Full content for LLMs\n├── sitemap.xml         # Standard sitemap\n├── docs.json           # Documentation manifest\n├── ai-index.json       # AI content index\n├── index.md            # Markdown for /\n└── about.md            # Markdown for /about\n```\n\n## Checker",
      "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
      "keywords": [
        "class",
        "site",
        "tabitem",
        "https",
        "import",
        "mysite",
        "from",
        "label",
        "title",
        "config"
      ],
      "metadata": {
        "title": "aeo.js",
        "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
        "template": "splash",
        "head": "",
        "- tag": "title",
        "content": "aeo.js — Answer Engine Optimization for the Modern Web",
        "hero": "",
        "tagline": "Make your site discoverable by ChatGPT, Claude, Perplexity, and every AI answer engine, automatically.",
        "actions": "",
        "- text": "Get Started",
        "link": "/getting-started/introduction/",
        "icon": "right-arrow",
        "variant": "primary",
        "chunkIndex": 3,
        "totalChunks": 5,
        "sourcePath": "docs/index.mdx"
      }
    },
    {
      "id": "2f144d7a2b0631dd",
      "url": "https://aeojs.org/docs/features/widget",
      "title": "Human/AI Widget (Part 2)",
      "content": "| Default | Small | Icon |\n|---------|-------|------|\n| ![Default widget](/widget-default.webp) | ![Small widget](/widget-small.webp) | ![Icon widget](/widget-icon.webp) |\n| `size: 'default'` | `size: 'small'` | `size: 'icon-only'` |\n| Full labels with icons | Compact — ~30% smaller | Just icons, no labels |\n\n<Aside type=\"tip\">\nSet `widget.enabled: false` to disable the widget entirely while still generating AEO files.\n</Aside>",
      "description": "The drop-in toggle that shows how AI sees your pages.",
      "keywords": [
        "widget",
        "import",
        "from",
        "react",
        "size",
        "default",
        "small",
        "icon",
        "aside",
        "components"
      ],
      "metadata": {
        "title": "Human/AI Widget",
        "description": "The drop-in toggle that shows how AI sees your pages.",
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "docs/features/widget.mdx"
      }
    },
    {
      "id": "3b0d3d9d2ab30f9a",
      "url": "https://aeojs.org/reference/configuration",
      "title": "Configuration (Part 3)",
      "content": "'bottom-right'\n\nWidget position\n\nhumanLabel\n\nstring\n\n'Human'\n\nLabel for human view\n\naiLabel\n\nstring\n\n'AI'\n\nLabel for AI view\n\nshowBadge\n\nboolean\n\ntrue\n\nShow the AEO badge\n\ntheme.background\n\nstring\n\n'rgba(18, 18, 24, 0.9)'\n\nWidget background\n\ntheme.text\n\nstring\n\n'#C0C0C5'\n\nText color\n\ntheme.accent\n\nstring\n\n'#E8E8EA'\n\nAccent color\n\ntheme.badge\n\nstring\n\n'#4ADE80'\n\nBadge color\n\n[Previous\nAudit & Citability](/features/audit/) [Next\nAPI](/reference/api/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Full configuration reference for aeo.js.",
      "keywords": [
        "true",
        "string",
        "boolean",
        "default",
        "description",
        "type",
        "section",
        "titled",
        "https",
        "schema"
      ],
      "metadata": {
        "chunkIndex": 2,
        "totalChunks": 3,
        "sourcePath": "/reference/configuration"
      }
    },
    {
      "id": "3bb61ec2c4672fe6",
      "url": "https://aeojs.org/docs/features/audit",
      "title": "Audit & Citability (Part 2)",
      "content": "// Get as JSON\nconsole.log(formatReportJson(report));\n```\n\n## Platform Hints\n\nGet platform-specific optimization suggestions:\n\n```ts\nimport { auditSite, generatePlatformHints, resolveConfig, scoreSiteCitability } from 'aeo.js';\n\nconst config = resolveConfig({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  pages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],\n});\n\nconst audit = auditSite(config);\nconst citability = scoreSiteCitability(config);\nconst hints = generatePlatformHints(audit, citability);\n// Returns platform-specific optimization hints for ChatGPT, Perplexity, Google AI, and Bing Copilot\n```",
      "description": "Audit your AEO setup and measure your site's citability score.",
      "keywords": [
        "site",
        "const",
        "config",
        "title",
        "resolveconfig",
        "content",
        "home",
        "auditsite",
        "report",
        "from"
      ],
      "metadata": {
        "title": "Audit & Citability",
        "description": "Audit your AEO setup and measure your site's citability score.",
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "docs/features/audit.mdx"
      }
    },
    {
      "id": "3c248c59d0c54216",
      "url": "https://aeojs.org/docs/reference/api",
      "title": "API Reference (Part 1)",
      "content": "## Core\n\n### `defineConfig(config)`\n\nType-safe configuration helper:\n\n```ts\nimport { defineConfig } from 'aeo.js';\n\nexport default defineConfig({\n  title: 'My Site',\n  url: 'https://mysite.com',\n});\n```\n\n### `generateAll(config)`\n\nGenerate all AEO files programmatically:\n\n```ts\nimport { generateAll } from 'aeo.js';\n\nawait generateAll({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  outDir: 'dist',\n});\n```\n\n### `resolveConfig(config)`\n\nResolve a partial config into a fully resolved config with defaults:\n\n```ts\nimport { resolveConfig } from 'aeo.js';\n\nconst resolved = resolveConfig({ title: 'My Site' });\n// All fields now have defaults\n```\n\nThe examples below use `resolvedConfig` for a config object returned by `resolveConfig`.\n\n### `validateConfig(config)`\n\nValidate a config object and return any errors:\n\n```ts\nimport { validateConfig } from 'aeo.js';\n\nconst errors = validateConfig(config);\n```\n\n### `detectFramework()`\n\nAuto-detect the framework used in the current project:\n\n```ts\nimport { detectFramework } from 'aeo.js';\n\nconst info = detectFramework();\n// { framework: 'next', contentDir: 'pages', outDir: '.next' }\n```\n\n## HTML Extraction\n\n### `htmlToMarkdown(html, pagePath, config)`\n\nConvert HTML to clean markdown:\n\n```ts\nimport { htmlToMarkdown } from 'aeo.js';\n\nconst md = htmlToMarkdown(\n  '<html><head><title>Hello</title></head><body><main><p>World</p></main></body></html>',\n  '/',\n  { url: 'https://mysite.com' }\n);\n// Returns a markdown document with YAML frontmatter\n```\n\n### `extractTextFromHtml(html)`\n\nExtract plain text from HTML:\n\n```ts\nimport { extractTextFromHtml } from 'aeo.js';\n\nconst text = extractTextFromHtml('<p>Hello <strong>world</strong></p>');\n```\n\n### `extractTitle(html)` / `extractDescription(html)`\n\nExtract the title or meta description from an HTML document.\n\n### `extractJsonLd(html)`\n\nExtract JSON-LD structured data from an HTML document.\n\n## Schema\n\n### `generateSchemaObjects(config)`\n\nGenerate JSON-LD schema objects:",
      "description": "Programmatic API for aeo.js.",
      "keywords": [
        "config",
        "from",
        "const",
        "import",
        "html",
        "title",
        "site",
        "resolvedconfig",
        "generate",
        "resolveconfig"
      ],
      "metadata": {
        "title": "API Reference",
        "description": "Programmatic API for aeo.js.",
        "chunkIndex": 0,
        "totalChunks": 3,
        "sourcePath": "docs/reference/api.mdx"
      }
    },
    {
      "id": "40769a7ef81185c5",
      "url": "https://aeojs.org",
      "title": "aeo.js — Answer Engine Optimization for the Modern Web (Part 3)",
      "content": "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.\n\n## Why AEO matters\n\n[Section titled “Why AEO matters”](#why-aeo-matters)\n\n58%\n\nof searches\n\nend without a click — AI gives the answer directly\n\n40%\n\nof Gen Z\n\nprefer AI assistants over traditional search engines\n\n97%\n\nof sites\n\nhave no llms.txt or structured data for AI crawlers\n\n1 min\n\nto set up\n\naeo.js generates robots.txt, llms.txt, schema &#x26; more\n\nIf 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.\n\n## Widget\n\n[Section titled “Widget”](#widget)\n\nThe 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:\n\n'use client';\n\nimport { useEffect } from 'react';\n\nexport function AeoWidgetLoader() {\n\nuseEffect(() => {\n\nimport('aeo.js/widget').then(({ AeoWidget }) => {\n\nnew AeoWidget({\n\nconfig: {\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\nwidget: { enabled: true, position: 'bottom-right' },\n\n},\n\n});\n\n});\n\n}, []);\n\nreturn null;\n\n}\n\n{ import(&#x27;aeo.js/widget&#x27;).then(({ AeoWidget }) => { new AeoWidget({ config: { title: &#x27;My Site&#x27;, url: &#x27;https://mysite.com&#x27;, widget: { enabled: true, position: &#x27;bottom-right&#x27; }, }, }); }); }, []); return null;}\">\n\nReact and Vue wrapper components are also available:\n\n- [React](#tab-panel-16)\n- [Vue](#tab-panel-17)\n\nimport { AeoReactWidget } from 'aeo.js/react';\n\n&#x3C;AeoReactWidget config={{ title: 'My Site', url: 'https://mysite.com' }} />\n\n\">\n\n&#x3C;script setup>\n\nimport { AeoVueWidget } from 'aeo.js/vue';\n\n&#x3C;/script>\n\n&#x3C;template>\n\n&#x3C;AeoVueWidget :config=\"{ title: 'My Site', url: 'https://mysite.com' }\" />\n\n&#x3C;/template>",
      "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
      "keywords": [
        "https",
        "site",
        "title",
        "mysite",
        "import",
        "config",
        "widget",
        "true",
        "from",
        "files"
      ],
      "metadata": {
        "chunkIndex": 2,
        "totalChunks": 4,
        "sourcePath": "/"
      }
    },
    {
      "id": "40a75a682470edae",
      "url": "https://aeojs.org/docs/index",
      "title": "aeo.js (Part 3)",
      "content": "**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.\n\n## Why AEO matters\n\n<div class=\"why-aeo-grid\">\n  <div class=\"why-card\">\n    <div class=\"why-stat\">58%</div>\n    <div class=\"why-label\">of searches</div>\n    <div class=\"why-desc\">end without a click — AI gives the answer directly</div>\n  </div>\n  <div class=\"why-card\">\n    <div class=\"why-stat\">40%</div>\n    <div class=\"why-label\">of Gen Z</div>\n    <div class=\"why-desc\">prefer AI assistants over traditional search engines</div>\n  </div>\n  <div class=\"why-card\">\n    <div class=\"why-stat\">97%</div>\n    <div class=\"why-label\">of sites</div>\n    <div class=\"why-desc\">have no llms.txt or structured data for AI crawlers</div>\n  </div>\n  <div class=\"why-card\">\n    <div class=\"why-stat\">1 min</div>\n    <div class=\"why-label\">to set up</div>\n    <div class=\"why-desc\">aeo.js generates robots.txt, llms.txt, schema &amp; more</div>\n  </div>\n</div>\n\nIf 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.\n\n## Widget\n\nThe 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:\n\n```tsx\n'use client';\nimport { useEffect } from 'react';\n\nexport function AeoWidgetLoader() {\n  useEffect(() => {\n    import('aeo.js/widget').then(({ AeoWidget }) => {\n      new AeoWidget({\n        config: {\n          title: 'My Site',\n          url: 'https://mysite.com',\n          widget: { enabled: true, position: 'bottom-right' },\n        },\n      });\n    });\n  }, []);\n  return null;\n}\n```\n\nReact and Vue wrapper components are also available:\n\n<Tabs>\n  <TabItem label=\"React\">\n    ```tsx\n    import { AeoReactWidget } from 'aeo.js/react';",
      "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
      "keywords": [
        "class",
        "site",
        "tabitem",
        "https",
        "import",
        "mysite",
        "from",
        "label",
        "title",
        "config"
      ],
      "metadata": {
        "title": "aeo.js",
        "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
        "template": "splash",
        "head": "",
        "- tag": "title",
        "content": "aeo.js — Answer Engine Optimization for the Modern Web",
        "hero": "",
        "tagline": "Make your site discoverable by ChatGPT, Claude, Perplexity, and every AI answer engine, automatically.",
        "actions": "",
        "- text": "Get Started",
        "link": "/getting-started/introduction/",
        "icon": "right-arrow",
        "variant": "primary",
        "chunkIndex": 2,
        "totalChunks": 5,
        "sourcePath": "docs/index.mdx"
      }
    },
    {
      "id": "45512fbdccb834f2",
      "url": "https://aeojs.org/reference/configuration",
      "title": "Configuration (Part 1)",
      "content": "## Configuration\n\nAll framework plugins and the CLI accept the same AeoConfig object.\n\n## Full example\n\n[Section titled “Full example”](#full-example)\n\nimport { defineConfig } from 'aeo.js';\n\nexport default defineConfig({\n\n// Required\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\n// Optional\n\ndescription: 'A description of your site',\n\ncontentDir: 'docs', // Directory with handwritten .md files\n\noutDir: 'public', // Output directory for generated files\n\n// Toggle individual generators\n\ngenerators: {\n\nrobotsTxt: true,\n\nllmsTxt: true,\n\nllmsFullTxt: true,\n\nrawMarkdown: true,\n\nmanifest: true,\n\nsitemap: true,\n\naiIndex: true,\n\nschema: true,\n\n},\n\n// Configure ai-index.json generation\n\naiIndex: {\n\nmaxChunkLength: 2000,\n\nmaxKeywords: 10,\n\n},\n\n// Customize robots.txt\n\nrobots: {\n\nallow: ['/'],\n\ndisallow: ['/admin'],\n\ncrawlDelay: 0,\n\nsitemap: 'https://mysite.com/sitemap.xml',\n\n},\n\n// JSON-LD structured data\n\nschema: {\n\nenabled: true,\n\norganization: {\n\nname: 'My Company',\n\nurl: 'https://mysite.com',\n\nlogo: 'https://mysite.com/logo.png',\n\nsameAs: ['https://twitter.com/mycompany'],\n\n},\n\ndefaultType: 'WebPage',\n\n},\n\n// Open Graph meta tags\n\nog: {\n\nenabled: true,\n\nimage: 'https://mysite.com/og.png',\n\ntwitterHandle: '@mycompany',\n\ntype: 'website',\n\n},\n\n// Widget configuration\n\nwidget: {\n\nenabled: true,\n\nposition: 'bottom-right',\n\nhumanLabel: 'Human',\n\naiLabel: 'AI',\n\nshowBadge: true,\n\ntheme: {\n\nbackground: 'rgba(18, 18, 24, 0.9)',\n\ntext: '#C0C0C5',\n\naccent: '#E8E8EA',\n\nbadge: '#4ADE80',\n\n},\n\n},\n\n});\n\n## Options reference\n\n[Section titled “Options reference”](#options-reference)\n\n### Top-level\n\n[Section titled “Top-level”](#top-level)\n\nOption\n\nType\n\nDefault\n\nDescription\n\ntitle\n\nstring\n\n''\n\nSite title\n\ndescription\n\nstring\n\n''\n\nSite description\n\nurl\n\nstring\n\n''\n\nSite URL (used for absolute URLs in generated files)\n\ncontentDir\n\nstring\n\n'docs'\n\nDirectory with handwritten markdown files\n\noutDir\n\nstring\n\nauto-detected\n\nOutput directory for generated files\n\npages\n\nPageEntry[]\n\n[]",
      "description": "Full configuration reference for aeo.js.",
      "keywords": [
        "true",
        "string",
        "boolean",
        "default",
        "description",
        "type",
        "section",
        "titled",
        "https",
        "schema"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 3,
        "sourcePath": "/reference/configuration"
      }
    },
    {
      "id": "4a78d04133eb79e3",
      "url": "https://aeojs.org/docs/frameworks/nuxt",
      "title": "Nuxt",
      "content": "import { Steps } from '@astrojs/starlight/components';\n\n## Setup\n\n<Steps>\n1. Install the package:\n   ```bash\n   npm install aeo.js\n   ```\n\n2. Add the module to your Nuxt config:\n   ```ts\n   // nuxt.config.ts\n   export default defineNuxtConfig({\n     modules: ['aeo.js/nuxt'],\n     aeo: {\n       title: 'My Site',\n       description: 'A site optimized for AI discovery',\n       url: 'https://mysite.com',\n     },\n   });\n   ```\n</Steps>\n\n## How it works\n\nThe Nuxt module:\n\n- Scans your `pages/` directory for routes\n- Generates AEO files during dev and production builds\n- Scans pre-rendered HTML from `.output/public/` for full page content\n- Injects the widget as a client-side Nuxt plugin\n- Adds `<link>` and `<meta>` tags for AEO discoverability\n\n## Configuration\n\nPass any [AeoConfig](/reference/configuration/) options in the `aeo` key:\n\n```ts\nexport default defineNuxtConfig({\n  modules: ['aeo.js/nuxt'],\n  aeo: {\n    title: 'My Site',\n    url: 'https://mysite.com',\n    generators: {\n      robotsTxt: true,\n      llmsTxt: true,\n      rawMarkdown: true,\n    },\n    widget: {\n      enabled: true,\n      position: 'bottom-left',\n    },\n  },\n});\n```",
      "description": "Use aeo.js with Nuxt 3.",
      "keywords": [
        "nuxt",
        "true",
        "steps",
        "site",
        "from",
        "install",
        "module",
        "your",
        "config",
        "export"
      ],
      "metadata": {
        "title": "Nuxt",
        "description": "Use aeo.js with Nuxt 3.",
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "docs/frameworks/nuxt.mdx"
      }
    },
    {
      "id": "4af97965a7c3b340",
      "url": "https://aeojs.org/features/schema-og",
      "title": "Schema & Open Graph (Part 2)",
      "content": "// Get a &#x3C;script> tag string\n\nconst script = generateJsonLdScript([...schemas.site,\n\n...(schemas.pages[page.pathname] ?? []),]);\n\n// Get OG meta tag objects\n\nconst tags = generateOGTags(page, resolvedConfig);\n\n// Get OG meta tags as HTML string\n\nconst html = generateOGTagsHtml(page, resolvedConfig);\n\ntag stringconst script = generateJsonLdScript([ ...schemas.site, ...(schemas.pages[page.pathname] ?? []),]);// Get OG meta tag objectsconst tags = generateOGTags(page, resolvedConfig);// Get OG meta tags as HTML stringconst html = generateOGTagsHtml(page, resolvedConfig);\">\n\nTip\n\nSchema and OG generators work independently — you can enable one without the other.\n\n[Previous\nCLI](/features/cli/) [Next\nJSON-LD Recipes](/features/json-ld/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Auto-generated JSON-LD structured data and Open Graph meta tags.",
      "keywords": [
        "page",
        "meta",
        "schema",
        "https",
        "tags",
        "const",
        "content",
        "json",
        "mysite",
        "description"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "/features/schema-og"
      }
    },
    {
      "id": "4bf4782ca6c223ef",
      "url": "https://aeojs.org/docs/index",
      "title": "aeo.js (Part 5)",
      "content": "<div class=\"aeo-checker-widget\" style={{marginTop: '1rem', marginBottom: '0.5rem'}}>\n  <form id=\"aeo-check-form\" class=\"aeo-checker-input-wrap\" action=\"https://check.aeojs.org\" method=\"GET\">\n    <input\n      type=\"text\"\n      name=\"q\"\n      class=\"aeo-checker-input\"\n      placeholder=\"Enter your website URL…\"\n      required\n    />\n    <button type=\"submit\" class=\"aeo-checker-btn\">\n      Scan\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M5 12h14\"/><path d=\"m12 5 7 7-7 7\"/></svg>\n    </button>\n  </form>\n  <p style={{textAlign: 'center', fontSize: '0.8rem', color: 'rgba(255,255,255,0.3)', marginTop: '0.75rem'}}>Free — no signup required. Powered by <a href=\"https://check.aeojs.org\" style={{color: 'rgba(255,255,255,0.5)', textDecoration: 'underline', textUnderlineOffset: '2px'}}>AEO Checker</a></p>\n</div>\n\n<HomepageContributors />",
      "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
      "keywords": [
        "class",
        "site",
        "tabitem",
        "https",
        "import",
        "mysite",
        "from",
        "label",
        "title",
        "config"
      ],
      "metadata": {
        "title": "aeo.js",
        "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
        "template": "splash",
        "head": "",
        "- tag": "title",
        "content": "aeo.js — Answer Engine Optimization for the Modern Web",
        "hero": "",
        "tagline": "Make your site discoverable by ChatGPT, Claude, Perplexity, and every AI answer engine, automatically.",
        "actions": "",
        "- text": "Get Started",
        "link": "/getting-started/introduction/",
        "icon": "right-arrow",
        "variant": "primary",
        "chunkIndex": 4,
        "totalChunks": 5,
        "sourcePath": "docs/index.mdx"
      }
    },
    {
      "id": "509dc5a4543fe75d",
      "url": "https://aeojs.org/docs/getting-started/quick-start",
      "title": "Quick Start (Part 2)",
      "content": "See [CLI docs](/features/cli/) for all commands and options.",
      "description": "Get aeo.js running in under 2 minutes.",
      "keywords": [
        "site",
        "import",
        "steps",
        "config",
        "from",
        "your",
        "install",
        "https",
        "mysite",
        "astro"
      ],
      "metadata": {
        "title": "Quick Start",
        "description": "Get aeo.js running in under 2 minutes.",
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "docs/getting-started/quick-start.mdx"
      }
    },
    {
      "id": "56458f0da655812f",
      "url": "https://aeojs.org/docs/frameworks/vite",
      "title": "Vite",
      "content": "import { Steps } from '@astrojs/starlight/components';\n\n## Setup\n\n<Steps>\n1. Install the package:\n   ```bash\n   npm install aeo.js\n   ```\n\n2. Add the plugin to your Vite config:\n   ```js\n   // vite.config.ts\n   import { defineConfig } from 'vite';\n   import { aeoVitePlugin } from 'aeo.js/vite';\n\n   export default defineConfig({\n     plugins: [\n       aeoVitePlugin({\n         title: 'My Site',\n         description: 'A site optimized for AI discovery',\n         url: 'https://mysite.com',\n       }),\n     ],\n   });\n   ```\n</Steps>\n\n## How it works\n\nThe Vite plugin:\n\n- Generates AEO files on both `vite dev` and `vite build`\n- Injects the Human/AI widget automatically via HTML transform\n- Serves dynamic `.md` files during development (extracts content from your running app)\n- Detects SPA shells and falls back to client-side DOM extraction\n- Works with React, Vue, Svelte, or any Vite-based framework\n\n## Configuration\n\nPass any [AeoConfig](/reference/configuration/) options to the plugin:\n\n```js\naeoVitePlugin({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  widget: {\n    position: 'top-right',\n    theme: {\n      background: 'rgba(0, 0, 0, 0.85)',\n      accent: '#f59e0b',\n    },\n  },\n});\n```",
      "description": "Use aeo.js with Vite (React, Vue, Svelte, etc.).",
      "keywords": [
        "vite",
        "from",
        "import",
        "steps",
        "plugin",
        "aeoviteplugin",
        "site",
        "install",
        "your",
        "config"
      ],
      "metadata": {
        "title": "Vite",
        "description": "Use aeo.js with Vite (React, Vue, Svelte, etc.).",
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "docs/frameworks/vite.mdx"
      }
    },
    {
      "id": "5662a1147ae5df90",
      "url": "https://aeojs.org/docs/features/json-ld",
      "title": "JSON-LD Recipes (Part 2)",
      "content": "```ts\nconst howToSchema = {\n  '@context': 'https://schema.org',\n  '@type': 'HowTo',\n  name: 'How to deploy a Next.js site to Vercel',\n  totalTime: 'PT5M',\n  step: [\n    { '@type': 'HowToStep', position: 1, name: 'Install CLI', text: 'Run `npm install -g vercel`.' },\n    { '@type': 'HowToStep', position: 2, name: 'Login',       text: 'Run `vercel login`.' },\n    { '@type': 'HowToStep', position: 3, name: 'Deploy',      text: 'Run `vercel --prod`.' },\n  ],\n};\n```\n\naeo.js **auto-detects** `Step 1:` / `Step 2:` heading patterns.\n\n## Article / BlogPosting\n\n```ts\nconst articleSchema = {\n  '@context': 'https://schema.org',\n  '@type': 'BlogPosting',\n  headline: 'Optimizing your site for AI search engines in 2026',\n  image: 'https://mysite.com/og/article-cover.png',\n  datePublished: '2026-05-14T10:00:00Z',\n  dateModified: '2026-05-14T10:00:00Z',\n  author: { '@type': 'Person', name: 'Jane Author' },\n  publisher: {\n    '@type': 'Organization',\n    name: 'My Site',\n    logo: { '@type': 'ImageObject', url: 'https://mysite.com/logo.png' },\n  },\n};\n```\n\n<Aside type=\"caution\">\nAlways use ISO-8601 strings for `datePublished` / `dateModified`. A raw `Date` object passed through a template literal renders as `\"Thu May 14 2026 ...\"` and breaks validators. Wrap with `new Date(d).toISOString()`.\n</Aside>\n\n## Product\n\n```ts\nconst productSchema = {\n  '@context': 'https://schema.org',\n  '@type': 'Product',\n  name: 'Acme Espresso Machine',\n  description: 'A semi-automatic espresso machine with built-in grinder.',\n  image: ['https://mysite.com/products/espresso/cover.jpg'],\n  sku: 'ACM-ESP-001',\n  brand: { '@type': 'Brand', name: 'Acme' },\n  offers: {\n    '@type': 'Offer',\n    url: 'https://mysite.com/products/espresso',\n    priceCurrency: 'USD',\n    price: '899.00',\n    availability: 'https://schema.org/InStock',\n  },\n  aggregateRating: {\n    '@type': 'AggregateRating',\n    ratingValue: '4.7',\n    reviewCount: '142',\n  },\n};\n```\n\n## BreadcrumbList",
      "description": "Copy-paste structured-data recipes for FAQ, HowTo, Product, Article, Recipe, Event, VideoObject, and BreadcrumbList — each paired with an XSS-safe serializer.",
      "keywords": [
        "type",
        "json",
        "https",
        "schema",
        "script",
        "name",
        "tabitem",
        "serializejsonforhtml",
        "aside",
        "const"
      ],
      "metadata": {
        "title": "JSON-LD Recipes",
        "description": "Copy-paste structured-data recipes for FAQ, HowTo, Product, Article, Recipe, Event, VideoObject, and BreadcrumbList — each paired with an XSS-safe serializer.",
        "chunkIndex": 1,
        "totalChunks": 4,
        "sourcePath": "docs/features/json-ld.mdx"
      }
    },
    {
      "id": "5ed515c47e46d362",
      "url": "https://aeojs.org/features/audit",
      "title": "Audit & Citability (Part 2)",
      "content": "pages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],\n\n});\n\nconst report = generateReport(config);\n\n// Get as markdown\n\nconsole.log(formatReportMarkdown(report));\n\n// Get as JSON\n\nconsole.log(formatReportJson(report));\n\n## Platform Hints\n\n[Section titled “Platform Hints”](#platform-hints)\n\nGet platform-specific optimization suggestions:\n\nimport { auditSite, generatePlatformHints, resolveConfig, scoreSiteCitability } from 'aeo.js';\n\nconst config = resolveConfig({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\npages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],\n\n});\n\nconst audit = auditSite(config);\n\nconst citability = scoreSiteCitability(config);\n\nconst hints = generatePlatformHints(audit, citability);\n\n// Returns platform-specific optimization hints for ChatGPT, Perplexity, Google AI, and Bing Copilot\n\n[Previous\nJSON-LD Recipes](/features/json-ld/) [Next\nConfiguration](/reference/configuration/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Audit your AEO setup and measure your site",
      "keywords": [
        "site",
        "const",
        "config",
        "title",
        "resolveconfig",
        "content",
        "audit",
        "citability",
        "score",
        "https"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "/features/audit"
      }
    },
    {
      "id": "6055a51f37e7cb9c",
      "url": "https://aeojs.org/docs/features/json-ld",
      "title": "JSON-LD Recipes (Part 4)",
      "content": "<Aside>\nFull catalog (including **Recipe**, **Event**, **VideoObject**, and more per-framework injection variants like React Helmet and vanilla HTML) is in [docs/json-ld.md on GitHub](https://github.com/multivmlabs/aeo.js/blob/main/docs/json-ld.md).\n</Aside>",
      "description": "Copy-paste structured-data recipes for FAQ, HowTo, Product, Article, Recipe, Event, VideoObject, and BreadcrumbList — each paired with an XSS-safe serializer.",
      "keywords": [
        "type",
        "json",
        "https",
        "schema",
        "script",
        "name",
        "tabitem",
        "serializejsonforhtml",
        "aside",
        "const"
      ],
      "metadata": {
        "title": "JSON-LD Recipes",
        "description": "Copy-paste structured-data recipes for FAQ, HowTo, Product, Article, Recipe, Event, VideoObject, and BreadcrumbList — each paired with an XSS-safe serializer.",
        "chunkIndex": 3,
        "totalChunks": 4,
        "sourcePath": "docs/features/json-ld.mdx"
      }
    },
    {
      "id": "60fd04c439d85529",
      "url": "https://aeojs.org/frameworks/vite",
      "title": "Vite",
      "content": "## Vite\n\n## Setup\n\n[Section titled “Setup”](#setup)\n\n-\nInstall the package:\n\nTerminal window\n\nnpm install aeo.js\n\n-\nAdd the plugin to your Vite config:\n\nvite.config.ts\n\nimport { defineConfig } from 'vite';\n\nimport { aeoVitePlugin } from 'aeo.js/vite';\n\nexport default defineConfig({\n\nplugins: [aeoVitePlugin({\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n}),],\n\n});\n\n## How it works\n\n[Section titled “How it works”](#how-it-works)\n\nThe Vite plugin:\n\n- Generates AEO files on both vite dev and vite build\n\n- Injects the Human/AI widget automatically via HTML transform\n\n- Serves dynamic .md files during development (extracts content from your running app)\n\n- Detects SPA shells and falls back to client-side DOM extraction\n\n- Works with React, Vue, Svelte, or any Vite-based framework\n\n## Configuration\n\n[Section titled “Configuration”](#configuration)\n\nPass any [AeoConfig](/reference/configuration/) options to the plugin:\n\naeoVitePlugin({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\nwidget: {\n\nposition: 'top-right',\n\ntheme: {\n\nbackground: 'rgba(0, 0, 0, 0.85)',\n\naccent: '#f59e0b',\n\n},\n\n},\n\n});\n\n[Previous\nNext.js](/frameworks/nextjs/) [Next\nNuxt](/frameworks/nuxt/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Use aeo.js with Vite (React, Vue, Svelte, etc.).",
      "keywords": [
        "vite",
        "https",
        "works",
        "configuration",
        "setup",
        "section",
        "titled",
        "plugin",
        "from",
        "aeoviteplugin"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "/frameworks/vite"
      }
    },
    {
      "id": "61fe649bb78ba17b",
      "url": "https://aeojs.org/docs/frameworks/vanilla",
      "title": "Vanilla JS / Static HTML (Part 3)",
      "content": "- [CLI Reference](/features/cli/) — every command, every flag\n- [JSON-LD Recipes](/features/json-ld/) — FAQ, HowTo, Product, Article, Recipe, Event\n- [Configuration Reference](/reference/configuration/)",
      "description": "Use aeo.js with a plain HTML site, hand-rolled JS, or any static-site generator — no framework required.",
      "keywords": [
        "site",
        "json",
        "https",
        "title",
        "from",
        "html",
        "mysite",
        "public",
        "contentdir",
        "pages"
      ],
      "metadata": {
        "title": "Vanilla JS / Static HTML",
        "description": "Use aeo.js with a plain HTML site, hand-rolled JS, or any static-site generator — no framework required.",
        "chunkIndex": 2,
        "totalChunks": 3,
        "sourcePath": "docs/frameworks/vanilla.mdx"
      }
    },
    {
      "id": "6216767cbf68c5a7",
      "url": "https://aeojs.org/docs/features/cli",
      "title": "CLI (Part 1)",
      "content": "## Usage\n\n```bash\nnpx aeo.js <command> [options]\n```\n\n## Commands\n\n### `generate`\n\nGenerate all AEO files (robots.txt, llms.txt, sitemap.xml, etc.):\n\n```bash\nnpx aeo.js generate\nnpx aeo.js generate --url https://mysite.com --title \"My Site\" --out public\n```\n\n### `init`\n\nCreate an `aeo.config.ts` configuration file in your project:\n\n```bash\nnpx aeo.js init\n```\n\nThis generates a starter config with all options documented.\n\n### `check`\n\nValidate your AEO setup and get a GEO readiness score (0–100). Does not write any files — safe to run in CI:\n\n```bash\nnpx aeo.js check              # formatted output\nnpx aeo.js check --json       # machine-readable JSON for scripting\n```\n\nFail a CI build if the score drops below a threshold:\n\n```bash\nSCORE=$(npx aeo.js check --json | jq '.audit.score')\n[ \"$SCORE\" -ge 70 ] || { echo \"GEO score $SCORE below 70\"; exit 1; }\n```\n\n### `report`\n\nDeeper analysis than `check`: per-page citability scores, platform-specific hints (ChatGPT, Claude, Perplexity, Google AI Overviews, Bing Copilot), and a prioritized fix list.\n\n```bash\nnpx aeo.js report > aeo-report.md\nnpx aeo.js report --json > aeo-report.json\n```\n\n## Options\n\n| Flag | Description |\n|------|-------------|\n| `--out <dir>` | Output directory (default: auto-detected) |\n| `--url <url>` | Site URL |\n| `--title <title>` | Site title |\n| `--no-widget` | Disable widget generation |\n| `--json` | JSON output (for `check` and `report`) |\n| `--help`, `-h` | Show help |\n| `--version`, `-v` | Show version |\n\nBoth `--flag value` and `--flag=value` forms are supported.\n\n## Configuration file\n\nimport { Aside } from '@astrojs/starlight/components';\n\n<Aside type=\"caution\">\nThe standalone CLI does **not** currently load `aeo.config.{ts,js}` — it configures itself from CLI flags + defaults only. `npx aeo.js init` still scaffolds the file as the canonical place for your settings, but today it's consumed by framework integrations rather than the CLI itself.\n</Aside>\n\nCreate one with `npx aeo.js init`:",
      "description": "Run aeo.js from the command line without any framework integration.",
      "keywords": [
        "json",
        "bash",
        "site",
        "score",
        "title",
        "config",
        "check",
        "report",
        "generate",
        "import"
      ],
      "metadata": {
        "title": "CLI",
        "description": "Run aeo.js from the command line without any framework integration.",
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "docs/features/cli.mdx"
      }
    },
    {
      "id": "629770d2b54e81c7",
      "url": "https://aeojs.org/docs/features/cli",
      "title": "CLI (Part 2)",
      "content": "```ts\nimport { defineConfig } from 'aeo.js';\n\nexport default defineConfig({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  description: 'A site optimized for AI discovery',\n  outDir: 'public',\n});\n```\n\nImport it into your framework config so the integration picks it up:\n\n```ts\n// vite.config.ts\nimport aeoConfig from './aeo.config';\nimport { aeoVitePlugin } from 'aeo.js/vite';\n\nexport default { plugins: [aeoVitePlugin(aeoConfig)] };\n```\n\nFor raw CLI usage on a static site, pass values directly:\n\n```bash\nnpx aeo.js generate --url https://mysite.com --title \"My Site\" --out public\n```\n\nSee the full [Configuration reference](/reference/configuration/) for all options.\n\nA complete CLI reference with every flag, exit codes, JSON output shapes, framework auto-detection table, and CI scripting patterns is in [docs/cli.md on GitHub](https://github.com/multivmlabs/aeo.js/blob/main/docs/cli.md).",
      "description": "Run aeo.js from the command line without any framework integration.",
      "keywords": [
        "json",
        "bash",
        "site",
        "score",
        "title",
        "config",
        "check",
        "report",
        "generate",
        "import"
      ],
      "metadata": {
        "title": "CLI",
        "description": "Run aeo.js from the command line without any framework integration.",
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "docs/features/cli.mdx"
      }
    },
    {
      "id": "660fe587a773ab7c",
      "url": "https://aeojs.org/reference/api",
      "title": "API Reference (Part 4)",
      "content": "[Section titled “generatePlatformHints(audit, citability)”](#generateplatformhintsaudit-citability)\n\nGenerate platform-specific optimization hints from audit and citability results:\n\nimport { auditSite, generatePlatformHints, scoreSiteCitability } from 'aeo.js';\n\nconst audit = auditSite(resolvedConfig);\n\nconst citability = scoreSiteCitability(resolvedConfig);\n\nconst hints = generatePlatformHints(audit, citability);\n\n## Types\n\n[Section titled “Types”](#types)\n\nAll types are exported from the main entry:\n\nimport type {\n\nAeoConfig,\n\nResolvedAeoConfig,\n\nPageEntry,\n\nDocEntry,\n\nAeoManifest,\n\nMarkdownFile,\n\nManifestEntry,\n\nAIIndexEntry,\n\nFrameworkType,\n\nFrameworkInfo,\n\nAuditResult,\n\nAuditCategory,\n\nAuditIssue,\n\nMetaTag,\n\nPageCitabilityResult,\n\nSiteCitabilityResult,\n\nCitabilityDimension,\n\nContentHint,\n\nAeoReport,\n\nPlatformHint,\n\n} from 'aeo.js';\n\n[Previous\nConfiguration](/reference/configuration/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Programmatic API for aeo.js.",
      "keywords": [
        "config",
        "section",
        "titled",
        "from",
        "html",
        "const",
        "import",
        "title",
        "citability",
        "site"
      ],
      "metadata": {
        "chunkIndex": 3,
        "totalChunks": 4,
        "sourcePath": "/reference/api"
      }
    },
    {
      "id": "6687571ae068be4f",
      "url": "https://aeojs.org/getting-started/introduction",
      "title": "Introduction (Part 2)",
      "content": "- structures content so AI crawlers can fetch, parse, and quote it\n\n- audits and scores your page-level citability so you know where to improve\n\nWhat aeo.js cannot influence\n\nOff-site signals that AI engines also weigh:\n\n- **third-party mentions and reviews** of your product across the web\n\n- **inbound links** and how reputable the linking domains are\n\n- **community discussions** (Reddit, Hacker News, X, niche forums) and how often you’re cited there\n\n- **model training data** — what an LLM “already knows” about you from its pre-training cutoff\n\n- **freshness signals** outside your control (independent news, blog roundups, podcasts)\n\nThink 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.\n\n## Supported Frameworks\n\n[Section titled “Supported Frameworks”](#supported-frameworks)\n\nFramework\n\nImport\n\nAstro\n\naeo.js/astro\n\nNext.js\n\naeo.js/next\n\nVite (React, Vue, Svelte)\n\naeo.js/vite\n\nNuxt\n\naeo.js/nuxt\n\nAngular\n\naeo.js/angular\n\nWebpack\n\naeo.js/webpack\n\nAny (CLI)\n\nnpx aeo.js generate\n\n[Next\nInstallation](/getting-started/installation/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "What is aeo.js and why you need Answer Engine Optimization.",
      "keywords": [
        "your",
        "what",
        "content",
        "llms",
        "site",
        "answer",
        "engine",
        "section",
        "titled",
        "full"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "/getting-started/introduction"
      }
    },
    {
      "id": "6748cb72ec53a1ed",
      "url": "https://aeojs.org/features/audit",
      "title": "Audit & Citability (Part 1)",
      "content": "## Audit & Citability\n\n## Site Audit\n\n[Section titled “Site Audit”](#site-audit)\n\nThe auditSite function checks your site for AEO best practices and returns a detailed report:\n\n-\n\nimport { auditSite, formatAuditReport, getGrade, resolveConfig } from 'aeo.js';\n\nconst config = resolveConfig({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\npages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],\n\n});\n\nconst result = auditSite(config);\n\nconsole.log(formatAuditReport(result));\n\nconsole.log('Grade:', getGrade(result.score));\n\nThe audit checks for:\n\nPresence of robots.txt, llms.txt, llms-full.txt\n\n- Sitemap accessibility\n\n- Structured data (JSON-LD)\n\n- Open Graph meta tags\n\n- AI crawler accessibility\n\nYou can also run it from the CLI:\n\nTerminal window\n\nnpx aeo.js check\n\n## Citability Score\n\n[Section titled “Citability Score”](#citability-score)\n\nMeasure how likely AI engines are to cite your content:\n\nimport { formatPageCitability, resolveConfig, scorePageCitability, scoreSiteCitability } from 'aeo.js';\n\n// Score a single page\n\nconst pageScore = scorePageCitability({\n\npathname: '/',\n\ntitle: 'Home',\n\ncontent: '# Home\\n\\nMy site publishes practical guides for AI-ready content.',\n\n});\n\nconsole.log(formatPageCitability(pageScore));\n\n// Score the whole site\n\nconst config = resolveConfig({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\npages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],\n\n});\n\nconst siteScore = scoreSiteCitability(config);\n\nThe citability score evaluates:\n\n- Content structure and headings\n\n- Factual density and specificity\n\n- Source attribution\n\n- Unique data and statistics\n\n- Clear definitions and explanations\n\n## Reports\n\n[Section titled “Reports”](#reports)\n\nGenerate a comprehensive AEO report:\n\nimport { formatReportJson, formatReportMarkdown, generateReport, resolveConfig } from 'aeo.js';\n\nconst config = resolveConfig({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',",
      "description": "Audit your AEO setup and measure your site",
      "keywords": [
        "site",
        "const",
        "config",
        "title",
        "resolveconfig",
        "content",
        "audit",
        "citability",
        "score",
        "https"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "/features/audit"
      }
    },
    {
      "id": "67f7ab9c9a5c4a50",
      "url": "https://aeojs.org/frameworks/nextjs",
      "title": "Next.js (Part 2)",
      "content": "[Previous\nAstro](/frameworks/astro/) [Next\nVite](/frameworks/vite/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Use aeo.js with Next.js.",
      "keywords": [
        "widget",
        "next",
        "https",
        "site",
        "title",
        "mysite",
        "true",
        "import",
        "config",
        "withaeo"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "/frameworks/nextjs"
      }
    },
    {
      "id": "6a8fb9e052251f1c",
      "url": "https://aeojs.org/frameworks/astro",
      "title": "Astro",
      "content": "## Astro\n\n## Setup\n\n[Section titled “Setup”](#setup)\n\n-\nInstall the package:\n\nTerminal window\n\nnpm install aeo.js\n\n-\nAdd the integration to your Astro config:\n\nastro.config.mjs\n\nimport { defineConfig } from 'astro/config';\n\nimport { aeoAstroIntegration } from 'aeo.js/astro';\n\nexport default defineConfig({\n\nsite: 'https://mysite.com',\n\nintegrations: [aeoAstroIntegration({\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n}),],\n\n});\n\n-\nBuild your site:\n\nTerminal window\n\nnpm run build\n\n## How it works\n\n[Section titled “How it works”](#how-it-works)\n\nThe Astro integration:\n\n- Hooks into the Astro build pipeline via astro:build:done\n\n- Scans all rendered HTML pages for content extraction\n\n- Generates all AEO files in your output directory\n\n- Automatically injects the Human/AI widget\n\n- Persists the widget across View Transitions\n\n## Configuration\n\n[Section titled “Configuration”](#configuration)\n\nPass any [AeoConfig](/reference/configuration/) options to the integration:\n\naeoAstroIntegration({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\ngenerators: {\n\nrobotsTxt: true,\n\nllmsTxt: true,\n\nsitemap: false, // Astro has its own sitemap\n\n},\n\nwidget: {\n\nposition: 'bottom-left',\n\ntheme: {\n\naccent: '#6366f1',\n\n},\n\n},\n\n});\n\n[Previous\nQuick Start](/getting-started/quick-start/) [Next\nNext.js](/frameworks/nextjs/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Use aeo.js with Astro.",
      "keywords": [
        "astro",
        "site",
        "https",
        "build",
        "configuration",
        "setup",
        "section",
        "titled",
        "integration",
        "your"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "/frameworks/astro"
      }
    },
    {
      "id": "6c29872e11094b15",
      "url": "https://aeojs.org/features/json-ld",
      "title": "JSON-LD Recipes (Part 1)",
      "content": "## JSON-LD Recipes\n\naeo.js auto-generates WebSite, Organization, and WebPage schemas when schema.enabled: true. For richer page-type-specific schemas, drop these into your page templates.\n\n## The safe serializer\n\n[Section titled “The safe serializer”](#the-safe-serializer)\n\nJSON.stringify(...) does **not** escape &#x3C;/script>. A schema value containing &#x3C;/script> (or U+2028 / U+2029) breaks out of the script block and executes as JavaScript. Always run JSON-LD payloads through this helper before injection:\n\n-\n\nlib/serialize-json-ld.ts\n\nexport function serializeJsonForHtml(value: unknown): string {\n\nreturn JSON.stringify(value)\n\n.replace(/&#x3C;/g, '\\\\u003C')\n\n.replace(/>/g, '\\\\u003E')\n\n.replace(/&#x26;/g, '\\\\u0026')\n\n.replace(/\\u2028/g, '\\\\u2028')\n\n.replace(/\\u2029/g, '\\\\u2029');\n\n}\n\n**/g, &#x27;\\\\u003E&#x27;) .replace(/&#x26;/g, &#x27;\\\\u0026&#x27;) .replace(/\\u2028/g, &#x27;\\\\u2028&#x27;) .replace(/\\u2029/g, &#x27;\\\\u2029&#x27;);}\">\n\nNote\n\naeo.js’s own auto-generated JSON-LD already uses this serializer internally. The recipes below are for custom** JSON-LD you add on top.\n\n## FAQ Page\n\n[Section titled “FAQ Page”](#faq-page)\n\nconst faqSchema = {\n\n'@context': 'https://schema.org',\n\n'@type': 'FAQPage',\n\nmainEntity: [{\n\n'@type': 'Question',\n\nname: 'What is Answer Engine Optimization?',\n\nacceptedAnswer: {\n\n'@type': 'Answer',\n\ntext: 'AEO is the practice of making your content discoverable and citable by AI-powered answer engines like ChatGPT, Claude, and Perplexity.',\n\n},\n\n},],\n\n};\n\n**\n\naeo.js auto-detects** FAQ patterns (heading ending with ? + answer paragraph) and emits this schema for you when schema.enabled: true.\n\n## HowTo\n\n[Section titled “HowTo”](#howto)\n\nconst howToSchema = {\n\n'@context': 'https://schema.org',\n\n'@type': 'HowTo',\n\nname: 'How to deploy a Next.js site to Vercel',\n\ntotalTime: 'PT5M',\n\nstep: [{ '@type': 'HowToStep', position: 1, name: 'Install CLI', text: 'Run `npm install -g vercel`.' },",
      "description": "Copy-paste structured-data recipes for FAQ, HowTo, Product, Article, Recipe, Event, VideoObject, and BreadcrumbList — each paired with an XSS-safe serializer.",
      "keywords": [
        "type",
        "https",
        "schema",
        "json",
        "name",
        "section",
        "titled",
        "script",
        "replace",
        "const"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 3,
        "sourcePath": "/features/json-ld"
      }
    },
    {
      "id": "6da3883592f1dc03",
      "url": "https://aeojs.org/docs/features/json-ld",
      "title": "JSON-LD Recipes (Part 1)",
      "content": "import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';\n\naeo.js auto-generates `WebSite`, `Organization`, and `WebPage` schemas when `schema.enabled: true`. For richer page-type-specific schemas, drop these into your page templates.\n\n## The safe serializer\n\n`JSON.stringify(...)` does **not** escape `</script>`. A schema value containing `</script>` (or U+2028 / U+2029) breaks out of the script block and executes as JavaScript. Always run JSON-LD payloads through this helper before injection:\n\n```ts\n// lib/serialize-json-ld.ts\nexport function serializeJsonForHtml(value: unknown): string {\n  return JSON.stringify(value)\n    .replace(/</g, '\\\\u003C')\n    .replace(/>/g, '\\\\u003E')\n    .replace(/&/g, '\\\\u0026')\n    .replace(/\\u2028/g, '\\\\u2028')\n    .replace(/\\u2029/g, '\\\\u2029');\n}\n```\n\n<Aside>\naeo.js's own auto-generated JSON-LD already uses this serializer internally. The recipes below are for **custom** JSON-LD you add on top.\n</Aside>\n\n## FAQ Page\n\n```ts\nconst faqSchema = {\n  '@context': 'https://schema.org',\n  '@type': 'FAQPage',\n  mainEntity: [\n    {\n      '@type': 'Question',\n      name: 'What is Answer Engine Optimization?',\n      acceptedAnswer: {\n        '@type': 'Answer',\n        text: 'AEO is the practice of making your content discoverable and citable by AI-powered answer engines like ChatGPT, Claude, and Perplexity.',\n      },\n    },\n  ],\n};\n```\n\naeo.js **auto-detects** FAQ patterns (heading ending with `?` + answer paragraph) and emits this schema for you when `schema.enabled: true`.\n\n## HowTo",
      "description": "Copy-paste structured-data recipes for FAQ, HowTo, Product, Article, Recipe, Event, VideoObject, and BreadcrumbList — each paired with an XSS-safe serializer.",
      "keywords": [
        "type",
        "json",
        "https",
        "schema",
        "script",
        "name",
        "tabitem",
        "serializejsonforhtml",
        "aside",
        "const"
      ],
      "metadata": {
        "title": "JSON-LD Recipes",
        "description": "Copy-paste structured-data recipes for FAQ, HowTo, Product, Article, Recipe, Event, VideoObject, and BreadcrumbList — each paired with an XSS-safe serializer.",
        "chunkIndex": 0,
        "totalChunks": 4,
        "sourcePath": "docs/features/json-ld.mdx"
      }
    },
    {
      "id": "72a970dfbf3ce6c2",
      "url": "https://aeojs.org/reference/api",
      "title": "API Reference (Part 3)",
      "content": "{ pathname: '/', title: 'Home' },\n\nresolvedConfig\n\n);\n\n// [{ property: 'og:title', content: 'Home' }, ...]\n\n### generateOGTagsHtml(page, config)\n\n[Section titled “generateOGTagsHtml(page, config)”](#generateogtagshtmlpage-config)\n\nReturns OG tags as an HTML string.\n\n## Audit\n\n[Section titled “Audit”](#audit)\n\n### auditSite(config)\n\n[Section titled “auditSite(config)”](#auditsiteconfig)\n\nAudit a site for AEO best practices:\n\nimport { auditSite, formatAuditReport, getGrade, resolveConfig } from 'aeo.js';\n\nconst config = resolveConfig({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\npages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],\n\n});\n\nconst result = auditSite(config);\n\nconsole.log(formatAuditReport(result));\n\nconsole.log(getGrade(result.score)); // 'Excellent', 'Good', 'Fair', etc.\n\n## Citability\n\n[Section titled “Citability”](#citability)\n\n### scorePageCitability(page)\n\n[Section titled “scorePageCitability(page)”](#scorepagecitabilitypage)\n\nScore how likely a page is to be cited by AI:\n\nimport { scorePageCitability, formatPageCitability } from 'aeo.js';\n\nconst score = scorePageCitability({\n\npathname: '/',\n\ntitle: 'Home',\n\ncontent: '# Home\\n\\nMy site publishes practical guides for AI-ready content.',\n\n});\n\nconsole.log(formatPageCitability(score));\n\n### scoreSiteCitability(config)\n\n[Section titled “scoreSiteCitability(config)”](#scoresitecitabilityconfig)\n\nScore citability across your entire site.\n\n## Reports\n\n[Section titled “Reports”](#reports)\n\n### generateReport(config)\n\n[Section titled “generateReport(config)”](#generatereportconfig)\n\nGenerate a comprehensive AEO report:\n\nimport { generateReport, formatReportMarkdown } from 'aeo.js';\n\nconst report = generateReport(resolvedConfig);\n\nconsole.log(formatReportMarkdown(report));\n\n## Platform Hints\n\n[Section titled “Platform Hints”](#platform-hints)\n\n### generatePlatformHints(audit, citability)",
      "description": "Programmatic API for aeo.js.",
      "keywords": [
        "config",
        "section",
        "titled",
        "from",
        "html",
        "const",
        "import",
        "title",
        "citability",
        "site"
      ],
      "metadata": {
        "chunkIndex": 2,
        "totalChunks": 4,
        "sourcePath": "/reference/api"
      }
    },
    {
      "id": "7301dda1a39fd93b",
      "url": "https://aeojs.org/docs/frameworks/nextjs",
      "title": "Next.js",
      "content": "import { Steps, Aside } from '@astrojs/starlight/components';\n\n## Setup\n\n<Steps>\n1. Install the package:\n   ```bash\n   npm install aeo.js\n   ```\n\n2. Wrap your Next.js config with `withAeo`:\n   ```js\n   // next.config.mjs\n   import { withAeo } from 'aeo.js/next';\n\n   export default withAeo({\n     aeo: {\n       title: 'My Site',\n       description: 'A site optimized for AI discovery',\n       url: 'https://mysite.com',\n     },\n   });\n   ```\n\n3. Add the post-build step to your `package.json`:\n   ```json\n   {\n     \"scripts\": {\n       \"postbuild\": \"node -e \\\"import('aeo.js/next').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\\\"\"\n     }\n   }\n   ```\n</Steps>\n\n<Aside type=\"tip\">\nThe `postbuild` step is needed because Next.js pre-renders pages during build. The post-build step scans the rendered HTML to extract full page content.\n</Aside>\n\n## Widget\n\nFor Next.js, add the widget manually as a client component:\n\n```tsx\n// app/layout.tsx (or any client component)\n'use client';\nimport { useEffect } from 'react';\n\nexport function AeoWidgetLoader() {\n  useEffect(() => {\n    import('aeo.js/widget').then(({ AeoWidget }) => {\n      new AeoWidget({\n        config: {\n          title: 'My Site',\n          url: 'https://mysite.com',\n          widget: { enabled: true, position: 'bottom-right' },\n        },\n      });\n    });\n  }, []);\n  return null;\n}\n```\n\n## Configuration\n\nPass any [AeoConfig](/reference/configuration/) options in the `aeo` key:\n\n```js\nexport default withAeo({\n  aeo: {\n    title: 'My Site',\n    url: 'https://mysite.com',\n    generators: {\n      robotsTxt: true,\n      llmsTxt: true,\n      schema: true,\n    },\n    widget: {\n      enabled: true,\n      position: 'bottom-right',\n    },\n  },\n});\n```",
      "description": "Use aeo.js with Next.js.",
      "keywords": [
        "next",
        "import",
        "site",
        "widget",
        "true",
        "withaeo",
        "title",
        "https",
        "mysite",
        "steps"
      ],
      "metadata": {
        "title": "Next.js",
        "description": "Use aeo.js with Next.js.",
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "docs/frameworks/nextjs.mdx"
      }
    },
    {
      "id": "77c89f00c11e6580",
      "url": "https://aeojs.org",
      "title": "aeo.js — Answer Engine Optimization for the Modern Web (Part 4)",
      "content": " \">\n\n## Configuration\n\n[Section titled “Configuration”](#configuration)\n\nAll frameworks use the same config shape — [see full reference](/reference/configuration/):\n\nimport { defineConfig } from 'aeo.js';\n\nexport default defineConfig({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\ndescription: 'A site optimized for AI discovery',\n\ngenerators: {\n\nrobotsTxt: true,\n\nllmsTxt: true,\n\nllmsFullTxt: true,\n\nrawMarkdown: true,\n\nsitemap: true,\n\naiIndex: true,\n\nschema: true,\n\n},\n\nschema: {\n\nenabled: true,\n\norganization: { name: 'My Company', url: 'https://mysite.com' },\n\ndefaultType: 'WebPage',\n\n},\n\nog: {\n\nenabled: true,\n\nimage: 'https://mysite.com/og.png',\n\ntwitterHandle: '@mycompany',\n\n},\n\nwidget: {\n\nenabled: true,\n\nposition: 'bottom-right',\n\ntheme: { accent: '#4ADE80', badge: '#4ADE80' },\n\n},\n\n});\n\n## Generated Files\n\n[Section titled “Generated Files”](#generated-files)\n\nAfter building, your output directory contains:\n\npublic/\n\n├── robots.txt # AI-crawler directives\n\n├── llms.txt # Short LLM-readable summary\n\n├── llms-full.txt # Full content for LLMs\n\n├── sitemap.xml # Standard sitemap\n\n├── docs.json # Documentation manifest\n\n├── ai-index.json # AI content index\n\n├── index.md # Markdown for /\n\n└── about.md # Markdown for /about\n\n## Checker\n\n[Section titled “Checker”](#checker)\n\nScan\n\nFree — no signup required. Powered by [AEO Checker](https://check.aeojs.org)\n\n## Built by\n\n[](https://github.com/rubenmarcus)[](https://github.com/KimHyeongRae0)[](https://github.com/FabioRocha231)[](https://github.com/ribeiroevandro)[](https://github.com/HusseinAdeiza)[](https://github.com/mhanelia)\n[View all 6 contributors →](/contributors/)\n\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
      "keywords": [
        "https",
        "site",
        "title",
        "mysite",
        "import",
        "config",
        "widget",
        "true",
        "from",
        "files"
      ],
      "metadata": {
        "chunkIndex": 3,
        "totalChunks": 4,
        "sourcePath": "/"
      }
    },
    {
      "id": "7d6be39e623d2df8",
      "url": "https://aeojs.org/features/generated-files",
      "title": "Generated Files (Part 2)",
      "content": "blog.md # Markdown for /blog\n\n## Toggling generators\n\n[Section titled “Toggling generators”](#toggling-generators)\n\nYou can enable or disable individual generators:\n\n{\n\ngenerators: {\n\nrobotsTxt: true,\n\nllmsTxt: true,\n\nllmsFullTxt: true,\n\nrawMarkdown: true,\n\nmanifest: true,\n\nsitemap: true,\n\naiIndex: true,\n\nschema: true,\n\n}\n\n}\n\n[Previous\nVanilla JS / Static HTML](/frameworks/vanilla/) [Next\nWidget](/features/widget/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "All the files aeo.js generates and what they",
      "keywords": [
        "https",
        "section",
        "titled",
        "true",
        "site",
        "mysite",
        "markdown",
        "llms",
        "content",
        "index"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "/features/generated-files"
      }
    },
    {
      "id": "897334fff5d461e1",
      "url": "https://aeojs.org/docs/getting-started/installation",
      "title": "Installation",
      "content": "import { Tabs, TabItem } from '@astrojs/starlight/components';\n\n## Install the package\n\n<Tabs>\n  <TabItem label=\"npm\">\n    ```bash\n    npm install aeo.js\n    ```\n  </TabItem>\n  <TabItem label=\"pnpm\">\n    ```bash\n    pnpm add aeo.js\n    ```\n  </TabItem>\n  <TabItem label=\"yarn\">\n    ```bash\n    yarn add aeo.js\n    ```\n  </TabItem>\n</Tabs>\n\n## Or use the CLI directly\n\nNo installation needed — run it with `npx`:\n\n```bash\nnpx aeo.js generate\n```\n\n## Requirements\n\n- **Node.js** 18 or later\n- A framework with a build step that outputs HTML (or use the CLI for any static site)\n\n## Next steps\n\nHead to [Quick Start](/getting-started/quick-start/) to add aeo.js to your project, or jump to your framework's guide:\n\n- [Astro](/frameworks/astro/)\n- [Next.js](/frameworks/nextjs/)\n- [Vite](/frameworks/vite/)\n- [Nuxt](/frameworks/nuxt/)\n- [Angular](/frameworks/angular/)\n- [Webpack](/frameworks/webpack/)",
      "description": "Install aeo.js in your project.",
      "keywords": [
        "tabitem",
        "frameworks",
        "bash",
        "tabs",
        "label",
        "install",
        "pnpm",
        "yarn",
        "with",
        "framework"
      ],
      "metadata": {
        "title": "Installation",
        "description": "Install aeo.js in your project.",
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "docs/getting-started/installation.mdx"
      }
    },
    {
      "id": "8e7a1608a84d0dc1",
      "url": "https://aeojs.org/reference/configuration",
      "title": "Configuration (Part 2)",
      "content": "Manually specify pages to include\n\n### generators\n\n[Section titled “generators”](#generators)\n\nOption\n\nType\n\nDefault\n\nDescription\n\nrobotsTxt\n\nboolean\n\ntrue\n\nGenerate robots.txt\n\nllmsTxt\n\nboolean\n\ntrue\n\nGenerate llms.txt\n\nllmsFullTxt\n\nboolean\n\ntrue\n\nGenerate llms-full.txt\n\nrawMarkdown\n\nboolean\n\ntrue\n\nGenerate per-page .md files\n\nmanifest\n\nboolean\n\ntrue\n\nGenerate docs.json\n\nsitemap\n\nboolean\n\ntrue\n\nGenerate sitemap.xml\n\naiIndex\n\nboolean\n\ntrue\n\nGenerate ai-index.json\n\nschema\n\nboolean\n\nfalse\n\nGenerate JSON-LD structured data\n\n### aiIndex\n\n[Section titled “aiIndex”](#aiindex)\n\nOption\n\nType\n\nDefault\n\nDescription\n\nmaxChunkLength\n\nnumber\n\n2000\n\nTarget chunk length (soft limit). Chunks split on \\n\\n paragraph boundaries, so a single long paragraph can exceed this value. Set with embedding-model token limits in mind.\n\nmaxKeywords\n\nnumber\n\n10\n\nMaximum number of keywords extracted per ai-index.json entry.\n\n### robots\n\n[Section titled “robots”](#robots)\n\nOption\n\nType\n\nDefault\n\nDescription\n\nallow\n\nstring[]\n\n['/']\n\nAllowed paths\n\ndisallow\n\nstring[]\n\n[]\n\nDisallowed paths\n\ncrawlDelay\n\nnumber\n\n0\n\nCrawl delay in seconds\n\nsitemap\n\nstring\n\nauto\n\nSitemap URL\n\n### schema\n\n[Section titled “schema”](#schema)\n\nOption\n\nType\n\nDefault\n\nDescription\n\nenabled\n\nboolean\n\nfalse\n\nEnable schema generation\n\norganization.name\n\nstring\n\n''\n\nOrganization name\n\norganization.url\n\nstring\n\n''\n\nOrganization URL\n\norganization.logo\n\nstring\n\n''\n\nOrganization logo URL\n\norganization.sameAs\n\nstring[]\n\n[]\n\nSocial profile URLs\n\ndefaultType\n\n'Article' | 'WebPage'\n\n'WebPage'\n\nDefault schema type for pages\n\n### og\n\n[Section titled “og”](#og)\n\nOption\n\nType\n\nDefault\n\nDescription\n\nenabled\n\nboolean\n\nfalse\n\nEnable OG tag generation\n\nimage\n\nstring\n\n''\n\nDefault OG image URL\n\ntwitterHandle\n\nstring\n\n''\n\nTwitter handle (e.g. @company)\n\ntype\n\n'website' | 'article'\n\n'website'\n\nDefault OG type\n\n### widget\n\n[Section titled “widget”](#widget)\n\nOption\n\nType\n\nDefault\n\nDescription\n\nenabled\n\nboolean\n\ntrue\n\nEnable the widget\n\nposition\n\nstring",
      "description": "Full configuration reference for aeo.js.",
      "keywords": [
        "true",
        "string",
        "boolean",
        "default",
        "description",
        "type",
        "section",
        "titled",
        "https",
        "schema"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 3,
        "sourcePath": "/reference/configuration"
      }
    },
    {
      "id": "988c293450866ae4",
      "url": "https://aeojs.org/docs/reference/configuration",
      "title": "Configuration (Part 1)",
      "content": "All framework plugins and the CLI accept the same `AeoConfig` object.\n\n## Full example\n\n```ts\nimport { defineConfig } from 'aeo.js';\n\nexport default defineConfig({\n  // Required\n  title: 'My Site',\n  url: 'https://mysite.com',\n\n  // Optional\n  description: 'A description of your site',\n  contentDir: 'docs',        // Directory with handwritten .md files\n  outDir: 'public',          // Output directory for generated files\n\n  // Toggle individual generators\n  generators: {\n    robotsTxt: true,\n    llmsTxt: true,\n    llmsFullTxt: true,\n    rawMarkdown: true,\n    manifest: true,\n    sitemap: true,\n    aiIndex: true,\n    schema: true,\n  },\n\n  // Configure ai-index.json generation\n  aiIndex: {\n    maxChunkLength: 2000,\n    maxKeywords: 10,\n  },\n\n  // Customize robots.txt\n  robots: {\n    allow: ['/'],\n    disallow: ['/admin'],\n    crawlDelay: 0,\n    sitemap: 'https://mysite.com/sitemap.xml',\n  },\n\n  // JSON-LD structured data\n  schema: {\n    enabled: true,\n    organization: {\n      name: 'My Company',\n      url: 'https://mysite.com',\n      logo: 'https://mysite.com/logo.png',\n      sameAs: ['https://twitter.com/mycompany'],\n    },\n    defaultType: 'WebPage',\n  },\n\n  // Open Graph meta tags\n  og: {\n    enabled: true,\n    image: 'https://mysite.com/og.png',\n    twitterHandle: '@mycompany',\n    type: 'website',\n  },\n\n  // Widget configuration\n  widget: {\n    enabled: true,\n    position: 'bottom-right',\n    humanLabel: 'Human',\n    aiLabel: 'AI',\n    showBadge: true,\n    theme: {\n      background: 'rgba(18, 18, 24, 0.9)',\n      text: '#C0C0C5',\n      accent: '#E8E8EA',\n      badge: '#4ADE80',\n    },\n  },\n});\n```\n\n## Options reference\n\n### Top-level",
      "description": "Full configuration reference for aeo.js.",
      "keywords": [
        "true",
        "string",
        "boolean",
        "default",
        "description",
        "type",
        "organization",
        "generate",
        "sitemap",
        "option"
      ],
      "metadata": {
        "title": "Configuration",
        "description": "Full configuration reference for aeo.js.",
        "chunkIndex": 0,
        "totalChunks": 3,
        "sourcePath": "docs/reference/configuration.mdx"
      }
    },
    {
      "id": "a1781ad16a6c6389",
      "url": "https://aeojs.org/docs/features/widget",
      "title": "Human/AI Widget (Part 1)",
      "content": "import { Aside } from '@astrojs/starlight/components';\n\nThe Human/AI widget is a floating toggle that lets visitors switch between the normal page and its AI-readable markdown version.\n\n## How it works\n\nWhen a visitor clicks **AI**, the widget:\n\n1. Fetches the `.md` file for the current page\n2. Falls back to extracting markdown from the live DOM if no `.md` exists\n3. Displays the markdown in a slide-out panel\n4. Offers copy-to-clipboard and download actions\n\n## Automatic injection\n\nFramework plugins (Astro, Vite, Nuxt, Angular) inject the widget automatically. No extra code needed.\n\n## Manual setup (Next.js / React)\n\nFor Next.js or other manual setups, create a client component:\n\n```tsx\n'use client';\nimport { useEffect } from 'react';\n\nexport function AeoWidgetLoader() {\n  useEffect(() => {\n    import('aeo.js/widget').then(({ AeoWidget }) => {\n      new AeoWidget({\n        config: {\n          title: 'My Site',\n          url: 'https://mysite.com',\n          widget: { enabled: true, position: 'bottom-right' },\n        },\n      });\n    });\n  }, []);\n  return null;\n}\n```\n\n## Framework components\n\naeo.js ships React, Vue, and Svelte wrapper components:\n\n### React\n\n```tsx\nimport { AeoReactWidget } from 'aeo.js/react';\n\n<AeoReactWidget config={{ title: 'My Site', url: 'https://mysite.com' }} />\n```\n\n### Vue\n\n```vue\n<script setup>\nimport { AeoVueWidget } from 'aeo.js/vue';\n</script>\n\n<template>\n  <AeoVueWidget :config=\"{ title: 'My Site', url: 'https://mysite.com' }\" />\n</template>\n```\n\n## Configuration\n\n```js\nwidget: {\n  enabled: true,\n  position: 'bottom-right', // 'bottom-left' | 'top-right' | 'top-left'\n  size: 'default',          // 'small' | 'icon-only'\n  humanLabel: 'Human',\n  aiLabel: 'AI',\n  showBadge: true,\n  theme: {\n    background: 'rgba(18, 18, 24, 0.9)',\n    text: '#C0C0C5',\n    accent: '#E8E8EA',\n    badge: '#4ADE80',\n  },\n}\n```\n\n## Size variants",
      "description": "The drop-in toggle that shows how AI sees your pages.",
      "keywords": [
        "widget",
        "import",
        "from",
        "react",
        "size",
        "default",
        "small",
        "icon",
        "aside",
        "components"
      ],
      "metadata": {
        "title": "Human/AI Widget",
        "description": "The drop-in toggle that shows how AI sees your pages.",
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "docs/features/widget.mdx"
      }
    },
    {
      "id": "abc0afec27074cbc",
      "url": "https://aeojs.org/getting-started/quick-start",
      "title": "Quick Start (Part 2)",
      "content": "[Previous\nInstallation](/getting-started/installation/) [Next\nAstro](/frameworks/astro/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Get aeo.js running in under 2 minutes.",
      "keywords": [
        "site",
        "astro",
        "https",
        "config",
        "mysite",
        "next",
        "vite",
        "your",
        "install",
        "import"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "/getting-started/quick-start"
      }
    },
    {
      "id": "ae189ca9b89835a2",
      "url": "https://aeojs.org/docs/frameworks/angular",
      "title": "Angular",
      "content": "import { Steps, Aside } from '@astrojs/starlight/components';\n\n## Setup\n\n<Steps>\n1. Install the package:\n   ```bash\n   npm install aeo.js\n   ```\n\n2. Add a post-build step to your `package.json`:\n   ```json\n   {\n     \"scripts\": {\n       \"postbuild\": \"node -e \\\"import('aeo.js/angular').then(m => m.postBuild({ title: 'My App', url: 'https://myapp.com' }))\\\"\"\n     }\n   }\n   ```\n\n3. Build your app:\n   ```bash\n   npm run build\n   ```\n</Steps>\n\n## How it works\n\nThe Angular plugin:\n\n- Reads `angular.json` to auto-detect the output directory (`dist/<project>/browser/`)\n- Scans route config files (`*.routes.ts`) and component directories for routes\n- Scans pre-rendered HTML from the build output for full page content\n- Injects the widget into `index.html` automatically\n\n## Programmatic usage\n\nYou can also generate AEO files from source routes without building:\n\n```ts\nimport { generate } from 'aeo.js/angular';\n\nawait generate({ title: 'My App', url: 'https://myapp.com' });\n```\n\n<Aside type=\"note\">\nAngular SSR (with `@angular/ssr`) is supported. The plugin will scan pre-rendered HTML for content extraction.\n</Aside>\n\n## Configuration\n\nPass any [AeoConfig](/reference/configuration/) options to `postBuild` or `generate`:\n\n```ts\nimport { postBuild } from 'aeo.js/angular';\n\nawait postBuild({\n  title: 'My App',\n  url: 'https://myapp.com',\n  generators: {\n    robotsTxt: true,\n    llmsTxt: true,\n    schema: true,\n  },\n});\n```",
      "description": "Use aeo.js with Angular.",
      "keywords": [
        "angular",
        "from",
        "postbuild",
        "import",
        "build",
        "generate",
        "steps",
        "aside",
        "json",
        "title"
      ],
      "metadata": {
        "title": "Angular",
        "description": "Use aeo.js with Angular.",
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "docs/frameworks/angular.mdx"
      }
    },
    {
      "id": "b070059d705effd7",
      "url": "https://aeojs.org/frameworks/vanilla",
      "title": "Vanilla JS / Static HTML (Part 2)",
      "content": "\"build:aeo\": \"aeo.js generate --url https://mysite.com --title \\\"My Site\\\" --out .\"\n\n}\n\n}\n\n### Eleventy / Hugo / Jekyll\n\n[Section titled “Eleventy / Hugo / Jekyll”](#eleventy--hugo--jekyll)\n\npackage.json\n\n{\n\n\"scripts\": {\n\n\"build\": \"eleventy\",\n\n\"postbuild\": \"aeo.js generate --url https://mysite.com --title \\\"My Site\\\" --out _site\"\n\n}\n\n}\n\nFor Hugo use --out public; for Jekyll --out _site. The postbuild script runs automatically after npm run build.\n\n### Markdown blog (no framework)\n\n[Section titled “Markdown blog (no framework)”](#markdown-blog-no-framework)\n\nThe CLI’s --out flag covers built HTML; to also pull .md front-matter and bodies from a contentDir, use the programmatic API:\n\nscripts/aeo.mjs\n\nimport { generateAEOFiles, resolveConfig } from 'aeo.js';\n\nawait generateAEOFiles(resolveConfig({\n\ntitle: 'My Blog',\n\nurl: 'https://myblog.dev',\n\ncontentDir: 'content', // pull post bodies from here\n\noutDir: 'public', // write generated files here\n\n}));\n\npackage.json\n\n{\n\n\"scripts\": {\n\n\"build:aeo\": \"node scripts/aeo.mjs\"\n\n}\n\n}\n\n## Adding the Widget\n\n[Section titled “Adding the Widget”](#adding-the-widget)\n\n&#x3C;script type=\"module\">\n\nimport { AeoWidget } from 'https://esm.sh/aeo.js/widget';\n\nnew AeoWidget({\n\nconfig: {\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\nwidget: { enabled: true, position: 'bottom-right', size: 'small' },\n\n},\n\n});\n\n&#x3C;/script>\n\nOr install and bundle locally with import { AeoWidget } from 'aeo.js/widget'.\n\n## CI Integration\n\n[Section titled “CI Integration”](#ci-integration)\n\n- run: npx aeo.js check --json | tee audit.json\n\n- run: |\n\nSCORE=$(jq '.audit.score' audit.json)\n\n[\"$SCORE\" -ge 70] || { echo \"GEO score $SCORE below 70\"; exit 1; }\n\nNote\n\nFull walkthrough with deployment recipes (Vercel, Netlify, Cloudflare, GitHub Pages) is in the [Vanilla Guide on GitHub](https://github.com/multivmlabs/aeo.js/blob/main/docs/vanilla.md).\n\n## Further Reading\n\n[Section titled “Further Reading”](#further-reading)",
      "description": "Use aeo.js with a plain HTML site, hand-rolled JS, or any static-site generator — no framework required.",
      "keywords": [
        "site",
        "https",
        "json",
        "html",
        "section",
        "titled",
        "title",
        "pages",
        "from",
        "mysite"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 3,
        "sourcePath": "/frameworks/vanilla"
      }
    },
    {
      "id": "bc43df2fd0afba97",
      "url": "https://aeojs.org/features/widget",
      "title": "Human/AI Widget (Part 2)",
      "content": "## Configuration\n\n[Section titled “Configuration”](#configuration)\n\nwidget: {\n\nenabled: true,\n\nposition: 'bottom-right', // 'bottom-left' | 'top-right' | 'top-left'\n\nsize: 'default', // 'small' | 'icon-only'\n\nhumanLabel: 'Human',\n\naiLabel: 'AI',\n\nshowBadge: true,\n\ntheme: {\n\nbackground: 'rgba(18, 18, 24, 0.9)',\n\ntext: '#C0C0C5',\n\naccent: '#E8E8EA',\n\nbadge: '#4ADE80',\n\n},\n\n}\n\n## Size variants\n\n[Section titled “Size variants”](#size-variants)\n\nDefault\n\nSmall\n\nIcon\n\nsize: 'default'\n\nsize: 'small'\n\nsize: 'icon-only'\n\nFull labels with icons\n\nCompact — ~30% smaller\n\nJust icons, no labels\n\nTip\n\nSet widget.enabled: false to disable the widget entirely while still generating AEO files.\n\n[Previous\nGenerated Files](/features/generated-files/) [Next\nCLI](/features/cli/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "The drop-in toggle that shows how AI sees your pages.",
      "keywords": [
        "widget",
        "react",
        "section",
        "titled",
        "size",
        "https",
        "import",
        "from",
        "framework",
        "manual"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "/features/widget"
      }
    },
    {
      "id": "bd4f27007c409577",
      "url": "https://aeojs.org/reference/api",
      "title": "API Reference (Part 1)",
      "content": "## API Reference\n\n## Core\n\n[Section titled “Core”](#core)\n\n### defineConfig(config)\n\n[Section titled “defineConfig(config)”](#defineconfigconfig)\n\nType-safe configuration helper:\n\nimport { defineConfig } from 'aeo.js';\n\nexport default defineConfig({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\n});\n\n**\n\n### generateAll(config)\n\n[Section titled “generateAll(config)”](#generateallconfig)\n\nGenerate all AEO files programmatically:\n\nimport { generateAll } from 'aeo.js';\n\nawait generateAll({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\noutDir: 'dist',\n\n});\n\n### resolveConfig(config)\n\n[Section titled “resolveConfig(config)”](#resolveconfigconfig)\n\nResolve a partial config into a fully resolved config with defaults:\n\nimport { resolveConfig } from 'aeo.js';\n\nconst resolved = resolveConfig({ title: 'My Site' });\n\n// All fields now have defaults\n\nThe examples below use resolvedConfig for a config object returned by resolveConfig.\n\n### validateConfig(config)\n\n[Section titled “validateConfig(config)”](#validateconfigconfig)\n\nValidate a config object and return any errors:\n\nimport { validateConfig } from 'aeo.js';\n\nconst errors = validateConfig(config);\n\n### detectFramework()\n\n[Section titled “detectFramework()”](#detectframework)\n\nAuto-detect the framework used in the current project:\n\nimport { detectFramework } from 'aeo.js';\n\nconst info = detectFramework();\n\n// { framework: 'next', contentDir: 'pages', outDir: '.next' }\n\n## HTML Extraction\n\n[Section titled “HTML Extraction”](#html-extraction)\n\n### htmlToMarkdown(html, pagePath, config)\n\n[Section titled “htmlToMarkdown(html, pagePath, config)”](#htmltomarkdownhtml-pagepath-config)\n\nConvert HTML to clean markdown:\n\nimport { htmlToMarkdown } from 'aeo.js';\n\nconst md = htmlToMarkdown(\n\n'&#x3C;html>&#x3C;head>&#x3C;title>Hello&#x3C;/title>&#x3C;/head>&#x3C;body>&#x3C;main>&#x3C;p>World&#x3C;/p>&#x3C;/main>&#x3C;/body>&#x3C;/html>',\n\n'/',\n\n{ url: 'https://mysite.com' }\n\n);\n\n// Returns a markdown document with YAML frontmatter",
      "description": "Programmatic API for aeo.js.",
      "keywords": [
        "config",
        "section",
        "titled",
        "from",
        "html",
        "const",
        "import",
        "title",
        "citability",
        "site"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 4,
        "sourcePath": "/reference/api"
      }
    },
    {
      "id": "be1c966e1e727e67",
      "url": "https://aeojs.org/getting-started/introduction",
      "title": "Introduction (Part 1)",
      "content": "## Introduction\n\n## What is Answer Engine Optimization?\n\n[Section titled “What is Answer Engine Optimization?”](#what-is-answer-engine-optimization)\n\nAnswer Engine Optimization (AEO) is the practice of making your website discoverable and citable by AI-powered answer engines like **ChatGPT**, **Claude**, **Perplexity**, and **SearchGPT**.\n\nUnlike 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.\n\n## Why aeo.js?\n\n[Section titled “Why aeo.js?”](#why-aeojs)\n\nAI crawlers and LLMs look for specific files and formats that most websites don’t provide:\n\n- **llms.txt** — A concise summary of your site written for LLMs\n\n- **llms-full.txt** — Full content concatenated for deep ingestion\n\n- **ai-index.json** — Structured content optimized for RAG pipelines\n\n- **docs.json** — Documentation manifest for content discovery\n\n- **Raw Markdown** — Per-page .md files for clean content extraction\n\n**aeo.js** generates all of these automatically from your existing pages — no manual work required.\n\n## How it works\n\n[Section titled “How it works”](#how-it-works)\n\n- **Install** the package and add the plugin for your framework\n\n- **Build** your site as usual\n\n- **aeo.js** scans your output, extracts content, and generates all AEO files\n\n- The optional **widget** lets visitors toggle between human and AI views of your pages\n\n## Scope: what aeo.js does and doesn’t influence\n\n[Section titled “Scope: what aeo.js does and doesn’t influence”](#scope-what-aeojs-does-and-doesnt-influence)\n\nAEO 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:\n\nWhat aeo.js does well\n\nImproves machine-readable access to **your own site**:\n\n- generates llms.txt, llms-full.txt, ai-index.json, raw markdown copies, JSON-LD schema, and a sitemap",
      "description": "What is aeo.js and why you need Answer Engine Optimization.",
      "keywords": [
        "your",
        "what",
        "content",
        "llms",
        "site",
        "answer",
        "engine",
        "section",
        "titled",
        "full"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "/getting-started/introduction"
      }
    },
    {
      "id": "c1975395f1ee2f73",
      "url": "https://aeojs.org/frameworks/vanilla",
      "title": "Vanilla JS / Static HTML (Part 3)",
      "content": "[CLI Reference](/features/cli/) — every command, every flag\n\n- [JSON-LD Recipes](/features/json-ld/) — FAQ, HowTo, Product, Article, Recipe, Event\n\n- [Configuration Reference](/reference/configuration/)\n\n[Previous\nWebpack](/frameworks/webpack/) [Next\nGenerated Files](/features/generated-files/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Use aeo.js with a plain HTML site, hand-rolled JS, or any static-site generator — no framework required.",
      "keywords": [
        "site",
        "https",
        "json",
        "html",
        "section",
        "titled",
        "title",
        "pages",
        "from",
        "mysite"
      ],
      "metadata": {
        "chunkIndex": 2,
        "totalChunks": 3,
        "sourcePath": "/frameworks/vanilla"
      }
    },
    {
      "id": "c508db81362df17c",
      "url": "https://aeojs.org/features/widget",
      "title": "Human/AI Widget (Part 1)",
      "content": "## Human/AI Widget\n\nThe Human/AI widget is a floating toggle that lets visitors switch between the normal page and its AI-readable markdown version.\n\n## How it works\n\n[Section titled “How it works”](#how-it-works)\n\nWhen a visitor clicks **AI**, the widget:\n\n- Fetches the .md file for the current page\n\n- Falls back to extracting markdown from the live DOM if no .md exists\n\n- Displays the markdown in a slide-out panel\n\n- Offers copy-to-clipboard and download actions\n\n## Automatic injection\n\n[Section titled “Automatic injection”](#automatic-injection)\n\nFramework plugins (Astro, Vite, Nuxt, Angular) inject the widget automatically. No extra code needed.\n\n## Manual setup (Next.js / React)\n\n[Section titled “Manual setup (Next.js / React)”](#manual-setup-nextjs--react)\n\nFor Next.js or other manual setups, create a client component:\n\n'use client';\n\nimport { useEffect } from 'react';\n\nexport function AeoWidgetLoader() {\n\nuseEffect(() => {\n\nimport('aeo.js/widget').then(({ AeoWidget }) => {\n\nnew AeoWidget({\n\nconfig: {\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\nwidget: { enabled: true, position: 'bottom-right' },\n\n},\n\n});\n\n});\n\n}, []);\n\nreturn null;\n\n}\n\n{ import(&#x27;aeo.js/widget&#x27;).then(({ AeoWidget }) => { new AeoWidget({ config: { title: &#x27;My Site&#x27;, url: &#x27;https://mysite.com&#x27;, widget: { enabled: true, position: &#x27;bottom-right&#x27; }, }, }); }); }, []); return null;}\">\n\n## Framework components\n\n[Section titled “Framework components”](#framework-components)\n\naeo.js ships React, Vue, and Svelte wrapper components:\n\n### React\n\n[Section titled “React”](#react)\n\nimport { AeoReactWidget } from 'aeo.js/react';\n\n&#x3C;AeoReactWidget config={{ title: 'My Site', url: 'https://mysite.com' }} />\n\n\">\n\n### Vue\n\n[Section titled “Vue”](#vue)\n\n&#x3C;script setup>\n\nimport { AeoVueWidget } from 'aeo.js/vue';\n\n&#x3C;/script>\n\n&#x3C;template>\n\n&#x3C;AeoVueWidget :config=\"{ title: 'My Site', url: 'https://mysite.com' }\" />\n\n&#x3C;/template>\n\n \">",
      "description": "The drop-in toggle that shows how AI sees your pages.",
      "keywords": [
        "widget",
        "react",
        "section",
        "titled",
        "size",
        "https",
        "import",
        "from",
        "framework",
        "manual"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "/features/widget"
      }
    },
    {
      "id": "c524d046ae5f4534",
      "url": "https://aeojs.org/docs/features/generated-files",
      "title": "Generated Files (Part 2)",
      "content": "```js\n{\n  generators: {\n    robotsTxt: true,\n    llmsTxt: true,\n    llmsFullTxt: true,\n    rawMarkdown: true,\n    manifest: true,\n    sitemap: true,\n    aiIndex: true,\n    schema: true,\n  }\n}\n```",
      "description": "All the files aeo.js generates and what they're for.",
      "keywords": [
        "true",
        "site",
        "https",
        "mysite",
        "content",
        "your",
        "about",
        "index",
        "markdown",
        "blog"
      ],
      "metadata": {
        "title": "Generated Files",
        "description": "All the files aeo.js generates and what they're for.",
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "docs/features/generated-files.mdx"
      }
    },
    {
      "id": "c80598e3c61480b2",
      "url": "https://aeojs.org/docs/frameworks/vanilla",
      "title": "Vanilla JS / Static HTML (Part 1)",
      "content": "import { Tabs, TabItem, Aside } from '@astrojs/starlight/components';\n\naeo.js works on any project that produces static HTML. Use the CLI directly — no plugin, no module, no framework.\n\n## Quick Start\n\n<Tabs>\n  <TabItem label=\"Zero-install (npx)\">\n    ```bash\n    npx aeo.js generate --url https://mysite.com --title \"My Site\" --out public\n    ```\n  </TabItem>\n  <TabItem label=\"Installed\">\n    ```bash\n    npm install --save-dev aeo.js\n    npx aeo.js generate --url https://mysite.com --title \"My Site\" --out public\n    ```\n  </TabItem>\n</Tabs>\n\n`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.\n\n<Aside type=\"caution\">\nThe 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`.\n</Aside>\n\n## How aeo.js Discovers Your Pages\n\n| Source | How to set | Use when |\n|---|---|---|\n| **Built HTML in `outDir`** | `--out public` (CLI) | You have a built static site with `*.html` files |\n| **`contentDir`** | programmatic only — see below | You have handwritten `.md` / `.mdx` files |\n| **`pages` array** | programmatic only — see below | Explicit control for runtime-only routes |\n\nThe CLI exposes `--out` for `outDir`. For the richer options (`contentDir`, `pages`), call the package's API directly:\n\n```js\n// scripts/aeo.mjs\nimport { generateAEOFiles, resolveConfig } from 'aeo.js';\n\nawait generateAEOFiles(resolveConfig({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  contentDir: 'content',\n  outDir: 'public',\n  pages: [{ pathname: '/', title: 'Home' }],\n}));\n```\n\n## Common Setups\n\n### Hand-rolled HTML site",
      "description": "Use aeo.js with a plain HTML site, hand-rolled JS, or any static-site generator — no framework required.",
      "keywords": [
        "site",
        "json",
        "https",
        "title",
        "from",
        "html",
        "mysite",
        "public",
        "contentdir",
        "pages"
      ],
      "metadata": {
        "title": "Vanilla JS / Static HTML",
        "description": "Use aeo.js with a plain HTML site, hand-rolled JS, or any static-site generator — no framework required.",
        "chunkIndex": 0,
        "totalChunks": 3,
        "sourcePath": "docs/frameworks/vanilla.mdx"
      }
    },
    {
      "id": "c9965c40e44472a1",
      "url": "https://aeojs.org/docs/features/audit",
      "title": "Audit & Citability (Part 1)",
      "content": "## Site Audit\n\nThe `auditSite` function checks your site for AEO best practices and returns a detailed report:\n\n```ts\nimport { auditSite, formatAuditReport, getGrade, resolveConfig } from 'aeo.js';\n\nconst config = resolveConfig({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  pages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],\n});\n\nconst result = auditSite(config);\n\nconsole.log(formatAuditReport(result));\nconsole.log('Grade:', getGrade(result.score));\n```\n\nThe audit checks for:\n\n- Presence of `robots.txt`, `llms.txt`, `llms-full.txt`\n- Sitemap accessibility\n- Structured data (JSON-LD)\n- Open Graph meta tags\n- AI crawler accessibility\n\nYou can also run it from the CLI:\n\n```bash\nnpx aeo.js check\n```\n\n## Citability Score\n\nMeasure how likely AI engines are to cite your content:\n\n```ts\nimport { formatPageCitability, resolveConfig, scorePageCitability, scoreSiteCitability } from 'aeo.js';\n\n// Score a single page\nconst pageScore = scorePageCitability({\n  pathname: '/',\n  title: 'Home',\n  content: '# Home\\n\\nMy site publishes practical guides for AI-ready content.',\n});\nconsole.log(formatPageCitability(pageScore));\n\n// Score the whole site\nconst config = resolveConfig({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  pages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],\n});\n\nconst siteScore = scoreSiteCitability(config);\n```\n\nThe citability score evaluates:\n\n- Content structure and headings\n- Factual density and specificity\n- Source attribution\n- Unique data and statistics\n- Clear definitions and explanations\n\n## Reports\n\nGenerate a comprehensive AEO report:\n\n```ts\nimport { formatReportJson, formatReportMarkdown, generateReport, resolveConfig } from 'aeo.js';\n\nconst config = resolveConfig({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  pages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],\n});\n\nconst report = generateReport(config);\n\n// Get as markdown\nconsole.log(formatReportMarkdown(report));",
      "description": "Audit your AEO setup and measure your site's citability score.",
      "keywords": [
        "site",
        "const",
        "config",
        "title",
        "resolveconfig",
        "content",
        "home",
        "auditsite",
        "report",
        "from"
      ],
      "metadata": {
        "title": "Audit & Citability",
        "description": "Audit your AEO setup and measure your site's citability score.",
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "docs/features/audit.mdx"
      }
    },
    {
      "id": "ceb04bed927b6b30",
      "url": "https://aeojs.org/frameworks/nuxt",
      "title": "Nuxt",
      "content": "## Nuxt\n\n## Setup\n\n[Section titled “Setup”](#setup)\n\n-\nInstall the package:\n\nTerminal window\n\nnpm install aeo.js\n\n-\nAdd the module to your Nuxt config:\n\nnuxt.config.ts\n\nexport default defineNuxtConfig({\n\nmodules: ['aeo.js/nuxt'],\n\naeo: {\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n},\n\n});\n\n## How it works\n\n[Section titled “How it works”](#how-it-works)\n\nThe Nuxt module:\n\n- Scans your pages/ directory for routes\n\n- Generates AEO files during dev and production builds\n\n- Scans pre-rendered HTML from .output/public/ for full page content\n\n- Injects the widget as a client-side Nuxt plugin\n\n- Adds &#x3C;link> and &#x3C;meta> tags for AEO discoverability\n\n## Configuration\n\n[Section titled “Configuration”](#configuration)\n\nPass any [AeoConfig](/reference/configuration/) options in the aeo key:\n\nexport default defineNuxtConfig({\n\nmodules: ['aeo.js/nuxt'],\n\naeo: {\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\ngenerators: {\n\nrobotsTxt: true,\n\nllmsTxt: true,\n\nrawMarkdown: true,\n\n},\n\nwidget: {\n\nenabled: true,\n\nposition: 'bottom-left',\n\n},\n\n},\n\n});\n\n[Previous\nVite](/frameworks/vite/) [Next\nAngular](/frameworks/angular/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Use aeo.js with Nuxt 3.",
      "keywords": [
        "nuxt",
        "https",
        "configuration",
        "true",
        "setup",
        "section",
        "titled",
        "site",
        "works",
        "install"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "/frameworks/nuxt"
      }
    },
    {
      "id": "d1fd87fbffe3e933",
      "url": "https://aeojs.org/features/json-ld",
      "title": "JSON-LD Recipes (Part 3)",
      "content": "{ '@type': 'ListItem', position: 3, name: 'Article Title' },],\n\n};\n\n## Injecting safely — per framework\n\n[Section titled “Injecting safely — per framework”](#injecting-safely--per-framework)\n\n[Next.js](#tab-panel-0)\n- [Astro](#tab-panel-1)\n- [Nuxt](#tab-panel-2)\n- [Svelte](#tab-panel-3)\n\nimport { serializeJsonForHtml } from '@/lib/serialize-json-ld';\n\n&#x3C;script\n\ntype=\"application/ld+json\"\n\ndangerouslySetInnerHTML={{ __html: serializeJsonForHtml(faqSchema) }}\n\n/>\n\n&#x3C;script lang=\"ts\">\n\nimport { serializeJsonForHtml } from './lib/serialize-json-ld';\n\nconst schema = serializeJsonForHtml(faqSchema);\n\n&#x3C;/script>\n\n&#x3C;svelte:head>\n\n&#x3C;script type=\"application/ld+json\">{@html schema}&#x3C;/script>\n\n&#x3C;/svelte:head>\n\n \">\n\n## Validation\n\n[Section titled “Validation”](#validation)\n\nAfter deploying, paste your URL into one of these:\n\n- [Schema Markup Validator](https://validator.schema.org/) — official, quickest\n\n- [Google Rich Results Test](https://search.google.com/test/rich-results) — Google rich-result eligibility\n\n- [Bing Webmaster URL Inspection](https://www.bing.com/webmasters/url-inspection) — Bing/Copilot-specific feedback\n\nNote\n\nFull catalog (including Recipe**, **Event**, **VideoObject**, and more per-framework injection variants like React Helmet and vanilla HTML) is in [docs/json-ld.md on GitHub](https://github.com/multivmlabs/aeo.js/blob/main/docs/json-ld.md).\n\n[Previous\nSchema & Open Graph](/features/schema-og/) [Next\nAudit & Citability](/features/audit/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Copy-paste structured-data recipes for FAQ, HowTo, Product, Article, Recipe, Event, VideoObject, and BreadcrumbList — each paired with an XSS-safe serializer.",
      "keywords": [
        "type",
        "https",
        "schema",
        "json",
        "name",
        "section",
        "titled",
        "script",
        "replace",
        "const"
      ],
      "metadata": {
        "chunkIndex": 2,
        "totalChunks": 3,
        "sourcePath": "/features/json-ld"
      }
    },
    {
      "id": "d22f5b66eddeeca5",
      "url": "https://aeojs.org",
      "title": "aeo.js — Answer Engine Optimization for the Modern Web (Part 2)",
      "content": "\"postbuild\": \"node -e \\\"import('aeo.js/next').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\\\"\"\n\n}\n\n}\n\nm.postBuild({ title: &#x27;My Site&#x27;, url: &#x27;https://mysite.com&#x27; }))\\&#x22;&#x22; }}\">\n\nvite.config.ts\n\nimport { defineConfig } from 'vite';\n\nimport { aeoVitePlugin } from 'aeo.js/vite';\n\nexport default defineConfig({\n\nplugins: [aeoVitePlugin({\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n}),],\n\n});\n\nnuxt.config.ts\n\nexport default defineNuxtConfig({\n\nmodules: ['aeo.js/nuxt'],\n\naeo: {\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n},\n\n});\n\nAdd a post-build step to package.json:\n\n{\n\n\"scripts\": {\n\n\"postbuild\": \"node -e \\\"import('aeo.js/angular').then(m => m.postBuild({ title: 'My App', url: 'https://myapp.com' }))\\\"\"\n\n}\n\n}\n\nm.postBuild({ title: &#x27;My App&#x27;, url: &#x27;https://myapp.com&#x27; }))\\&#x22;&#x22; }}\">\n\nOr generate programmatically:\n\nimport { generate } from 'aeo.js/angular';\n\nawait generate({ title: 'My App', url: 'https://myapp.com' });\n\nwebpack.config.js\n\nconst { AeoWebpackPlugin } = require('aeo.js/webpack');\n\nmodule.exports = {\n\nplugins: [new AeoWebpackPlugin({\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n}),],\n\n};\n\nNo framework needed — run standalone:\n\nTerminal window\n\n# Generate all AEO files\n\nnpx aeo.js generate --url https://mysite.com --title \"My Site\"\n\n# Scaffold a config file\n\nnpx aeo.js init\n\n# Check your setup\n\nnpx aeo.js check\n\n## What is AEO?\n\n[Section titled “What is AEO?”](#what-is-aeo)\n\nAnswer Engine Optimization (AEO) is the practice of making your website discoverable and citable by AI-powered answer engines like ChatGPT, Claude, Perplexity, and SearchGPT.",
      "description": "Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.",
      "keywords": [
        "https",
        "site",
        "title",
        "mysite",
        "import",
        "config",
        "widget",
        "true",
        "from",
        "files"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 4,
        "sourcePath": "/"
      }
    },
    {
      "id": "d586bea441969721",
      "url": "https://aeojs.org/docs/getting-started/quick-start",
      "title": "Quick Start (Part 1)",
      "content": "import { Tabs, TabItem, Steps } from '@astrojs/starlight/components';\n\nThe fastest way to add AEO to your site depends on your framework.\n\n## Astro\n\n<Steps>\n1. Install the package:\n   ```bash\n   npm install aeo.js\n   ```\n\n2. Add the integration to your Astro config:\n   ```js\n   // astro.config.mjs\n   import { defineConfig } from 'astro/config';\n   import { aeoAstroIntegration } from 'aeo.js/astro';\n\n   export default defineConfig({\n     site: 'https://mysite.com',\n     integrations: [\n       aeoAstroIntegration({\n         title: 'My Site',\n         description: 'A site optimized for AI discovery',\n         url: 'https://mysite.com',\n       }),\n     ],\n   });\n   ```\n\n3. Build your site — all AEO files are generated automatically.\n</Steps>\n\n## Next.js\n\n<Steps>\n1. Install the package:\n   ```bash\n   npm install aeo.js\n   ```\n\n2. Wrap your Next.js config:\n   ```js\n   // next.config.mjs\n   import { withAeo } from 'aeo.js/next';\n\n   export default withAeo({\n     aeo: {\n       title: 'My Site',\n       description: 'A site optimized for AI discovery',\n       url: 'https://mysite.com',\n     },\n   });\n   ```\n\n3. Add the post-build step to `package.json`:\n   ```json\n   {\n     \"scripts\": {\n       \"postbuild\": \"node -e \\\"import('aeo.js/next').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\\\"\"\n     }\n   }\n   ```\n</Steps>\n\n## Vite\n\n<Steps>\n1. Install the package:\n   ```bash\n   npm install aeo.js\n   ```\n\n2. Add the plugin to your Vite config:\n   ```js\n   // vite.config.ts\n   import { defineConfig } from 'vite';\n   import { aeoVitePlugin } from 'aeo.js/vite';\n\n   export default defineConfig({\n     plugins: [\n       aeoVitePlugin({\n         title: 'My Site',\n         description: 'A site optimized for AI discovery',\n         url: 'https://mysite.com',\n       }),\n     ],\n   });\n   ```\n</Steps>\n\n## CLI (any site)\n\nNo framework integration needed:\n\n```bash\nnpx aeo.js generate --url https://mysite.com --title \"My Site\"\n```",
      "description": "Get aeo.js running in under 2 minutes.",
      "keywords": [
        "site",
        "import",
        "steps",
        "config",
        "from",
        "your",
        "install",
        "https",
        "mysite",
        "astro"
      ],
      "metadata": {
        "title": "Quick Start",
        "description": "Get aeo.js running in under 2 minutes.",
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "docs/getting-started/quick-start.mdx"
      }
    },
    {
      "id": "d94439cad79b4098",
      "url": "https://aeojs.org/docs/getting-started/introduction",
      "title": "Introduction (Part 2)",
      "content": "<Aside type=\"caution\" title=\"What aeo.js cannot influence\">\nOff-site signals that AI engines also weigh:\n\n- **third-party mentions and reviews** of your product across the web\n- **inbound links** and how reputable the linking domains are\n- **community discussions** (Reddit, Hacker News, X, niche forums) and how often you're cited there\n- **model training data** — what an LLM \"already knows\" about you from its pre-training cutoff\n- **freshness signals** outside your control (independent news, blog roundups, podcasts)\n</Aside>\n\nThink 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.\n\n## Supported Frameworks\n\n| Framework | Import |\n|-----------|--------|\n| Astro | `aeo.js/astro` |\n| Next.js | `aeo.js/next` |\n| Vite (React, Vue, Svelte) | `aeo.js/vite` |\n| Nuxt | `aeo.js/nuxt` |\n| Angular | `aeo.js/angular` |\n| Webpack | `aeo.js/webpack` |\n| Any (CLI) | `npx aeo.js generate` |",
      "description": "What is aeo.js and why you need Answer Engine Optimization.",
      "keywords": [
        "your",
        "content",
        "llms",
        "site",
        "aside",
        "what",
        "full",
        "json",
        "from",
        "answer"
      ],
      "metadata": {
        "title": "Introduction",
        "description": "What is aeo.js and why you need Answer Engine Optimization.",
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "docs/getting-started/introduction.mdx"
      }
    },
    {
      "id": "d95f8907004121f9",
      "url": "https://aeojs.org/frameworks/webpack",
      "title": "Webpack",
      "content": "## Webpack\n\n## Setup\n\n[Section titled “Setup”](#setup)\n\n-\nInstall the package:\n\nTerminal window\n\nnpm install aeo.js\n\n-\nAdd the plugin to your Webpack config:\n\nwebpack.config.js\n\nconst { AeoWebpackPlugin } = require('aeo.js/webpack');\n\nmodule.exports = {\n\nplugins: [new AeoWebpackPlugin({\n\ntitle: 'My Site',\n\ndescription: 'A site optimized for AI discovery',\n\nurl: 'https://mysite.com',\n\n}),],\n\n};\n\n## How it works\n\n[Section titled “How it works”](#how-it-works)\n\nThe Webpack plugin:\n\n- Runs during the emit phase of the Webpack compilation\n\n- Generates all AEO files in your output directory\n\n- Injects the widget into your HTML entry point\n\n## Configuration\n\n[Section titled “Configuration”](#configuration)\n\nPass any [AeoConfig](/reference/configuration/) options to the plugin:\n\nnew AeoWebpackPlugin({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\nwidget: {\n\nenabled: true,\n\nposition: 'bottom-right',\n\n},\n\n});\n\n[Previous\nAngular](/frameworks/angular/) [Next\nVanilla JS / Static HTML](/frameworks/vanilla/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Use aeo.js with Webpack.",
      "keywords": [
        "webpack",
        "https",
        "configuration",
        "setup",
        "section",
        "titled",
        "plugin",
        "your",
        "aeowebpackplugin",
        "site"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "/frameworks/webpack"
      }
    },
    {
      "id": "dfd49959f70f08f2",
      "url": "https://aeojs.org/features/schema-og",
      "title": "Schema & Open Graph (Part 1)",
      "content": "## Schema & Open Graph\n\naeo.js can generate JSON-LD structured data and Open Graph meta tags for your pages.\n\n## JSON-LD Schema\n\n[Section titled “JSON-LD Schema”](#json-ld-schema)\n\nEnable schema generation in your config:\n\n-\n\n{\n\nschema: {\n\nenabled: true,\n\norganization: {\n\nname: 'My Company',\n\nurl: 'https://mysite.com',\n\nlogo: 'https://mysite.com/logo.png',\n\nsameAs: ['https://twitter.com/mycompany',\n\n'https://github.com/mycompany',],\n\n},\n\ndefaultType: 'WebPage', // or 'Article'\n\n},\n\n}\n\n**\n\nThis generates &#x3C;script type=\"application/ld+json\"> blocks with:\n\nOrganization** schema for your site\n\n- **WebPage** or **Article** schema for each page\n\n- Proper @context, @type, name, description, and url fields\n\n## Open Graph tags\n\n[Section titled “Open Graph tags”](#open-graph-tags)\n\nEnable OG tag generation:\n\n{\n\nog: {\n\nenabled: true,\n\nimage: 'https://mysite.com/og.png',\n\ntwitterHandle: '@mycompany',\n\ntype: 'website', // or 'article'\n\n},\n\n}\n\nThis generates meta tags like:\n\n&#x3C;meta property=\"og:title\" content=\"Page Title\" />\n\n&#x3C;meta property=\"og:description\" content=\"Page description\" />\n\n&#x3C;meta property=\"og:image\" content=\"https://mysite.com/og.png\" />\n\n&#x3C;meta property=\"og:url\" content=\"https://mysite.com/page\" />\n\n&#x3C;meta name=\"twitter:card\" content=\"summary_large_image\" />\n\n&#x3C;meta name=\"twitter:site\" content=\"@mycompany\" />\n\n\">\n\n## Programmatic API\n\n[Section titled “Programmatic API”](#programmatic-api)\n\nThe lower-level helpers expect a resolved config and a page entry.\n\nimport {\n\ngenerateJsonLdScript,\n\ngenerateOGTags,\n\ngenerateOGTagsHtml,\n\ngenerateSchemaObjects,\n\nresolveConfig,\n\n} from 'aeo.js';\n\nconst page = {\n\npathname: '/page',\n\ntitle: 'Page Title',\n\ndescription: 'Page description',\n\ncontent: 'Page content',\n\n};\n\nconst resolvedConfig = resolveConfig({\n\ntitle: 'My Company',\n\ndescription: 'My company website',\n\nurl: 'https://mysite.com',\n\npages: [page],\n\n});\n\n// Get schema objects\n\nconst schemas = generateSchemaObjects(resolvedConfig);",
      "description": "Auto-generated JSON-LD structured data and Open Graph meta tags.",
      "keywords": [
        "page",
        "meta",
        "schema",
        "https",
        "tags",
        "const",
        "content",
        "json",
        "mysite",
        "description"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "/features/schema-og"
      }
    },
    {
      "id": "e3559a15f546c191",
      "url": "https://aeojs.org/reference/api",
      "title": "API Reference (Part 2)",
      "content": "Hello\nWorld\n\n&#x27;, &#x27;/&#x27;, { url: &#x27;https://mysite.com&#x27; });// Returns a markdown document with YAML frontmatter\">\n\n### extractTextFromHtml(html)\n\n[Section titled “extractTextFromHtml(html)”](#extracttextfromhtmlhtml)\n\nExtract plain text from HTML:\n\nimport { extractTextFromHtml } from 'aeo.js';\n\nconst text = extractTextFromHtml('&#x3C;p>Hello &#x3C;strong>world&#x3C;/strong>&#x3C;/p>');\n\nworld**\n\n&#x27;);\">\n\n### extractTitle(html) / extractDescription(html)\n\n[Section titled “extractTitle(html) / extractDescription(html)”](#extracttitlehtml--extractdescriptionhtml)\n\nExtract the title or meta description from an HTML document.\n\n### extractJsonLd(html)\n\n[Section titled “extractJsonLd(html)”](#extractjsonldhtml)\n\nExtract JSON-LD structured data from an HTML document.\n\n## Schema\n\n[Section titled “Schema”](#schema)\n\n### generateSchemaObjects(config)\n\n[Section titled “generateSchemaObjects(config)”](#generateschemaobjectsconfig)\n\nGenerate JSON-LD schema objects:\n\nimport { generateSchemaObjects } from 'aeo.js';\n\nconst schemas = generateSchemaObjects(resolvedConfig);\n\n### generateJsonLdScript(schemas)\n\n[Section titled “generateJsonLdScript(schemas)”](#generatejsonldscriptschemas)\n\nGenerate a &#x3C;script type=\"application/ld+json\"> tag:\n\nimport { generateJsonLdScript, generateSiteSchemas } from 'aeo.js';\n\nconst schemas = generateSiteSchemas(resolvedConfig);\n\nconst script = generateJsonLdScript(schemas);\n\n### generateSiteSchemas(config) / generatePageSchemas(page, config)\n\n[Section titled “generateSiteSchemas(config) / generatePageSchemas(page, config)”](#generatesiteschemasconfig--generatepageschemaspage-config)\n\nGenerate schemas for the site or individual pages.\n\n## Open Graph\n\n[Section titled “Open Graph”](#open-graph)\n\n### generateOGTags(page, config)\n\n[Section titled “generateOGTags(page, config)”](#generateogtagspage-config)\n\nReturns an array of MetaTag objects:\n\nimport { generateOGTags } from 'aeo.js';\n\nconst tags = generateOGTags(",
      "description": "Programmatic API for aeo.js.",
      "keywords": [
        "config",
        "section",
        "titled",
        "from",
        "html",
        "const",
        "import",
        "title",
        "citability",
        "site"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 4,
        "sourcePath": "/reference/api"
      }
    },
    {
      "id": "e41aa69570e1a304",
      "url": "https://aeojs.org/docs/features/schema-og",
      "title": "Schema & Open Graph (Part 2)",
      "content": "// Get a <script> tag string\nconst script = generateJsonLdScript([\n  ...schemas.site,\n  ...(schemas.pages[page.pathname] ?? []),\n]);\n\n// Get OG meta tag objects\nconst tags = generateOGTags(page, resolvedConfig);\n\n// Get OG meta tags as HTML string\nconst html = generateOGTagsHtml(page, resolvedConfig);\n```\n\n<Aside type=\"tip\">\nSchema and OG generators work independently — you can enable one without the other.\n</Aside>",
      "description": "Auto-generated JSON-LD structured data and Open Graph meta tags.",
      "keywords": [
        "page",
        "meta",
        "https",
        "content",
        "schema",
        "mysite",
        "description",
        "const",
        "tags",
        "title"
      ],
      "metadata": {
        "title": "Schema & Open Graph",
        "description": "Auto-generated JSON-LD structured data and Open Graph meta tags.",
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "docs/features/schema-og.mdx"
      }
    },
    {
      "id": "e461e98ff44ddf2a",
      "url": "https://aeojs.org/docs/features/generated-files",
      "title": "Generated Files (Part 1)",
      "content": "After building, aeo.js generates these files in your output directory:\n\n## robots.txt\n\nAI-crawler-aware robots directives. Includes rules for all known AI crawlers (GPTBot, ClaudeBot, PerplexityBot, etc.) with sensible defaults.\n\n```txt\nUser-agent: *\nAllow: /\n\nUser-agent: GPTBot\nAllow: /\n\nUser-agent: ClaudeBot\nAllow: /\n```\n\n## llms.txt\n\nA concise, LLM-readable summary of your site. This is the first file AI crawlers look for — it tells them what your site is about and where to find content.\n\n```txt\n# My Site\n\nA site optimized for AI discovery\n\n## Pages\n\n- [Home](https://mysite.com/)\n- [About](https://mysite.com/about)\n- [Blog](https://mysite.com/blog)\n```\n\n## llms-full.txt\n\nFull concatenated content of all pages in a single file. Useful for LLMs that want to ingest your entire site at once.\n\n## sitemap.xml\n\nStandard XML sitemap for search engines and AI crawlers.\n\n## docs.json\n\nA structured documentation manifest:\n\n```json\n{\n  \"name\": \"My Site\",\n  \"description\": \"A site optimized for AI discovery\",\n  \"baseUrl\": \"https://mysite.com\",\n  \"totalDocs\": 5,\n  \"docs\": [\n    {\n      \"title\": \"Home\",\n      \"path\": \"/\",\n      \"markdownUrl\": \"https://mysite.com/index.md\",\n      \"htmlUrl\": \"https://mysite.com/\",\n      \"content\": \"...\"\n    }\n  ]\n}\n```\n\n## ai-index.json\n\nAn AI-optimized content index designed for RAG (Retrieval-Augmented Generation) pipelines:\n\n```json\n[\n  {\n    \"id\": \"index\",\n    \"url\": \"https://mysite.com/\",\n    \"title\": \"Home\",\n    \"content\": \"Full page content in markdown...\",\n    \"description\": \"Page description\",\n    \"keywords\": [\"keyword1\", \"keyword2\"]\n  }\n]\n```\n\n## Raw Markdown\n\nOne `.md` file per page, extracted from your rendered HTML:\n\n```\npublic/\n  index.md     # Markdown for /\n  about.md     # Markdown for /about\n  blog.md      # Markdown for /blog\n```\n\n## Toggling generators\n\nYou can enable or disable individual generators:",
      "description": "All the files aeo.js generates and what they're for.",
      "keywords": [
        "true",
        "site",
        "https",
        "mysite",
        "content",
        "your",
        "about",
        "index",
        "markdown",
        "blog"
      ],
      "metadata": {
        "title": "Generated Files",
        "description": "All the files aeo.js generates and what they're for.",
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "docs/features/generated-files.mdx"
      }
    },
    {
      "id": "e8b58693e44424e2",
      "url": "https://aeojs.org/docs/reference/api",
      "title": "API Reference (Part 2)",
      "content": "```ts\nimport { generateSchemaObjects } from 'aeo.js';\n\nconst schemas = generateSchemaObjects(resolvedConfig);\n```\n\n### `generateJsonLdScript(schemas)`\n\nGenerate a `<script type=\"application/ld+json\">` tag:\n\n```ts\nimport { generateJsonLdScript, generateSiteSchemas } from 'aeo.js';\n\nconst schemas = generateSiteSchemas(resolvedConfig);\nconst script = generateJsonLdScript(schemas);\n```\n\n### `generateSiteSchemas(config)` / `generatePageSchemas(page, config)`\n\nGenerate schemas for the site or individual pages.\n\n## Open Graph\n\n### `generateOGTags(page, config)`\n\nReturns an array of `MetaTag` objects:\n\n```ts\nimport { generateOGTags } from 'aeo.js';\n\nconst tags = generateOGTags(\n  { pathname: '/', title: 'Home' },\n  resolvedConfig\n);\n// [{ property: 'og:title', content: 'Home' }, ...]\n```\n\n### `generateOGTagsHtml(page, config)`\n\nReturns OG tags as an HTML string.\n\n## Audit\n\n### `auditSite(config)`\n\nAudit a site for AEO best practices:\n\n```ts\nimport { auditSite, formatAuditReport, getGrade, resolveConfig } from 'aeo.js';\n\nconst config = resolveConfig({\n  title: 'My Site',\n  url: 'https://mysite.com',\n  pages: [{ pathname: '/', title: 'Home', content: 'Welcome to my site.' }],\n});\n\nconst result = auditSite(config);\nconsole.log(formatAuditReport(result));\nconsole.log(getGrade(result.score)); // 'Excellent', 'Good', 'Fair', etc.\n```\n\n## Citability\n\n### `scorePageCitability(page)`\n\nScore how likely a page is to be cited by AI:\n\n```ts\nimport { scorePageCitability, formatPageCitability } from 'aeo.js';\n\nconst score = scorePageCitability({\n  pathname: '/',\n  title: 'Home',\n  content: '# Home\\n\\nMy site publishes practical guides for AI-ready content.',\n});\nconsole.log(formatPageCitability(score));\n```\n\n### `scoreSiteCitability(config)`\n\nScore citability across your entire site.\n\n## Reports\n\n### `generateReport(config)`\n\nGenerate a comprehensive AEO report:\n\n```ts\nimport { generateReport, formatReportMarkdown } from 'aeo.js';",
      "description": "Programmatic API for aeo.js.",
      "keywords": [
        "config",
        "from",
        "const",
        "import",
        "html",
        "title",
        "site",
        "resolvedconfig",
        "generate",
        "resolveconfig"
      ],
      "metadata": {
        "title": "API Reference",
        "description": "Programmatic API for aeo.js.",
        "chunkIndex": 1,
        "totalChunks": 3,
        "sourcePath": "docs/reference/api.mdx"
      }
    },
    {
      "id": "ed56d83d9dbbdae1",
      "url": "https://aeojs.org/features/cli",
      "title": "CLI (Part 2)",
      "content": "The standalone CLI does not** currently load aeo.config.{ts,js} — it configures itself from CLI flags + defaults only. npx aeo.js init still scaffolds the file as the canonical place for your settings, but today it’s consumed by framework integrations rather than the CLI itself.\n\nCreate one with npx aeo.js init:\n\nimport { defineConfig } from 'aeo.js';\n\nexport default defineConfig({\n\ntitle: 'My Site',\n\nurl: 'https://mysite.com',\n\ndescription: 'A site optimized for AI discovery',\n\noutDir: 'public',\n\n});\n\nImport it into your framework config so the integration picks it up:\n\nvite.config.ts\n\nimport aeoConfig from './aeo.config';\n\nimport { aeoVitePlugin } from 'aeo.js/vite';\n\nexport default { plugins: [aeoVitePlugin(aeoConfig)] };\n\nFor raw CLI usage on a static site, pass values directly:\n\nTerminal window\n\nnpx aeo.js generate --url https://mysite.com --title \"My Site\" --out public\n\nSee the full [Configuration reference](/reference/configuration/) for all options.\n\nA complete CLI reference with every flag, exit codes, JSON output shapes, framework auto-detection table, and CI scripting patterns is in [docs/cli.md on GitHub](https://github.com/multivmlabs/aeo.js/blob/main/docs/cli.md).\n\n[Previous\nWidget](/features/widget/) [Next\nSchema & Open Graph](/features/schema-og/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Run aeo.js from the command line without any framework integration.",
      "keywords": [
        "report",
        "json",
        "section",
        "titled",
        "check",
        "terminal",
        "window",
        "options",
        "generate",
        "site"
      ],
      "metadata": {
        "chunkIndex": 1,
        "totalChunks": 2,
        "sourcePath": "/features/cli"
      }
    },
    {
      "id": "f2295a30ef3836fc",
      "url": "https://aeojs.org/docs/frameworks/vanilla",
      "title": "Vanilla JS / Static HTML (Part 2)",
      "content": "```jsonc\n// package.json\n{\n  \"scripts\": {\n    \"build:aeo\": \"aeo.js generate --url https://mysite.com --title \\\"My Site\\\" --out .\"\n  }\n}\n```\n\n### Eleventy / Hugo / Jekyll\n\n```jsonc\n// package.json\n{\n  \"scripts\": {\n    \"build\": \"eleventy\",\n    \"postbuild\": \"aeo.js generate --url https://mysite.com --title \\\"My Site\\\" --out _site\"\n  }\n}\n```\n\nFor Hugo use `--out public`; for Jekyll `--out _site`. The `postbuild` script runs automatically after `npm run build`.\n\n### Markdown blog (no framework)\n\nThe CLI's `--out` flag covers built HTML; to also pull `.md` front-matter and bodies from a `contentDir`, use the programmatic API:\n\n```js\n// scripts/aeo.mjs\nimport { generateAEOFiles, resolveConfig } from 'aeo.js';\n\nawait generateAEOFiles(resolveConfig({\n  title: 'My Blog',\n  url: 'https://myblog.dev',\n  contentDir: 'content',        // pull post bodies from here\n  outDir: 'public',             // write generated files here\n}));\n```\n\n```jsonc\n// package.json\n{\n  \"scripts\": {\n    \"build:aeo\": \"node scripts/aeo.mjs\"\n  }\n}\n```\n\n## Adding the Widget\n\n```html\n<script type=\"module\">\n  import { AeoWidget } from 'https://esm.sh/aeo.js/widget';\n  new AeoWidget({\n    config: {\n      title: 'My Site',\n      url: 'https://mysite.com',\n      widget: { enabled: true, position: 'bottom-right', size: 'small' },\n    },\n  });\n</script>\n```\n\nOr install and bundle locally with `import { AeoWidget } from 'aeo.js/widget'`.\n\n## CI Integration\n\n```yaml\n- run: npx aeo.js check --json | tee audit.json\n- run: |\n    SCORE=$(jq '.audit.score' audit.json)\n    [ \"$SCORE\" -ge 70 ] || { echo \"GEO score $SCORE below 70\"; exit 1; }\n```\n\n<Aside>\nFull walkthrough with deployment recipes (Vercel, Netlify, Cloudflare, GitHub Pages) is in the [Vanilla Guide on GitHub](https://github.com/multivmlabs/aeo.js/blob/main/docs/vanilla.md).\n</Aside>\n\n## Further Reading",
      "description": "Use aeo.js with a plain HTML site, hand-rolled JS, or any static-site generator — no framework required.",
      "keywords": [
        "site",
        "json",
        "https",
        "title",
        "from",
        "html",
        "mysite",
        "public",
        "contentdir",
        "pages"
      ],
      "metadata": {
        "title": "Vanilla JS / Static HTML",
        "description": "Use aeo.js with a plain HTML site, hand-rolled JS, or any static-site generator — no framework required.",
        "chunkIndex": 1,
        "totalChunks": 3,
        "sourcePath": "docs/frameworks/vanilla.mdx"
      }
    },
    {
      "id": "f3b133f8dfb06d7b",
      "url": "https://aeojs.org/features/generated-files",
      "title": "Generated Files (Part 1)",
      "content": "## Generated Files\n\nAfter building, aeo.js generates these files in your output directory:\n\n## robots.txt\n\n[Section titled “robots.txt”](#robotstxt)\n\nAI-crawler-aware robots directives. Includes rules for all known AI crawlers (GPTBot, ClaudeBot, PerplexityBot, etc.) with sensible defaults.\n\nUser-agent: *\n\nAllow: /\n\nUser-agent: GPTBot\n\nAllow: /\n\nUser-agent: ClaudeBot\n\nAllow: /\n\n## llms.txt\n\n[Section titled “llms.txt”](#llmstxt)\n\nA concise, LLM-readable summary of your site. This is the first file AI crawlers look for — it tells them what your site is about and where to find content.\n\n# My Site\n\nA site optimized for AI discovery\n\n## Pages\n\n- [Home](https://mysite.com/)\n\n- [About](https://mysite.com/about)\n\n- [Blog](https://mysite.com/blog)\n\n## llms-full.txt\n\n[Section titled “llms-full.txt”](#llms-fulltxt)\n\nFull concatenated content of all pages in a single file. Useful for LLMs that want to ingest your entire site at once.\n\n## sitemap.xml\n\n[Section titled “sitemap.xml”](#sitemapxml)\n\nStandard XML sitemap for search engines and AI crawlers.\n\n## docs.json\n\n[Section titled “docs.json”](#docsjson)\n\nA structured documentation manifest:\n\n{\n\n\"name\": \"My Site\",\n\n\"description\": \"A site optimized for AI discovery\",\n\n\"baseUrl\": \"https://mysite.com\",\n\n\"totalDocs\": 5,\n\n\"docs\": [{\n\n\"title\": \"Home\",\n\n\"path\": \"/\",\n\n\"markdownUrl\": \"https://mysite.com/index.md\",\n\n\"htmlUrl\": \"https://mysite.com/\",\n\n\"content\": \"...\"\n\n}]\n\n}\n\n## ai-index.json\n\n[Section titled “ai-index.json”](#ai-indexjson)\n\nAn AI-optimized content index designed for RAG (Retrieval-Augmented Generation) pipelines:\n\n[{\n\n\"id\": \"index\",\n\n\"url\": \"https://mysite.com/\",\n\n\"title\": \"Home\",\n\n\"content\": \"Full page content in markdown...\",\n\n\"description\": \"Page description\",\n\n\"keywords\": [\"keyword1\", \"keyword2\"]\n\n}]\n\n## Raw Markdown\n\n[Section titled “Raw Markdown”](#raw-markdown)\n\nOne .md file per page, extracted from your rendered HTML:\n\npublic/\n\nindex.md # Markdown for /\n\nabout.md # Markdown for /about",
      "description": "All the files aeo.js generates and what they",
      "keywords": [
        "https",
        "section",
        "titled",
        "true",
        "site",
        "mysite",
        "markdown",
        "llms",
        "content",
        "index"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "/features/generated-files"
      }
    },
    {
      "id": "f452caba69101fb6",
      "url": "https://aeojs.org/docs/getting-started/introduction",
      "title": "Introduction (Part 1)",
      "content": "import { Aside } from '@astrojs/starlight/components';\n\n![aeo.js in action](/example.webp)\n\n## What is Answer Engine Optimization?\n\nAnswer Engine Optimization (AEO) is the practice of making your website discoverable and citable by AI-powered answer engines like **ChatGPT**, **Claude**, **Perplexity**, and **SearchGPT**.\n\nUnlike 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.\n\n## Why aeo.js?\n\nAI crawlers and LLMs look for specific files and formats that most websites don't provide:\n\n- **`llms.txt`** — A concise summary of your site written for LLMs\n- **`llms-full.txt`** — Full content concatenated for deep ingestion\n- **`ai-index.json`** — Structured content optimized for RAG pipelines\n- **`docs.json`** — Documentation manifest for content discovery\n- **Raw Markdown** — Per-page `.md` files for clean content extraction\n\n**aeo.js** generates all of these automatically from your existing pages — no manual work required.\n\n## How it works\n\n1. **Install** the package and add the plugin for your framework\n2. **Build** your site as usual\n3. **aeo.js** scans your output, extracts content, and generates all AEO files\n4. The optional **widget** lets visitors toggle between human and AI views of your pages\n\n## Scope: what aeo.js does and doesn't influence\n\nAEO 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:\n\n<Aside type=\"note\" title=\"What aeo.js does well\">\nImproves machine-readable access to **your own site**:\n\n- generates `llms.txt`, `llms-full.txt`, `ai-index.json`, raw markdown copies, JSON-LD schema, and a sitemap\n- structures content so AI crawlers can fetch, parse, and quote it\n- audits and scores your page-level citability so you know where to improve\n</Aside>",
      "description": "What is aeo.js and why you need Answer Engine Optimization.",
      "keywords": [
        "your",
        "content",
        "llms",
        "site",
        "aside",
        "what",
        "full",
        "json",
        "from",
        "answer"
      ],
      "metadata": {
        "title": "Introduction",
        "description": "What is aeo.js and why you need Answer Engine Optimization.",
        "chunkIndex": 0,
        "totalChunks": 2,
        "sourcePath": "docs/getting-started/introduction.mdx"
      }
    },
    {
      "id": "f51b15e780dbaf8f",
      "url": "https://aeojs.org/docs/features/json-ld",
      "title": "JSON-LD Recipes (Part 3)",
      "content": "```ts\nconst breadcrumbSchema = {\n  '@context': 'https://schema.org',\n  '@type': 'BreadcrumbList',\n  itemListElement: [\n    { '@type': 'ListItem', position: 1, name: 'Home', item: 'https://mysite.com/' },\n    { '@type': 'ListItem', position: 2, name: 'Blog', item: 'https://mysite.com/blog' },\n    { '@type': 'ListItem', position: 3, name: 'Article Title' },\n  ],\n};\n```\n\n## Injecting safely — per framework\n\n<Tabs>\n  <TabItem label=\"Next.js\">\n    ```tsx\n    import { serializeJsonForHtml } from '@/lib/serialize-json-ld';\n\n    <script\n      type=\"application/ld+json\"\n      dangerouslySetInnerHTML={{ __html: serializeJsonForHtml(faqSchema) }}\n    />\n    ```\n  </TabItem>\n  <TabItem label=\"Astro\">\n    ```astro\n    ---\n    import { serializeJsonForHtml } from '../lib/serialize-json-ld';\n    ---\n\n    <script type=\"application/ld+json\" set:html={serializeJsonForHtml(faqSchema)} />\n    ```\n  </TabItem>\n  <TabItem label=\"Nuxt\">\n    ```vue\n    <script setup lang=\"ts\">\n    import { serializeJsonForHtml } from '~/utils/serialize-json-ld';\n\n    useHead({\n      script: [{\n        type: 'application/ld+json',\n        children: serializeJsonForHtml(faqSchema),\n      }],\n    });\n    </script>\n    ```\n  </TabItem>\n  <TabItem label=\"Svelte\">\n    ```svelte\n    <script lang=\"ts\">\n      import { serializeJsonForHtml } from './lib/serialize-json-ld';\n      const schema = serializeJsonForHtml(faqSchema);\n    </script>\n\n    <svelte:head>\n      <script type=\"application/ld+json\">{@html schema}</script>\n    </svelte:head>\n    ```\n  </TabItem>\n</Tabs>\n\n## Validation\n\nAfter deploying, paste your URL into one of these:\n\n- [Schema Markup Validator](https://validator.schema.org/) — official, quickest\n- [Google Rich Results Test](https://search.google.com/test/rich-results) — Google rich-result eligibility\n- [Bing Webmaster URL Inspection](https://www.bing.com/webmasters/url-inspection) — Bing/Copilot-specific feedback",
      "description": "Copy-paste structured-data recipes for FAQ, HowTo, Product, Article, Recipe, Event, VideoObject, and BreadcrumbList — each paired with an XSS-safe serializer.",
      "keywords": [
        "type",
        "json",
        "https",
        "schema",
        "script",
        "name",
        "tabitem",
        "serializejsonforhtml",
        "aside",
        "const"
      ],
      "metadata": {
        "title": "JSON-LD Recipes",
        "description": "Copy-paste structured-data recipes for FAQ, HowTo, Product, Article, Recipe, Event, VideoObject, and BreadcrumbList — each paired with an XSS-safe serializer.",
        "chunkIndex": 2,
        "totalChunks": 4,
        "sourcePath": "docs/features/json-ld.mdx"
      }
    },
    {
      "id": "fe3e73e267325986",
      "url": "https://aeojs.org/frameworks/angular",
      "title": "Angular",
      "content": "## Angular\n\n## Setup\n\n[Section titled “Setup”](#setup)\n\n-\nInstall the package:\n\nTerminal window\n\nnpm install aeo.js\n\n-\nAdd a post-build step to your package.json:\n\n{\n\n\"scripts\": {\n\n\"postbuild\": \"node -e \\\"import('aeo.js/angular').then(m => m.postBuild({ title: 'My App', url: 'https://myapp.com' }))\\\"\"\n\n}\n\n}\n\nm.postBuild({ title: &#x27;My App&#x27;, url: &#x27;https://myapp.com&#x27; }))\\&#x22;&#x22; }}\">\n\n-\nBuild your app:\n\nTerminal window\n\nnpm run build\n\n## How it works\n\n[Section titled “How it works”](#how-it-works)\n\nThe Angular plugin:\n\n- Reads angular.json to auto-detect the output directory (dist/&#x3C;project>/browser/)\n\n- Scans route config files (*.routes.ts) and component directories for routes\n\n- Scans pre-rendered HTML from the build output for full page content\n\n- Injects the widget into index.html automatically\n\n## Programmatic usage\n\n[Section titled “Programmatic usage”](#programmatic-usage)\n\nYou can also generate AEO files from source routes without building:\n\nimport { generate } from 'aeo.js/angular';\n\nawait generate({ title: 'My App', url: 'https://myapp.com' });\n\nNote\n\nAngular SSR (with @angular/ssr) is supported. The plugin will scan pre-rendered HTML for content extraction.\n\n## Configuration\n\n[Section titled “Configuration”](#configuration)\n\nPass any [AeoConfig](/reference/configuration/) options to postBuild or generate:\n\nimport { postBuild } from 'aeo.js/angular';\n\nawait postBuild({\n\ntitle: 'My App',\n\nurl: 'https://myapp.com',\n\ngenerators: {\n\nrobotsTxt: true,\n\nllmsTxt: true,\n\nschema: true,\n\n},\n\n});\n\n[Previous\nNuxt](/frameworks/nuxt/) [Next\nWebpack](/frameworks/webpack/)\nBuilt by [rubenmarcus](https://github.com/rubenmarcus) & [multivmlabs](https://github.com/multivmlabs)",
      "description": "Use aeo.js with Angular.",
      "keywords": [
        "angular",
        "postbuild",
        "https",
        "section",
        "titled",
        "build",
        "title",
        "myapp",
        "from",
        "generate"
      ],
      "metadata": {
        "chunkIndex": 0,
        "totalChunks": 1,
        "sourcePath": "/frameworks/angular"
      }
    }
  ],
  "metadata": {
    "totalEntries": 79,
    "generator": "aeo.js",
    "generatorUrl": "https://aeojs.org",
    "embedding": {
      "recommended": "text-embedding-ada-002",
      "dimensions": 1536
    }
  }
}