examples/functions/algolia-document-sync/README.md
Content teams need to keep their search functionality up-to-date with their latest content, but manually syncing content to search indexes is time-consuming and error-prone. This creates a gap between published content and searchable content.
This Sanity Function automatically syncs documents to Algolia's search index, ensuring your search functionality always reflects your latest content. When a post is published, the function sends the document data to Algolia, either creating a new search record or updating an existing one. We also track when documents are updated and deleted, using the delta operation our function can remove an item from Algolia under the delete operation. We could selectively update for create vs update but for now we pass the same addOrUpdate to Algolia.
This function is built to be compatible with any of the official "clean" templates. We recommend testing the function out in one of those after you have installed them locally.
Important: Run these commands from the root of your project (not inside the studio/ folder).
Initialize the example
Run this if you haven't initialized blueprints:
npx sanity blueprints init
You'll be prompted to select your organization and Sanity studio.
Then run:
npx sanity blueprints add function --example algolia-document-sync
Add configuration to your blueprint
// sanity.blueprint.ts
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')
}
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_APP_ID,
ALGOLIA_WRITE_KEY: ALGOLIA_WRITE_KEY,
},
})
Install dependencies
Install dependencies in the project root:
npm install dotenv
Set up environment variables
Add your Algolia credentials to your root .env file:
ALGOLIA_APP_ID: Your Algolia application IDALGOLIA_WRITE_KEY: Your Algolia write API keyYou can test the algolia-document-sync function locally using the Sanity CLI before deploying:
This function writes directly to Algolia, so we can test locally with our document.json without relying on any Sanity schema.
Test with the included sample document:
npx sanity functions test algolia-document-sync --file functions/algolia-document-sync/document.json --dataset production --with-user-token
Start the development server for interactive testing:
npx sanity functions dev
Test with your own document data:
npx sanity functions test algolia-document-sync --data '{
"_type": "post",
"_id": "test-post",
"title": "Test Article"
}' --dataset production --with-user-token
Capture a real document from your dataset:
# From the studio/ folder export a real document for testing
cd studio
npx sanity documents get "your-post-id" > ../test-document.json
# Back to project root for function testing
cd ..
npx sanity functions test algolia-document-sync --file test-document.json --dataset production --with-user-token
To see detailed logs during testing, modify the function temporarily to add logging:
// Add debugging logs
console.log('Event data:', JSON.stringify(event.data, null, 2))
console.log('Syncing to Algolia:', data._id)
npx sanity documents query to find suitable test documentspost document type containing:
title field to sync to AlgoliaWhen a content editor publishes a blog post, the function automatically:
Sample input document:
{
"_type": "post",
"_id": "test-post-123",
"title": "My First Blog Post",
"slug": {
"current": "my-first-blog-post"
},
"body": "This is the content of my first blog post.",
"author": {
"_type": "reference",
"_ref": "author-123"
},
"publishedAt": "2024-01-15T10:00:00.000Z",
"hideFromSearch": false
}
Result: The document is synced to Algolia's search index, making it immediately searchable.
Update the fields sent to Algolia by modifying the object in addOrUpdateObject:
await algolia.addOrUpdateObject({
indexName: 'posts',
objectID: _id,
body: {
title,
slug: data.slug?.current,
publishedAt: data.publishedAt,
// Add more fields as needed
},
})
Modify the index name to sync to a different Algolia index, alternatively pass _type into the projection so you can sync to indexes based on the post type, allowing one function to update many indexes:
await algolia.addOrUpdateObject({
indexName: 'your-custom-index', // Different index name
objectID: _id,
body: {
title,
},
})
Update the filter to sync specific document types or conditions:
filter: "_type == 'post' && defined(publishedAt)"