aeo.js
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.txtor 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
Point at any UI element, leave a comment, and hand the feedback to an AI coding...
Server-side middleware SDK for making websites AI-readable by ChatGPT, Perplexit...
Official ModelRiver client SDK for real-time AI response streaming via WebSocket...
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 | |
| 0.0.11 | MIT | |
| 0.0.10 | MIT | |
| 0.0.9 | MIT | |
| 0.0.8 | MIT | |
| 0.0.7 | MIT | |
| 0.0.6 | MIT | |
| 0.0.5 | MIT | |
| 0.0.4 | MIT | |
| 0.0.3 | MIT | |
| 0.0.2 | MIT | |
| 0.0.1 | MIT |