Skip to content
Skillv1.0.0

algolia-reference-architecture

Implement Algolia reference architecture: index design, multi-index strategy, data pipeline, search service layer, and frontend/backend separation. Trigger: "algolia architecture", "algolia best pract

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (plugins/saas-packs/algolia-pack/skills/algolia-reference-architecture/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill algolia-reference-architecture. Copyright stays with the author (MIT).

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.

Prerequisites

  • A source-of-truth datastore, an approved transformation boundary, and explicit ownership for indexing and search-serving services.
  • Separate Admin and search-only credentials, kept on the backend and frontend respectively.
  • An environment and index naming convention that permits safe rehearsal and rollback.

Instructions

Use the architecture, project layout, and design patterns as a composable reference. Keep indexing, settings management, and search serving as separately testable boundaries rather than coupling them to a frontend component.

Examples

The diagrams and TypeScript patterns below demonstrate the reference topology, record transformation, settings-as-code, and service-layer contracts. Adapt the interfaces to your source schema while preserving the key boundary between write and search credentials.

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

// src/algolia/indices.ts
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`,     // Internal search only (never expose to frontend)
} as const;

export type IndexName = typeof INDICES[keyof typeof INDICES];

Pattern 2: Record Transformer (Source → Algolia)

// src/algolia/transforms/product.ts
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[];        // Algolia convention: filterable tags
}

export function transformProduct(product: Product): AlgoliaProduct {
  return {
    objectID: product.id,
    name: product.name,
    description: product.description?.substring(0, 5000) || '',  // Truncate
    category: product.category.name,
    brand: product.brand.name,
    price: product.price / 100,                  // Cents → dollars
    rating: product.avgRating,
    review_count: product.reviewCount,
    in_stock: product.inventory > 0,
    image_url: product.images[0]?.url || '',
    _tags: [
      product.category.slug,
      ...(product.isFeatured ? ['featured'] : []),
      ...(product.isNew ? ['new-arrival'] : []),
    ],
  };
}

Pattern 3: Settings as Code

// src/algolia/settings/products.ts
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)',
  ],
};

// src/algolia/settings/apply.ts
import { getClient } from '../client';
import { INDICES } from '../indices';
import { productSettings } from './products';

async function applyAllSettings() {
  const client = getClient();
  await client.setSettings({ indexName: INDICES.products, indexSettings: productSettings });
  console.log('All Algolia settings applied');
}

Pattern 4: Search Service Layer

// src/services/search.ts
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', 'brand'],
          clickAnalytics: true,
        },
      });
    } catch (error) {
      if (error instanceof ApiError && error.status === 404) {
        return { hits: [], nbHits: 0, nbPages: 0, page: 0 };
      }
      throw error;
    }
  }

  async federatedSearch(query: string) {
    const { results } = await this.client.search({
      requests: [
        { indexName: INDICES.products, query, hitsPerPage: 5 },
        { indexName: INDICES.articles, query, hitsPerPage: 3 },
        { indexName: INDICES.faq, query, hitsPerPage: 3 },
      ],
    });
    return results;
  }
}

Output

The resulting system has explicit data flow, index ownership, settings deployment, and search-service contracts. It supports independent observability and rollback of indexing without exposing write credentials to end users.

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.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-algolia-refer-aeea37/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-algolia-refer-aeea37.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-algolia-refer-aeea37",
  "kind": "skill",
  "name": "algolia-reference-architecture",
  "description": "Implement Algolia reference architecture: index design, multi-index strategy, data pipeline, search service layer, and frontend/backend separation. Trigger: \"algolia architecture\", \"algolia best practices\", \"algolia project structure\", \"how to organize algolia\", \"algolia index design\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "general"
    ],
    "tags": [
      "skill-md",
      "saas",
      "search",
      "algolia",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Implement Algolia reference architecture: index design, multi-index strategy, data pipeline, search service layer, and frontend/backend separation. Trigger: \"algolia architecture\", \"algolia best practices\", \"algolia project structure\", \"how to organize algolia\", \"algolia index design\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "plugins/saas-packs/algolia-pack/skills/algolia-reference-architecture/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/plugins/saas-packs/algolia-pack/skills/algolia-reference-architecture/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/plugins/saas-packs/algolia-pack/skills/algolia-reference-architecture/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Grep"
    ],
    "license": "MIT"
  },
  "instructions": "# Algolia Reference Architecture\n\n## Overview\n\nProduction-ready architecture for Algolia-powered search. Covers index design, data pipeline from source to Algolia, service layer patterns, and frontend integration.\n\n## Prerequisites\n\n- A source-of-truth datastore, an approved transformation boundary, and explicit ownership for indexing and search-serving services.\n- Separate Admin and search-only credentials, kept on the backend and frontend respectively.\n- An environment and index naming convention that permits safe rehearsal and rollback.\n\n## Instructions\n\nUse the architecture, project layout",
  "cost": {
    "context_tokens": 2257
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-algolia-refer-aeea37/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.