
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI can see from the error you're encountering that you're using the sanity-algolia package, which is actually no longer the recommended approach for integrating Algolia with Sanity. The package has been deprecated because both Sanity webhooks and the Algolia client have improved significantly since it was created, making the package unnecessary.
The error Cannot read property 'created' of undefined is occurring because the deprecated package expects a specific payload structure that doesn't match modern webhook implementations. The GitHub repository explicitly states: "Both Sanity webhooks and the Algolia client have significantly improved since the sanity-algolia package was originally released, so much so that the package is no longer necessary."
Instead of using the sanity-algolia package, you should integrate Algolia directly using either:
Sanity Functions are the modern, serverless compute solution built into Sanity. They're perfect for this use case because they run on Sanity's infrastructure and can react to document changes automatically:
// sanity.blueprint.ts
import { defineBlueprint } from 'sanity'
import algoliasearch from 'algoliasearch'
const client = algoliasearch(
process.env.ALGOLIA_APP_ID!,
process.env.ALGOLIA_ADMIN_KEY!
)
const index = client.initIndex('your_index_name')
export default defineBlueprint({
functions: {
algoliaSync: {
on: 'document.create,document.update,document.delete',
filter: '_type in ["post", "page"]', // Specify your document types
handler: async ({ event, sanityClient }) => {
const { _id, operation } = event
if (operation === 'delete') {
await index.deleteObject(_id)
return { success: true, action: 'deleted' }
}
// Fetch the full document with the fields you need
const document = await sanityClient.fetch(
`*[_id == $id][0]{
objectID: _id,
title,
slug,
content,
// Add other fields you want to index
}`,
{ id: _id }
)
if (document) {
await index.saveObject(document)
return { success: true, action: 'indexed' }
}
return { success: false, reason: 'document not found' }
}
}
}
})If you prefer to keep using your Next.js API route approach, modernize it by using GROQ-powered webhooks and the Algolia JavaScript client directly:
// pages/api/algolia-sync.js (or app/api/algolia-sync/route.ts for App Router)
import algoliasearch from 'algoliasearch'
import { createClient } from '@sanity/client'
import { isValidSignature, SIGNATURE_HEADER_NAME } from '@sanity/webhook'
const algolia = algoliasearch(
process.env.ALGOLIA_APP_ID,
process.env.ALGOLIA_ADMIN_KEY
)
const index = algolia.initIndex('your_index_name')
const sanityClient = createClient({
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
apiVersion: '2024-01-01',
useCdn: false
})
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ message: 'Method not allowed' })
}
// Verify webhook signature
const signature = req.headers[SIGNATURE_HEADER_NAME]
const isValid = isValidSignature(
JSON.stringify(req.body),
signature,
process.env.SANITY_WEBHOOK_SECRET
)
if (!isValid) {
return res.status(401).json({ message: 'Invalid signature' })
}
try {
const { _id, operation, value } = req.body
// Handle delete operation
if (operation === 'delete') {
await index.deleteObject(_id)
return res.status(200).json({ success: true, action: 'deleted' })
}
// For create/update, the value from the webhook projection contains the data
if (value) {
await index.saveObject(value)
return res.status(200).json({ success: true, action: 'indexed' })
}
return res.status(400).json({ error: 'No value provided' })
} catch (error) {
console.error('Algolia sync error:', error)
return res.status(500).json({ error: error.message })
}
}In your Sanity webhook settings, configure:
Filter:
_type == 'post'Projection:
{
"transactionId": _rev,
"projectId": sanity::projectId(),
"dataset": sanity::dataset(),
_id,
"operation": delta::operation(),
"value": {
"objectID": _id,
"title": title,
"slug": slug.current,
"body": pt::text(content),
"_type": _type,
"coverImage": coverImage.asset->url,
"date": date,
"_createdAt": _createdAt,
"_updatedAt": _updatedAt
}
}npm uninstall sanity-algolianpm install algoliasearch @sanity/webhookThe sanity-algolia package served its purpose when it was created, but the ecosystem has evolved. The direct integration approach gives you more flexibility and uses current best practices for both Sanity and Algolia. You can find a complete implementation guide in the official Sanity + Algolia guide and reference implementation in the sanity-algolia repository.
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store