Search API
The Search API that uses the SearchService class allows Content SDK apps to query SitecoreAI search indexes to create tailored search experiences for different content types and user needs. This enables quick retrieval of content items and operations such as sorting, paginating, limiting results, etc. It abstracts the underlying search implementation and provides a consistent API.
The API has the following capabilities:
-
Use generic types to model documents for better IDE support and type safety
-
Sort results and use dot notation for nested properties
-
Limit and paginate results
-
Use custom fetch options for advanced use cases
Configuration
To initialize the SearchService class, you can create an instance of it using a configuration object as shown.
import { SearchService } from '@sitecore-content-sdk/search';
const searchService = new SearchService({
contextId: 'SITECORE_EDGE_CONTEXT_ID',
});The object expects the SITECORE_EDGE_CONTEXT_ID that you can retrieve from the Developer settings tab of your environment in the SitecoreAI Deploy App. After initialization, you can use the search method of the SearchService to retrieve results from SitecoreAI.
Supported parameters
The search method expects the ID of the search index and also supports several other parameters used to sort, paginate, limit, and offset results.
|
Parameter |
Type |
Description |
|---|---|---|
|
|
string |
The ID of the SitecoreAI search index to retrieve results from. Required |
|
|
string |
Use phrases to search the index for specific content. |
|
|
Object or Array of objects |
Specify an object or array of objects containing the name and order to sort results by. |
|
|
number |
Specify the limit to restrict the number of results returned. |
|
|
number |
Specify a number to drop that many results. Use with |
Examples
The following sections demonstrate examples using the SearchService for common scenarios.
Simple search
A basic search only requires the searchIndexId. The default limit is 10, so it returns only 10 results.
const response = await searchService.search({
searchIndexId: '1234567890',
});
console.log(`Found ${response.total} results`);
response.results.forEach((result) => {
console.log(result);
});Search with keyphrase
You can also search using a keyphrase as shown:
const response = await searchService.search({
searchIndexId: '1234567890',
keyphrase: 'sitecore',
});
console.log(`Found ${response.total} results matching "sitecore"`);Search with a generic type
The SearchService supports TypeScript generics, allowing you to define the shape of your search document for type safety and better IDE support.
The following example demonstrates using a type called Article to retrieve results and display its contents. This ensures predictable results.
import { SearchService } from '@sitecore-content-sdk/search';
type Article = {
id: string;
title: string;
description: string;
publishDate: string;
author: {
name: string;
email: string;
};
tags: string[];
}
const searchService = new SearchService({
contextId: 'your-context-id',
});
// TypeScript now knows the shape of the search document
const response = await searchService.search<Article>({
searchIndexId: '1234567890',
keyphrase: 'typescript',
});
// Type-safe access to properties
response.results.forEach((article) => {
console.log(article.title);
console.log(article.author.name);
console.log(article.tags.join(', '));
});Search with basic sorting
The SearchService supports sorting results using a single object specifying the name and order. The following example sorts the search results by the publishDate in the descending order (most recent first).
const response = await searchService.search({
searchIndexId: '1234567890',
keyphrase: 'article',
sort: {
name: 'publishDate',
order: 'desc', // Most recent first
},
});Search with multi-field sorting
You can also specify multiple fields to sort. Instead of a single object, you should specify this as an array of objects. The following example sorts the search results by category in the ascending order, followed by price in ascending order, and finally by rating in the descending order.
const response = await searchService.search({
searchIndexId: '1234567890',
keyphrase: 'electronics',
sort: [
{
name: 'category',
order: 'asc', // First sort by category
},
{
name: 'price',
order: 'asc', // Then by price within each category
},
{
name: 'rating',
order: 'desc', // Finally by rating (highest first)
},
],
});Search with type sorting
You can sort fields when you're using generics. TypeScript verifies the existence of the sort field in this case.
type Product = {
id: string;
name: string;
price: number;
rating: number;
category: string;
}
const response = await searchService.search<Product>({
searchIndexId: '1234567890',
sort: {
name: 'category', // TypeScript hints that this field exists
order: 'desc',
},
});
/* TypeScript error: Property 'invalidField' does not exist
const invalidSort = {
name: 'invalidField',
order: 'asc',
};
*/Search with nested sorting
Using dot notation (.), you can sort nested properties.
type Order = {
id: string;
orderDate: string;
customer: {
name: string;
email: string;
};
items: Array<{
productId: string;
quantity: number;
}>;
}
const response = await searchService.search<Order>({
searchIndexId: '1234567890',
sort: {
name: 'customer.name', // TypeScript hints that this field exists
order: 'asc',
},
});Search with limited results
To limit the number of results returned, you can use the limit property. The default value is 10 and the maximum value allowed is 500.
// Retrieve 5 results
const response = await searchService.search({
searchIndexId: '1234567890',
keyphrase: 'product',
limit: 5,
});
// Retrieve up to 500 results
const response = await searchService.search({
searchIndexId: '1234567890',
keyphrase: 'article',
limit: 500, // Maximum value
});Search with pagination
Use the offset parameter to implement pagination. Combined with limit, you can fetch results in pages.
async function getPage(
searchService: SearchService,
searchIndexId: string,
keyphrase: string,
page: number,
pageSize: number = 10
) {
const response = await searchService.search({
searchIndexId,
keyphrase,
limit: pageSize,
offset: (page - 1) * pageSize,
});
return {
results: response.results,
total: response.total,
page,
pageSize,
totalPages: Math.ceil(response.total / pageSize),
};
}
// Usage
const page1 = await getPage(searchService, 'your-search-index-id', 'article', 1, 10);
const page2 = await getPage(searchService, 'your-search-index-id', 'article', 2, 10);Search with custom fetch options
The SearchService allows you to customize the underlying fetch request by passing a RequestInit object as the second parameter. This is useful for adding custom headers, setting timeouts, or configuring other request options.
Custom headers
You can set custom headers using the headers object containing key-value pairs of the header name and value.
const response = await searchService.search(
{
searchIndexId: '1234567890',
keyphrase: 'product',
},
{
headers: {
'X-Custom-Header': 'custom-value',
},
}
);Request timeout
You can set a custom request timeout using the signal object that references the AbortController's signal property.
// Using AbortController for timeout
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 second timeout
try {
const response = await searchService.search(
{
searchIndexId: '1234567890',
keyphrase: 'product',
},
{
signal: controller.signal,
}
);
clearTimeout(timeoutId);
console.log(response.results);
} catch (error) {
if (error.name === 'AbortError') {
console.error('Request timed out');
} else {
throw error;
}
}Error handling
The SearchService throws specific errors that you should handle appropriately:
try {
const response = await searchService.search({
searchIndexId: '1234567890',
keyphrase: 'product',
limit: 10,
});
} catch (error) {
if (error instanceof RangeError) {
// Handle validation errors (limit, offset)
console.error('Invalid parameter:', error.message);
} else if (error instanceof TypeError) {
// Handle type errors (missing searchIndexId, invalid sort)
console.error('Type error:', error.message);
} else if (error instanceof Error) {
// Handle network/API errors
console.error('Search failed:', error.message);
}
}