Core Concepts

RAG Integration

Last updated by Harlan Wilton in chore: lint.

Nuxt AI Ready provides a build-time hook for processing content chunks during prerendering. Use it to build RAG pipelines, vector databases, and semantic search implementations.

Build-Time Hook

The ai-ready:chunk hook fires for each content chunk during prerendering. You can generate embeddings, populate vector databases, or build custom search indexes.

Hook Context

interface ChunkContext {
  chunk: BulkChunk // The chunk data
  route: string // Page route (e.g., '/about')
  title: string // Page title
  description: string // Page description
  headings: Array<Record<string, string>> // Headings structure (e.g., [{ h1: 'Title' }])
}

interface BulkChunk {
  id: string // SHA256-based chunk ID (stable across rebuilds, e.g., "abc123-0")
  route: string // Page route
  content: string // Markdown content
}

The chunk index can be inferred from the id suffix (e.g., "abc123-0" → index 0, "abc123-1" → index 1).

Usage Examples

Vector Database Integration

Generate embeddings and populate a vector database:

// nuxt.config.ts
export default defineNuxtConfig({
  hooks: {
    'ai-ready:chunk': async (context) => {
      const embedding = await generateEmbedding(context.chunk.content)
      const chunkIndex = Number.parseInt(context.chunk.id.split('-').pop() || '0')

      await vectorDb.insert({
        id: context.chunk.id,
        embedding,
        content: context.chunk.content,
        metadata: {
          route: context.route,
          title: context.title,
          chunkIndex,
        }
      })
    }
  }
})

Search Index Building

Build a custom search index:

export default defineNuxtConfig({
  hooks: {
    'ai-ready:chunk': async (context) => {
      await searchIndex.addDocument({
        id: context.chunk.id,
        route: context.route,
        title: context.title,
        content: context.chunk.content,
        headings: context.headings,
      })
    }
  }
})

Multiple Database Sync

Populate multiple systems simultaneously:

export default defineNuxtConfig({
  hooks: {
    'ai-ready:chunk': async (context) => {
      const embedding = await generateEmbedding(context.chunk.content)

      await Promise.all([
        // Vector database for semantic search
        vectorDb.insert({ id: context.chunk.id, embedding }),
        // Full-text search index
        searchIndex.add({ id: context.chunk.id, content: context.chunk.content }),
        // Analytics/tracking
        analytics.track('chunk_indexed', { route: context.route }),
      ])
    }
  }
})

Chunk ID Stability

Chunk IDs are deterministic SHA256 hashes based on route and index, stable across rebuilds:

// Generated by nuxt-ai-ready
function generateVectorId(route: string, chunkIndex: number): string {
  const hash = createHash('sha256')
    .update(route)
    .digest('hex')
    .substring(0, 8)
  return `${hash}-${chunkIndex}`
}

Same route + index = same ID across rebuilds. You can skip regenerating embeddings for unchanged content and do efficient incremental updates.

Configuration

Route Filtering

Exclude routes from processing:

export default defineNuxtConfig({
  nitro: {
    prerender: {
      ignore: ['/admin/**', '/api/**']
    }
  }
})

Best Practices

  1. Batch Operations: Collect chunks and batch insert to vector DB for better performance
  2. Error Handling: Wrap hook logic in try/catch so builds don't fail
  3. Incremental Updates: Use stable chunk IDs to only update changed content
  4. Metadata: Store relevant metadata (route, title, headers) alongside embeddings for filtering

See API Reference for complete hook documentation.

Did this page help you?