Index of every page on this site: llms.txt

Use these functions in Nitro server code. Enable a database, directly or through runtime sync, before querying stored pages. Nuxt auto-imports queryPages, searchPages, countPages, streamPages, indexPage, and indexPageByRoute. Other exports need an explicit #ai-ready/server import.

queryPages

Type: (event?: H3Event, options?: QueryPagesOptions) => Promise<PageEntry[] | PageData[]>

Without route, returns a page array. With route, returns one page or undefined. Set includeMarkdown: true to include the Markdown body. List queries exclude error pages by default.

server/api/pages.get.ts
import { queryPages } from '#ai-ready/server'

export default defineEventHandler(async (event) => {
  return queryPages(event, { limit: 20 })
})

Single page lookup:

server/api/page.get.ts
export default defineEventHandler(async (event) => {
  const { path } = getQuery(event)
  if (typeof path !== 'string' || !path.startsWith('/'))
    throw createError({ statusCode: 400, statusMessage: 'Provide a page path starting with /.' })

  const page = await queryPages(event, { route: path, includeMarkdown: true })
  if (!page)
    throw createError({ statusCode: 404, statusMessage: 'Page not found.' })
  return page
})

QueryPagesOptions:

OptionTypeDescription
routestringGet single page by route
includeMarkdownbooleanInclude markdown content
where.pendingbooleanFilter by indexing status
where.hasErrorbooleanFilter by error status
where.source'prerender' | 'runtime'Filter by source
limitnumberMax pages to return
offsetnumberSkip first N pages

PageEntry:

PropertyTypeDescription
routestringPage route (e.g., /about)
titlestringPage title
descriptionstringMeta description
headingsArray<Record<string, string>>Parsed headings, such as [{ h1: "Title" }]
keywordsstring[]Extracted keywords
updatedAtstringISO timestamp
isErrorbooleanWhether the stored page is an error page
localestringStored locale, or an empty string

PageData: Extends PageEntry with markdown: string.

searchPages

Type: (event: H3Event, query: string, options?: SearchPagesOptions) => Promise<SearchResult[]>

SQLite-compatible databases use FTS5 across title, description, route, headings, keywords, and Markdown. PostgreSQL uses case-insensitive matching across title, description, headings, and Markdown. Search returns an empty array during development and prerendering.

server/api/search.get.ts
import { searchPages } from '#ai-ready/server'

export default defineEventHandler(async (event) => {
  const { q } = getQuery(event)
  if (typeof q !== 'string' || !q.trim())
    return []
  return searchPages(event, q, { limit: 10 })
})

SearchResult:

PropertyTypeDescription
routestringPage route
titlestringPage title
descriptionstringMeta description
scorenumberFTS5 BM25 score, lower ranks first; PostgreSQL returns 0

countPages

Type: (event?: H3Event, options?: CountPagesOptions) => Promise<number>

Count pages matching criteria.

server/api/stats.get.ts
import { countPages } from '#ai-ready/server'

export default defineEventHandler(async (event) => {
  const total = await countPages(event)
  const pending = await countPages(event, { where: { pending: true } })
  return { total, pending, indexed: total - pending }
})

streamPages

Type: (event?: H3Event, options?: StreamPagesOptions) => AsyncGenerator<PageData>

Read pages in batches using cursor-based pagination. This does not stream the HTTP response by itself. The example below returns only a count, so it does not collect every Markdown body in memory.

server/api/export.get.ts
import { streamPages } from '#ai-ready/server'

export default defineEventHandler(async (event) => {
  let withMarkdown = 0
  for await (const page of streamPages(event, { batchSize: 50 })) {
    if (page.markdown)
      withMarkdown++
  }
  return { withMarkdown }
})

indexPage

Type: (route: string, html: string, options?: IndexPageOptions, event?: H3Event) => Promise<IndexPageResult>

Index HTML you already trust. Call this from your authenticated publishing flow:

server/utils/index-about.ts
import type { H3Event } from 'h3'
import { indexPage } from '#ai-ready/server'

export function indexAbout(html: string, event: H3Event) {
  return indexPage('/about', html, { force: true }, event)
}

Database, conversion, or hook failures can throw. A successful write returns success: true. The indexPageByRoute wrapper converts fetch and indexing failures into a result with success: false.

Options:

OptionTypeDefaultDescription
ttlnumberconfig valueOverride TTL check
forcebooleanfalseRe-index even if fresh
skipHookbooleanfalseSkip ai-ready:page:indexed hook

Result:

PropertyTypeDescription
successbooleanWhether indexing succeeded
skippedbooleantrue if page was fresh
isUpdatebooleantrue if updating existing entry
contentChangedbooleantrue if content hash differs
dataobjectPage data if successful; its headings field contains serialized JSON
errorstringError message if failed

indexPageByRoute

Type: (route: string, event: H3Event | undefined, options?: IndexPageOptions) => Promise<IndexPageResult>

Fetch HTML and index it in one call. Pass the current request event:

server/utils/refresh-about.ts
import type { H3Event } from 'h3'
import { indexPageByRoute } from '#ai-ready/server'

export function refreshAbout(event: H3Event) {
  return indexPageByRoute('/about', event, { force: true })
}

Call this helper from an authenticated publishing flow. For HTTP triggers, use the module's authenticated reindex endpoint.

useDatabase

The current export is useRawDb. useDatabase is not exported. Use an explicit import for raw SQL access:

Type: (event?: H3Event) => Promise<RawExecutor>

server/api/custom.get.ts
import { useRawDb } from '#ai-ready/server'

export default defineEventHandler(async (event) => {
  const db = await useRawDb(event)
  return db.all('SELECT route, title FROM ai_ready_pages WHERE indexed = 1 AND is_error = 0 LIMIT 20')
})

Prefer queryPages when it covers the query. Raw SQL depends on the database schema.

Data Sources

ContextSource
DevelopmentQuery helpers return empty results
PrerenderTemporary SQLite database; full-text search is unavailable
RuntimeConfigured SQLite, Bun, D1, LibSQL, Neon, or PostgreSQL database

A database-backed feature must enable storage. See database configuration.

Was this page helpful?