Algolia Reference Architecture
Overview
Production-ready architecture for Algolia-powered search. Covers index design, data pipeline from source to Algolia, service layer patterns, and frontend integration.
Architecture Overview
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Frontend โ
โ InstantSearch.js / React InstantSearch โ
โ Uses: liteClient (search-only key) โ
โ Sends: search-insights events (clicks, conversions) โ
โโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Search + Events
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Algolia Cloud โ
โ โโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โ โ Search โ โ Analytics โ โ Recommend โ โ
โ โ Engine โ โ + Insights โ โ (ML-based) โ โ
โ โโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโฒโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Indexing (admin key)
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Backend Service โ
โ โโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ Search โ โ Indexing โ โ Settings โ โ
โ โ Service โ โ Pipeline โ โ Manager โ โ
โ โโโโโโโโโโโโโโ โโโโโโโโฌโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Source Database โ โ
โ โ PostgreSQL / MongoDB / CMS / External API โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Project Structure
src/
โโโ algolia/
โ โโโ client.ts # Singleton client (see algolia-sdk-patterns)
โ โโโ indices.ts # Index name constants + environment prefixing
โ โโโ settings/
โ โ โโโ products.ts # Products index settings
โ โ โโโ articles.ts # Articles index settings
โ โ โโโ apply.ts # Script to apply all settings
โ โโโ transforms/
โ โโโ product.ts # DB record โ Algolia record transformer
โ โโโ article.ts # DB record โ Algolia record transformer
โโโ services/
โ โโโ search.ts # Search service (wraps Algolia client)
โ โโโ indexing.ts # Indexing pipeline (DB โ transform โ Algolia)
โโโ api/
โ โโโ search.ts # Search endpoint (returns Algolia results)
โ โโโ reindex.ts # Admin endpoint to trigger reindex
โโโ jobs/
โโโ sync-algolia.ts # Cron job for periodic full sync
Index Design Patterns
Pattern 1: One Index Per Entity Type
const ENV = process.env.NODE_ENV === 'production' ? '' : `${process.env.NODE_ENV}_`;
export const INDICES = {
products: `${ENV}products`,
articles: `${ENV}articles`,
faq: `${ENV}faq`,
users: `${ENV}users`,
} as const;
export type IndexName = typeof INDICES[keyof typeof INDICES];
Pattern 2: Record Transformer (Source โ Algolia)
import type { Product } from '../db/types';
interface AlgoliaProduct {
objectID: string;
name: string;
description: string;
category: string;
brand: string;
price: number;
rating: number;
review_count: number;
in_stock: boolean;
image_url: string;
_tags: string[];
}
export function transformProduct(product: Product): AlgoliaProduct {
return {
objectID: product.id,
name: product.name,
description: product.description?.substring(0, 5000) || '',
category: product.category.name,
: product..,
: product. / ,
: product.,
: product.,
: product. > ,
: product.[]?. || ,
: [
product..,
...(product. ? [] : []),
...(product. ? [] : []),
],
};
}
Pattern 3: Settings as Code
import type { IndexSettings } from 'algoliasearch';
export const productSettings: IndexSettings = {
searchableAttributes: [
'name',
'brand',
'category',
'unordered(description)',
],
attributesForFaceting: [
'searchable(brand)',
'category',
'filterOnly(price)',
'filterOnly(in_stock)',
'_tags',
],
customRanking: ['desc(review_count)', 'desc(rating)'],
attributesToRetrieve: ['name', 'brand', 'price', 'image_url', 'category', 'rating'],
attributesToHighlight: ['name', 'description'],
attributesToSnippet: ['description:30'],
unretrievableAttributes: ['_tags'],
distinct: 1,
attributeForDistinct: 'product_group_id',
replicas: [
'virtual(products_price_asc)',
'virtual(products_price_desc)',
'virtual(products_newest)',
],
};
import { getClient } ;
{ } ;
{ productSettings } ;
() {
client = ();
client.({ : ., : productSettings });
.();
}
Pattern 4: Search Service Layer
import { getClient } from '../algolia/client';
import { INDICES } from '../algolia/indices';
import { ApiError } from 'algoliasearch';
export class SearchService {
private client = getClient();
async searchProducts(params: {
query: string;
filters?: string;
facetFilters?: string[][];
page?: number;
hitsPerPage?: number;
}) {
try {
return await this.client.searchSingleIndex({
indexName: INDICES.products,
searchParams: {
query: params.query,
filters: params.filters,
facetFilters: params.facetFilters,
page: params.page ?? 0,
hitsPerPage: params.hitsPerPage ?? 20,
facets: ['category', ],
: ,
},
});
} (error) {
(error && error. === ) {
{ : [], : , : , : };
}
error;
}
}
() {
{ results } = ..({
: [
{ : ., query, : },
{ : ., query, : },
{ : ., query, : },
],
});
results;
}
}
Error Handling
| Issue | Cause | Solution |
|---|
| Circular dependency | Service imports client imports service | Use lazy initialization |
| Config drift | Dashboard edits not in code | Apply settings from code in CI |
| Transform errors | DB schema change | Add validation in transformer |
| Index name typo | Hardcoded strings | Use INDICES constants |
Resources
Next Steps
For multi-environment setup, see algolia-multi-env-setup.