aeo.js

Answer Engine Optimization for the modern web. Make your site discoverable by AI crawlers and LLMs.
16,857 144
Install
npm install aeo.js
Latest Version:0.0.16
Vue:3
License:MIT
Last Updated:Oct 21, 2026
Links: GitHub  ·  npm
Maintainer: rmarcus

Install

npm install aeo.js

Check any site in 10 seconds

See how visible a site is to ChatGPT, Claude, Perplexity & co — no install, no config:

npx aeo.js check mysite.com

You get a 0–100 GEO readiness score, an access matrix for 23 AI crawlers, average content citability, and the top fixes — for any deployed site. Also available in the browser at check.aeojs.org.

Quick Start

Astro

// astro.config.mjs
import { defineConfig } from 'astro/config';
import { aeoAstroIntegration } from 'aeo.js/astro';

export default defineConfig({
  site: 'https://mysite.com',
  integrations: [
    aeoAstroIntegration({
      title: 'My Site',
      description: 'A site optimized for AI discovery',
      url: 'https://mysite.com',
    }),
  ],
});

Next.js

// next.config.mjs
import { withAeo } from 'aeo.js/next';

export default withAeo({
  aeo: {
    title: 'My Site',
    description: 'A site optimized for AI discovery',
    url: 'https://mysite.com',
  },
});

Add the post-build step to package.json:

{
  "scripts": {
    "postbuild": "node -e \"import('aeo.js/next').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\""
  }
}

Vite

// vite.config.ts
import { defineConfig } from 'vite';
import { aeoVitePlugin } from 'aeo.js/vite';

export default defineConfig({
  plugins: [
    aeoVitePlugin({
      title: 'My Site',
      description: 'A site optimized for AI discovery',
      url: 'https://mysite.com',
    }),
  ],
});

Nuxt

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['aeo.js/nuxt'],
  aeo: {
    title: 'My Site',
    description: 'A site optimized for AI discovery',
    url: 'https://mysite.com',
  },
});

Remix

{
  "scripts": {
    "postbuild": "node -e \"import('aeo.js/remix').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\""
  }
}

SvelteKit

{
  "scripts": {
    "postbuild": "node -e \"import('aeo.js/sveltekit').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\""
  }
}

TanStack Start

{
  "scripts": {
    "postbuild": "node -e \"import('aeo.js/tanstack-start').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\""
  }
}

Routes are discovered from src/routes (TanStack Router file conventions). No build output yet? Use generate() instead of postBuild() to emit files into public/ from your source routes.

Docusaurus

// docusaurus.config.js
module.exports = {
  plugins: [
    ['aeo.js/docusaurus', { url: 'https://mysite.com', title: 'My Docs' }],
  ],
};

url, title, and description default to your Docusaurus siteConfig (including baseUrl) when omitted. AEO files are generated from the built HTML during docusaurus build, and the widget is injected on every page.

Eleventy

// eleventy.config.js
const aeo = require('aeo.js/eleventy');

module.exports = function (eleventyConfig) {
  eleventyConfig.addPlugin(aeo, { url: 'https://mysite.com', title: 'My Site' });
};

Requires Eleventy 2.0+. AEO files are generated from the rendered output into your Eleventy output directory (_site by default), and the widget is injected into every HTML page.

VitePress

// .vitepress/config.ts
import { defineConfig } from 'vitepress';
import { withAeo } from 'aeo.js/vitepress';

export default defineConfig(withAeo({
  title: 'My Docs',
  // …your VitePress config…
}, { url: 'https://mysite.com' }));

withAeo wraps your config: it collects pages during vitepress build, injects the widget, and generates AEO files into the output directory. url, title, and description default from your VitePress site config (and sitemap.hostname).

Angular

{
  "scripts": {
    "postbuild": "node -e \"import('aeo.js/angular').then(m => m.postBuild({ title: 'My App', url: 'https://myapp.com' }))\""
  }
}

Webpack

// webpack.config.js
const { AeoWebpackPlugin } = require('aeo.js/webpack');

module.exports = {
  plugins: [
    new AeoWebpackPlugin({
      title: 'My Site',
      description: 'A site optimized for AI discovery',
      url: 'https://mysite.com',
    }),
  ],
};

CLI

No framework needed — run standalone:

npx aeo.js generate --url https://mysite.com --title "My Site"
npx aeo.js init
npx aeo.js check

Supported Frameworks

Framework Import
Astro aeo.js/astro
Next.js aeo.js/next
Vite aeo.js/vite
Nuxt aeo.js/nuxt
Remix aeo.js/remix
SvelteKit aeo.js/sveltekit
Angular aeo.js/angular
Webpack aeo.js/webpack
CLI npx aeo.js generate

Widget

The Human/AI widget lets visitors toggle between the normal page and its AI-readable markdown version.

Default Small Icon

Framework plugins inject it automatically. For Next.js or manual setups:

'use client';
import { useEffect } from 'react';

export function AeoWidgetLoader() {
  useEffect(() => {
    import('aeo.js/widget').then(({ AeoWidget }) => {
      new AeoWidget({
        config: {
          title: 'My Site',
          url: 'https://mysite.com',
          widget: { enabled: true, position: 'bottom-right' },
        },
      });
    });
  }, []);
  return null;
}

React and Vue wrapper components are also available:

import { AeoReactWidget } from 'aeo.js/react';

<AeoReactWidget config={{ title: 'My Site', url: 'https://mysite.com' }} />
<script setup>
import { AeoVueWidget } from 'aeo.js/vue';
</script>

<template>
  <AeoVueWidget :config="{ title: 'My Site', url: 'https://mysite.com' }" />
</template>

Generated Files

After building, your output directory contains:

public/
├── robots.txt        # AI-crawler directives
├── llms.txt          # Short LLM-readable summary
├── llms-full.txt     # Full content for LLMs
├── sitemap.xml       # Standard sitemap
├── docs.json         # Documentation manifest
├── ai-index.json     # AI content index
├── index.md          # Markdown for /
└── about.md          # Markdown for /about

Configuration

import { defineConfig } from 'aeo.js';

export default defineConfig({
  title: 'My Site',
  url: 'https://mysite.com',
  description: 'A description of your site',

  generators: {
    robotsTxt: true,
    llmsTxt: true,
    llmsFullTxt: true,
    rawMarkdown: true,
    sitemap: true,
    aiIndex: true,
    schema: true,
  },

  schema: {
    enabled: true,
    organization: { name: 'My Company', url: 'https://mysite.com' },
    defaultType: 'WebPage',
  },

  og: {
    enabled: true,
    image: 'https://mysite.com/og.png',
    twitterHandle: '@mycompany',
  },

  widget: {
    enabled: true,
    position: 'bottom-right',
    theme: { accent: '#4ADE80', badge: '#4ADE80' },
  },
});

Full configuration reference → aeojs.org/reference/configuration

Why AEO?

  • 58% of searches end without a click — AI gives the answer directly
  • 40% of Gen Z prefer AI assistants over traditional search engines
  • 97% of sites have no llms.txt or structured data for AI crawlers
  • 1 minute to set up with aeo.js

If your site isn't optimized for AI engines, you're invisible to a growing share of users who never open a search results page.

Links

License

MIT

Related Packages

@githumbi/grabby

Point at any UI element, leave a comment, and hand the feedback to an AI coding...

948 0
hexagon-ai

Server-side middleware SDK for making websites AI-readable by ChatGPT, Perplexit...

1,593
@modelriver/client

Official ModelRiver client SDK for real-time AI response streaming via WebSocket...

2,724 6
artifactuse

The Artifact SDK for AI Agents - Turn AI outputs into interactive experiences

7,162 2
@mcpc-tech/unplugin-dev-inspector-mcp

Universal dev inspector plugin for React/Vue - inspect component sources and API...

31,029 47

Version History

Version Released License
0.0.16 MIT
0.0.15 MIT
0.0.14 MIT
0.0.13 MIT
0.0.12 MIT