POST /api/search
Semantic search endpoint with optional query rewriting.
interface SearchRequest {
query: string // Required: Search query
limit?: number // Optional: Max results (default: 10)
query_id?: string // Optional: Query identifier
}
curl -X POST "https://example.com/api/search" \
-H "Content-Type: application/json" \
-d '{
"query": "nuxt modules",
"limit": 10
}'
interface SearchResponse {
query_id?: string
results: SearchResult[]
}
interface SearchResult {
url: string
name: string
score: number
description?: string
markdown?: string
}
Example:
{
"query_id": "abc123",
"results": [
{
"url": "/guide/module-development",
"name": "Module Development Guide",
"score": 0.89,
"description": "Learn how to build Nuxt modules",
"markdown": "# Module Development\n\nModule development involves..."
}
]
}
Missing Query:
{
"statusCode": 400,
"message": "Query parameter is required"
}
Invalid Limit:
{
"statusCode": 400,
"message": "Limit must be between 1 and 100"
}
Index Not Found:
{
"statusCode": 500,
"message": "Vector database not found. Make sure the site has been built."
}
ai-search:search:queryTransform query before search execution (e.g., query rewriting).
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook('ai-search:search:query', async (ctx, result) => {
// Modify query before search
result.query = ctx.query + ' synonyms here'
})
})
Context:
interface SearchQueryContext {
query: string
event: H3Event
limit: number
model?: LanguageModel
config: RuntimeConfig
}
ai-search:search:resultsPost-process search results (e.g., filtering, reranking).
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook('ai-search:search:results', async (ctx, result) => {
// Filter results by score
result.results = result.results.filter(r => r.score > 0.5)
})
})
Context:
interface SearchResultsContext {
query: string
results: SearchResult[]
event: H3Event
config: RuntimeConfig
}
The module includes built-in query rewriting via the ai-search:search:query hook.
Configuration:
export default defineNuxtConfig({
aiSearch: {
llm: {
provider: 'openai',
model: 'gpt-4o-mini',
apiKey: process.env.OPENAI_API_KEY
},
queryRewriting: {
enabled: true,
systemPrompt: 'Expand the query with relevant synonyms...'
}
}
})
Note: Query rewriting is automatically disabled for models <7B params.
curl -X POST "https://example.com/api/search" \
-H "Content-Type: application/json" \
-d '{"query": "installation"}'
curl -X POST "https://example.com/api/search" \
-H "Content-Type: application/json" \
-d '{"query": "nuxt modules", "limit": 5}'
curl -X POST "https://example.com/api/search" \
-H "Content-Type: application/json" \
-d '{
"query": "how to create plugins",
"limit": 10,
"query_id": "user-123-query-1"
}'
// Fetch API
const response = await fetch('/api/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query: 'nuxt modules',
limit: 10
})
})
const data = await response.json()
// Nuxt composable
const results = await $fetch('/api/search', {
method: 'POST',
body: {
query: 'nuxt modules',
limit: 10
}
})
To allow cross-origin requests:
export default defineNuxtConfig({
routeRules: {
'/api/search': {
cors: true,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
}
}
}
})
import type {
SearchRequest,
SearchResponse,
SearchResult
} from 'nuxt-ai-search'
const request: SearchRequest = {
query: 'nuxt modules',
limit: 10
}
const response: SearchResponse = await $fetch('/api/search', {
method: 'POST',
body: request
})