Claude-code-plugins algolia-webhooks-events
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/algolia-pack/skills/algolia-webhooks-events" ~/.claude/skills/jeremylongshore-claude-code-plugins-algolia-webhooks-events && rm -rf "$T"
manifest:
plugins/saas-packs/algolia-pack/skills/algolia-webhooks-events/SKILL.mdsource content
Algolia Events & Insights
Overview
Algolia doesn't use traditional webhooks. Instead, it provides the Insights API for sending user behavior events (clicks, conversions, views) back to Algolia, and the Analytics API for reading search performance data. For keeping your index in sync, you build event-driven pipelines from your database to Algolia.
Prerequisites
v5 installed (Insights client is included)algoliasearch- Index with records and
enabled (for click analytics)queryID
npm package for frontend event trackingsearch-insights
Instructions
Step 1: Enable Click Analytics in Search
import { algoliasearch } from 'algoliasearch'; const client = algoliasearch(process.env.ALGOLIA_APP_ID!, process.env.ALGOLIA_ADMIN_KEY!); // Enable clickAnalytics to get queryID in search results const { hits, queryID } = await client.searchSingleIndex({ indexName: 'products', searchParams: { query: 'running shoes', clickAnalytics: true, // Returns queryID for event correlation }, }); // queryID links this search to subsequent click/conversion events
Step 2: Send Click and Conversion Events (Backend)
// The Insights API is built into the algoliasearch client // Events connect user behavior back to specific search queries // Track a click on a search result await client.pushEvents({ events: [{ eventType: 'click', eventName: 'Product Clicked', index: 'products', userToken: 'user-123', // Unique user identifier queryID: queryID, // From search response objectIDs: ['product-456'], // What was clicked positions: [3], // Position in results (1-indexed) timestamp: Date.now(), }], }); // Track a conversion (purchase, add-to-cart) await client.pushEvents({ events: [{ eventType: 'conversion', eventName: 'Product Purchased', index: 'products', userToken: 'user-123', queryID: queryID, objectIDs: ['product-456'], timestamp: Date.now(), }], }); // Track a view (product page visit, no search context) await client.pushEvents({ events: [{ eventType: 'view', eventName: 'Product Viewed', index: 'products', userToken: 'user-123', objectIDs: ['product-456'], timestamp: Date.now(), }], });
Step 3: Frontend Event Tracking with search-insights
npm install search-insights
// Frontend: lightweight event tracking import { default as aa } from 'search-insights'; aa('init', { appId: 'YourAppID', apiKey: 'YourSearchOnlyKey', // Search-only key is fine for events }); // Set user token (anonymous or authenticated) aa('setUserToken', 'user-123'); // After user clicks a search result aa('clickedObjectIDsAfterSearch', { eventName: 'Product Clicked', index: 'products', queryID: 'abc123', // From search response objectIDs: ['product-456'], positions: [3], }); // After user converts (purchases) aa('convertedObjectIDsAfterSearch', { eventName: 'Product Purchased', index: 'products', queryID: 'abc123', objectIDs: ['product-456'], });
Step 4: Read Search Analytics
// The analytics client is part of algoliasearch const analyticsClient = client.initAnalytics({ region: 'us' }); // Top searches const { searches } = await client.getTopSearches({ index: 'products', startDate: '2025-01-01', endDate: '2025-01-31', }); searches.forEach(s => console.log(`"${s.search}" — ${s.count} searches, ${s.nbHits} avg hits`)); // Searches with no results (critical for relevance tuning) const { searches: noResults } = await client.getSearchesNoResults({ index: 'products', startDate: '2025-01-01', endDate: '2025-01-31', }); noResults.forEach(s => console.log(`"${s.search}" — ${s.count} times, 0 results`)); // Click-through rate and conversion rate const { clickRate, conversionRate } = await client.getClickThroughRate({ index: 'products', }); console.log(`CTR: ${(clickRate * 100).toFixed(1)}%, CVR: ${(conversionRate * 100).toFixed(1)}%`);
Step 5: Database-to-Algolia Sync Pipeline
// Real-time index updates from your database change events // Works with Prisma, Drizzle, Mongoose change streams, PostgreSQL LISTEN/NOTIFY import { getClient } from './algolia/client'; // Prisma middleware example prisma.$use(async (params, next) => { const result = await next(params); const client = getClient(); if (params.model === 'Product') { switch (params.action) { case 'create': case 'update': await client.saveObject({ indexName: 'products', body: { objectID: result.id, name: result.name, price: result.price, category: result.category, }, }); break; case 'delete': await client.deleteObject({ indexName: 'products', objectID: params.args.where.id, }); break; } } return result; });
Error Handling
| Issue | Cause | Solution |
|---|---|---|
is null | not set | Add to search params |
| Events not appearing in dashboard | Wrong format | Use stable, non-empty string identifiers |
| Analytics shows 0 CTR | Events not correlated | Ensure matches between search and click |
| Sync pipeline losing events | No retry on failure | Add dead-letter queue for failed updates |
Resources
Next Steps
For performance optimization, see
algolia-performance-tuning.