Remix
-
Install the package:
Terminal window npm install aeo.js -
Add a post-build step to your
package.json:{"scripts": {"postbuild": "node -e \"import('aeo.js/remix').then(m => m.postBuild({ title: 'My Site', url: 'https://mysite.com' }))\""}} -
Build your app:
Terminal window npm run build
How it works
Section titled “How it works”The Remix plugin:
- Detects the static assets directory:
build/clientfor Vite-based Remix / React Router 7,public/for the classic compiler - Scans
app/routesflat-file routes (_index.tsx,about.tsx,blog._index.tsx, folder routes withroute.tsx) — pathless layouts (_marketing.) and optional segments (($lang).) are resolved, dynamic segments ($slug) are skipped - Scans prerendered HTML (React Router's
prerenderoption) for titles, descriptions, and full text content - Generates all AEO files (robots.txt, llms.txt, sitemap.xml, ai-index.json, …) into the static assets directory so they're served from the site root
Widget
Section titled “Widget”Remix renders HTML on the server, so add the widget script to your root route once:
import { getWidgetScript } from 'aeo.js/remix';
const widgetScript = getWidgetScript({ title: 'My Site', url: 'https://mysite.com',});
// In your Layout component, before </body>:<div dangerouslySetInnerHTML={{ __html: widgetScript }} />Programmatic usage
Section titled “Programmatic usage”Generate AEO files from source routes without a build — files land in public/:
import { generate } from 'aeo.js/remix';
await generate({ title: 'My Site', url: 'https://mysite.com' });Configuration
Section titled “Configuration”Pass any AeoConfig options to postBuild or generate:
import { postBuild } from 'aeo.js/remix';
await postBuild({ title: 'My Site', url: 'https://mysite.com', description: 'A site optimized for AI discovery', schema: { organization: { name: 'My Company' } },});