Joint session with Vercel: How to build intelligent storefronts (May 15th)

Algolia Sync Function

Official(made by Sanity team)

Automatically update your Algolia index

By Kevin Green


functions/algolia-document-sync/index.ts

import {env} from 'node:process'

import {documentEventHandler} from '@sanity/functions'
import {algoliasearch} from 'algoliasearch'

const {ALGOLIA_APP_ID = '', ALGOLIA_WRITE_KEY = ''} = env

// TODO: Allow this function to run on multiple indexes/post types (e.g. 'posts', 'products', 'events', etc.)
const ALGOLIA_INDEX_NAME = 'posts'

export const handler = documentEventHandler(async ({event}) => {
  const {_id, title, hideFromSearch, operation} = event.data

  const algolia = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_WRITE_KEY)
  if (operation === 'delete') {
    try {
      // We are assuming you already have an algolia instance setup with an index called 'posts'
      // addOrUpdateObject documentation: https://www.algolia.com/doc/libraries/javascript/v5/methods/search/delete-object/?client=javascript
      await algolia.deleteObject({
        indexName: ALGOLIA_INDEX_NAME,
        objectID: _id,
      })

      console.log(`Successfully deleted document ${_id} ("${title}") from Algolia`)
    } catch (error) {
      console.error('Error syncing to Algolia:', error)
      throw error
    }
  } else {
    try {
      // We are assuming you already have an algolia instance setup with an index called 'posts'
      // addOrUpdateObject documentation: https://www.algolia.com/doc/libraries/javascript/v5/methods/search/add-or-update-object/?client=javascript
      await algolia.addOrUpdateObject({
        indexName: ALGOLIA_INDEX_NAME,
        objectID: _id,
        body: {
          title,
          hideFromSearch, // This is an optional field that you can use to hide a document from search results
        },
      })

      console.log(`Successfully synced document ${_id} ("${title}") to Algolia`)
    } catch (error) {
      console.error('Error syncing to Algolia:', error)
      throw error
    }
  }
})

sanity.blueprint.ts

import {defineBlueprint, defineDocumentFunction} from '@sanity/blueprints'
import 'dotenv/config'
import process from 'node:process'

const {ALGOLIA_APP_ID, ALGOLIA_WRITE_KEY} = process.env
if (typeof ALGOLIA_APP_ID !== 'string' || typeof ALGOLIA_WRITE_KEY !== 'string') {
  throw new Error('ALGOLIA_APP_ID and ALGOLIA_WRITE_KEY must be set')
}

export default defineBlueprint({
  resources: [
    defineDocumentFunction({
      name: 'algolia-document-sync',
      memory: 1,
      timeout: 10,
      src: './functions/algolia-document-sync',
      event: {
        on: [
          "create",
          "update",
          "delete"
        ],
        filter: "_type == 'post'",
        projection: "{_id, title, hideFromSearch, 'operation': delta::operation()}"
      },
      env: {
        ALGOLIA_APP_ID,
        ALGOLIA_WRITE_KEY
      },
   }),
  ],
})

Keeping your search index updated is a critical component to any large site utilizing things like Algolia. This function removes some of the technical debt that might be associated to cron jobs, or even web hooks that trigger Algolia updates remotely. This function reduces that complexity by updating your index on publish, update and delete for articles, products, whatever needs to be stored in Algolia.

Quick Start

View the complete example and source code.

Initialize blueprints if you haven't already: npx sanity blueprints init

Then: npx sanity blueprints add function --example algolia-document-sync

Then deploy: npx sanity blueprints deploy

How It Works

When a content editor publishes a new blog post, the function automatically:

  • Triggers on the publish, update and delete event for post documents
  • Sends the document payload to Algolia
  • Generates a new document or updates an existing in Algolia
  • Instantly access searchable content on your frontend

Key Benefits

  • Removes technical debt with cron jobs doing similar functionality
  • Removes technical debt from serverless functions listening to web-hook updates potentially doing similar functionality
  • Keeps functionality and code closer to the source

Technical Implementation

The function syncs data to Algolia to keep your search index updated:

  • Event-driven architecture (triggers on document publish)
  • Simple, customizable implementation for different content types

Perfect For

  • Content teams uncomfortable with keeping Algolia data in sync
  • Content teams unsure of when cron jobs/content will be updated in Algolia indexes

The function is compatible with any Sanity project and can be easily customized to manage other content types, post more data to Algolia, or handle other index update requirements.

Contributor

Kevin Green

Developer at Sanity

Visit Kevin Green's profile