These composables are auto-imported in Nitro server context (API routes, middleware, plugins).
queryPagesType: (event?: H3Event, options?: QueryPagesOptions) => Promise<PageEntry[] | PageData[]>
Unified page query function with filtering, pagination, and optional markdown content.
import { queryPages } from '#ai-ready'
export default defineEventHandler(async (event) => {
// Get all pages
const pages = await queryPages(event)
return pages
})
Single page lookup:
export default defineEventHandler(async (event) => {
const { path } = getQuery(event)
const page = await queryPages(event, { route: path as string, includeMarkdown: true })
return page
})
QueryPagesOptions:
| Option | Type | Description |
|---|---|---|
route | string | Get single page by route |
includeMarkdown | boolean | Include markdown content |
where.pending | boolean | Filter by indexing status |
where.hasError | boolean | Filter by error status |
where.source | 'prerender' | 'runtime' | Filter by source |
limit | number | Max pages to return |
offset | number | Skip first N pages |
PageEntry:
| Property | Type | Description |
|---|---|---|
route | string | Page route (e.g., /about) |
title | string | Page title |
description | string | Meta description |
headings | string | Pipe-separated headings (e.g., h1:Title|h2:Subtitle) |
keywords | string[] | Extracted keywords |
updatedAt | string | ISO timestamp |
PageData: Extends PageEntry with markdown: string.
searchPagesType: (event: H3Event, query: string, options?: SearchPagesOptions) => Promise<SearchResult[]>
Full-text search using SQLite FTS5. Searches title, description, route, headings, keywords, and markdown content.
import { searchPages } from '#ai-ready'
export default defineEventHandler(async (event) => {
const { q } = getQuery(event)
return searchPages(event, q as string, { limit: 10 })
})
SearchResult:
| Property | Type | Description |
|---|---|---|
route | string | Page route |
title | string | Page title |
description | string | Meta description |
score | number | BM25 relevance score |
countPagesType: (event?: H3Event, options?: CountPagesOptions) => Promise<number>
Count pages matching criteria.
import { countPages } from '#ai-ready'
export default defineEventHandler(async (event) => {
const total = await countPages(event)
const pending = await countPages(event, { where: { pending: true } })
return { total, pending, indexed: total - pending }
})
streamPagesType: (event?: H3Event, options?: StreamPagesOptions) => AsyncGenerator<PageData>
Stream pages using cursor-based pagination. Useful for large datasets.
import { streamPages } from '#ai-ready'
export default defineEventHandler(async (event) => {
const pages = []
for await (const page of streamPages(event, { batchSize: 50 })) {
pages.push({ route: page.route, title: page.title })
}
return pages
})
indexPageType: (route: string, html: string, options?: IndexPageOptions) => Promise<IndexPageResult>
Manually index a page into the database.
import { indexPage } from '#ai-ready'
export default defineEventHandler(async (event) => {
const { path } = await readBody(event)
const html = await $fetch(path)
return indexPage(path, html, { force: true })
})
Options:
| Option | Type | Default | Description |
|---|---|---|---|
ttl | number | config value | Override TTL check |
force | boolean | false | Re-index even if fresh |
skipHook | boolean | false | Skip ai-ready:page:indexed hook |
Result:
| Property | Type | Description |
|---|---|---|
success | boolean | Whether indexing succeeded |
skipped | boolean | true if page was fresh |
isUpdate | boolean | true if updating existing entry |
contentChanged | boolean | true if content hash differs |
data | object | Page data if successful |
error | string | Error message if failed |
indexPageByRouteType: (route: string, event?: H3Event, options?: IndexPageOptions) => Promise<IndexPageResult>
Fetch HTML and index in one call.
import { indexPageByRoute } from '#ai-ready'
export default defineNitroPlugin(async () => {
// Pre-warm important pages on startup
const routes = ['/', '/docs', '/pricing']
await Promise.all(routes.map(r => indexPageByRoute(r)))
})
useDatabaseType: (event?: H3Event) => Promise<DatabaseAdapter>
Direct database access for advanced queries.
import { useDatabase } from '#ai-ready'
export default defineEventHandler(async (event) => {
const db = await useDatabase(event)
const rows = await db.all('SELECT route, title FROM ai_ready_pages WHERE indexed = 1')
return rows
})
| Context | Source |
|---|---|
| Development | Empty (warning logged) |
| Prerender | SQLite via virtual module |
| Runtime | SQLite via db0 |