惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Project Zero
Project Zero
WordPress大学
WordPress大学
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
Visual Studio Blog
爱范儿
爱范儿
P
Proofpoint News Feed
F
Fortinet All Blogs
雷峰网
雷峰网
小众软件
小众软件
Jina AI
Jina AI
人人都是产品经理
人人都是产品经理
TaoSecurity Blog
TaoSecurity Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Secure Thoughts
Recent Commits to openclaw:main
Recent Commits to openclaw:main
博客园 - 司徒正美
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
S
Security @ Cisco Blogs
Help Net Security
Help Net Security
GbyAI
GbyAI
Webroot Blog
Webroot Blog
T
Troy Hunt's Blog
B
Blog
MongoDB | Blog
MongoDB | Blog
月光博客
月光博客
H
Heimdal Security Blog
Google Online Security Blog
Google Online Security Blog
S
Security Affairs
云风的 BLOG
云风的 BLOG
Engineering at Meta
Engineering at Meta
www.infosecurity-magazine.com
www.infosecurity-magazine.com
H
Help Net Security
O
OpenAI News
H
Hacker News: Front Page
博客园 - 叶小钗
Last Week in AI
Last Week in AI
S
Schneier on Security
The Last Watchdog
The Last Watchdog
C
Cyber Attacks, Cyber Crime and Cyber Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
MyScale Blog
MyScale Blog
Recorded Future
Recorded Future
博客园 - 【当耐特】
V
Vulnerabilities – Threatpost
大猫的无限游戏
大猫的无限游戏
N
News | PayPal Newsroom
The Hacker News
The Hacker News
A
Arctic Wolf

Sanity.io

A Board Game agent built using Sanity Context and Vercel's AI SDK | Sanity Build a prototype with Claude Code that your whole team can edit | Sanity What’s New - May 2026 | Sanity I built a London pub guide with v0 and the Sanity MCP in six hours. Here's what I learned. | Sanity Build a conference concierge with Agent Context and Anthropic | Sanity Build a content-aware Telegram agent with Vercel AI SDK and Chat SDK | Sanity How I used Agent API to generate photos for my family’s recipes | Sanity What’s New April - 2026 | Sanity Better context, better matches: An AI love story (for dogs) | Sanity How to write for an agent | Sanity Content Agent, meet Slack: AI content operations in your workflow | Sanity Structure powers intelligence | Sanity Your agent needs better content. Here's how to give it. | Sanity How to serve content to agents (a field guide) | Sanity Sanity TypeGen GA: Automatic TypeScript types for content and GROQ | Sanity Sanity is now available on the Vercel Marketplace | Sanity The logo soup problem (and how to solve it) | Sanity Content Releases: From scattered updates to coordinated publishing | Sanity What's New - February 2026 | Sanity How we solved the agent memory problem | Sanity v0 Builder Challenge: The winners | Sanity Introducing: Sanity Agent Skills | Sanity Content Agent: Days of work in one conversation | Sanity Our Sanity Values | Sanity Open Source Pledge 2025: Stepping up when it matters | Sanity v0 builder challenge: $3000 in prizes | Sanity Why AI Breaks Without Structured Content Operations | Sanity What’s New January - 2026 | Sanity BFCM 2025: What teams built when infrastructure stopped being the problem | Sanity How AI shaped holiday shopping and what it means for content in 2026 | Sanity Sanity Studio v5: Embracing React 19 | Sanity You’ll need a CMS eventually. Let your agent set it up. | Sanity “You should never build a CMS” | Sanity AI Content Operations: A 30-Day Implementation Guide | Sanity What’s New December - 2025 | Sanity Scheduled Drafts: Stop manually publishing content at midnight | Sanity What’s New November - 2025 | Sanity Everything *[NYC] 2025 recap: A day of AI, Content Operations, and Culture | Sanity Clankers and content operations | Sanity Content Agent: AI that understands your structured content is here | Sanity Why design-driven content modeling creates technical debt, not velocity | Sanity What's New October - 2025 | Sanity From studio to inbox: How Kevin Green eliminated email campaign friction | Sanity The content editor's guide to content operations [E-commerce edition] | Sanity styled-components maintenance mode: A 40% faster fork | Sanity From zero code to a live website in 7 hours (thanks, Cursor!) | Sanity First attempt will be 95% garbage: A staff engineer's 6-week journey with Claude Code | Sanity Internationalization is more than translating words | Sanity What's New - September 2025 | Sanity We just deleted our 35k-member community Slack | Sanity What's New - August 2025 | Sanity The engineer's guide to content operations [E-commerce edition] | Sanity SEO for AI: Evolving from Web Pages to the Content Lake | Sanity What's New - July 2025 | Sanity Sanity Studio v4: A major version bump for a minor reason | Sanity What's New - June 2025 | Sanity Dashboard and Insights: Your New Content HQ | Sanity Canvas: AI-accelerated, context-aware, freeform authoring | Sanity Agent Actions: AI building blocks for structured content | Sanity Functions: Life beyond pressing publish | Sanity A new era for content applications with Sanity App SDK | Sanity The end of CMS era and our $85M Series C. | Sanity What's New – May 2025 | Sanity Introducing the Sanity Model Context Protocol (MCP) server | Sanity What's New – April 2025 | Sanity Pushing all the envelopes with ambitious content | Sanity Self-hosting is only free if your time is worth nothing | Sanity Content that lasts: Scaling beyond your frontend | Sanity The Live Content API is now Generally Available | Sanity The future beyond AI chat bots | Sanity Learning the new skill of working with AI | Sanity What's New - March 2025 | Sanity Give it in plain text: Making your content AI-Ready | Sanity No More 'DO NOT PUBLISH': Introducing Content Releases | Sanity React in 2025, what's next? | Sanity The final boss of front-end: block editors | Sanity Introducing Sanity for Startups | Sanity A block content editor that loves you back | Sanity A Black Friday Snooze Fest: Massive Traffic, No Drama | Sanity How to make a recipe site that scales well | Sanity The Sanity Winter Release 2024 | Sanity AVIF Arrives, Sanity’s Promise Fulfilled | Sanity Sanity joins the Open Source Pledge | Sanity Your content is now Live by default | Sanity Begin Team to Join Sanity | Sanity Sanity Digest - September '24 Edition | Sanity Sanity partners with Google. Now live on the Google Cloud Marketplace. | Sanity Sanity Digest - August ‘24 Edition | Sanity Now playing: the latest Mux Video Input plugin for Sanity | Sanity Community Digest - June ‘24 Edition | Sanity Community Digest - May ‘24 Edition | Sanity Guide to Sanity's newest product announcements | Sanity AI and Content Creation: A Leader's Guide | Sanity Of course, you should be able to type your content quickly! | Sanity New to AI Assist: translation, reference suggestions, image generation | Sanity Speak the language of your editors: Sanity Studio UI localization | Sanity Introducing the new Sanity Growth plan to serve collaborative teams | Sanity Presentation: Work faster than ever with structured content | Sanity Goodbye Feedback Frenzy, Hello Sanity Studio Comments! | Sanity Easing into the App Router with the Sanity Toolkit for Next.js | Sanity
Indexing in Algolia using serverless functions (and observables!) | Sanity
Knut Melvær · 2018-11-21 · via Sanity.io

2021-03-30: This article uses Webtask which now has been sunset. You can still read it to learn how to use observables in serverless functions. However, we recommend using our Sanity-Algolia toolkit for indexing content from your Sanity Content Lake in Algolia.

<Movie trailer voice>

In a world where monoliths break up, devs build new exciting services with towering JAMstacks, serverless functions, and epic cloud services. Yet they face one challenge: Moving data from one service to another. Introducing Observables. The code pattern that takes streams of data, mutate it to your liking, and pipe it effortlessly to another place. Coming soon to a code editor near you.

</Movie trailer voice>

With Sanity’s powerful export API it's easy to make a small serverless function in order to index all your content in Algolia for the times you want to harness its search capabilities. It's also a nice way to learn about observables in JavaScript.

Algolia is a powerful search-as-a-service that makes it easy to provide weighted searches, statistics, and rich user interfaces for search for your frontends. Webtask by Auth0 is a service that makes it easy to build serverless functions right in the browser. In this tutorial we will look closer on how we can use Sanity’s export API to quickly get the content you want to index into Algolia using a scheduled serverless function.

Sanity + Webtask + Algolia = Heart
Sanity + Webtask + Algolia = 💖

Setting up Algolia and getting some API keys

First you'll have to sign up for an account at Algolia. It should be pretty straightforward. Once you've set up an account go to API keys in the sidebar. You should be able to do this tutorial on the free plan, but note that there are some limits that may kick in at some point.

App ID and API Keys in Algolia
App ID and API Keys in Algolia

Have the keys available, because we're going to need them when we set up our serverless function.

Setting up a serverless function on webtask.io

There are many great services for setting up serverless functions: begin.com, code.xyz, Netlify functions, AWS Lambda, Now, Google Cloud Functions, the list could go on. For this tutorial we'll use webtask.io because it easy to set up, runs in the browser, and has scheduling as a feature. It shouldn't be too much work adapting this code to other services though.

Add secret tokens

Go to webtask.io/make, log in and make a new function from an empty template. Go to the 🔧wrench menu and choose secrets and Add Secret.

Choose secrets in the 🔧 menu
Choose secrets in the 🔧 menu

Call your "secret key" ALGOLIA_TOKEN and copy-paste your Admin API Key from Algolia into the "secret value" field. In other words: You should be careful with where you save this. This key will now be available under context.secrets.ALGOLIA_TOKEN in your function.

What is a serverless function?

A serverless function often looks like this code snippet. It is a function that takes two parameters, one of the HTTP request and additional information (e.g. secret keys stored in the function-as-a-service), and a callback or response function that you run at the end to return whatever feedback or data that the function needs to return. Different services allow for different programming languages, so serverless functions can also be written in for example Python, Java, or Go. In this tutorial, we'll use JavaScript in a Node.js environment.

In Webtask you call the callback function with two parameters, the second parameter is what you'll return when someone calls your function, it can be an HTTP status code (200 for OK, 500 for error), a string, or even an object.

A serverless function often have a limited execution time. That means that whatever it does, it has be done within the time limit of the service. Sometimes it's 30 seconds, or up to 15 minutes. That means that serverless functions are best suited for single quick tasks. To index all your content may not sound like such, but Sanity’s export API is so quick it takes only a couple of seconds. So without further ado, let’s dive into it!

Setting up the Algolia connection

First, we must make it possible for the function to connect to our index in Algolia.

Webtask will show a '+'-mark left of the line numbers when you add a 'require'-statement, click this to import the npm module you specified. You can also add NPM-modules via the wrench menu.

Setting up the Sanity connection

While we could have used the Sanity JavaScript client and used GROQ to get some content, we will use the export API for this function. The export API will stream all your public content in a ndjson-format, and do it very quickly in just one API call.

Preparing an observable for streaming contents

The export API can end up delivering lots of data and does that via a stream. In many cases, we could probably write all this data to memory (i.e. a variable) and then send it to Algolia, but a more robust and scalable pattern is to do it in a stream using something called Observables. To do that we'll use a library called RxJS (that we use extensively at Sanity). We'll start by converting the Algolia client’s saveObjects-method (which is callback-based) to a function that returns an Observable using a function in RxJS called bindNodeCallback.

Adding the observable pipeline

Now the fun stuff! First, we have to import the methods we need to pipe the stream we get from the export API into Algolia. The thinking is that we want to get all the data, do some manipulation and pick out what we want to index, and then ship updates to Algolia in batches. When the job is done, we want the function to return with a message of how many documents it updated, and how many batches. The end result will look like this:

Let's zoom in and look closer of what's going on here.

Initially, we set up the request to the export API URL with request(sanityExportURL), this will return a node stream of delineated JSON objects which we pipe to ndjson() that transforms the data in to and emits it to objects.

This stream of objects is then transformed to a RxJS stream that is piped to the map operator. The map operator passes each object to a function. Here we use parameter destructuring to pick out those fields we want, and build a new object using Object.assign (we could have used ES6 spread syntax, but the node environment in Webtask doesn't seem to have those yet).

Not all objects that are apassed to this function will have all the keys, and will be undefined. Notice that I have defaulted the array fields since they are sent to a function (there are probably many other ways we could have dealt with this). At the bottom of this file we add a small helper function that takes structured text from Sanity and transforms it into a simple text string. We declare it as a function in order to hoist it, so that it can be used above.

The subsequent arguments in the pipe-method are bufferCount that collects the objects from map and passes them on when the specified number is met (100). We use mergeMap to pass each chunk to the partialUpdateObjects function, one by one. It will wait for async operations (like passing data to Algolia) and return the response. Finally, we collect them all in an array in toArray(). so that we can count them and return the summary of how the job went.

We use subscribe to receive the emitted array of arrays with all the objects, and sum up all the objects with reduce. At the end, we call the callback-function that is passed with the serverless function and return a string with how many documents we updated, and how many batches it took.

Scheduling the serverless function

Of course, we can run this function manually by requesting the URL that is displayed at the bottom of the Webtask UI. You should keep this URL secret since you don't want anyone to just trigger a reindexing (the function in the screenshots is deleted). But syncing your search indexes is a great example of something that should be done automatically. You can also add this URL to a webhook, so that it runs every time something updates (it's done after a couple of seconds), but that's probably overkill, and will most likely burn up your quota. So that's where scheduling comes in. If you again open the wrench menu and choose Scheduler, you'll open a panel where you can select the time span for repeating the function. It should be as often as seems sensible, depending on how much your content changes. You can of course still trigger the indexing manually by calling the URL.

Scheduler in Webtask
Scheduler in Webtask

Let's take a step back…

What you have done now is pretty awesome: In less than 60 lines of code you have set up a serverless function that streams all your content from Sanity with one API call, manipulates each document and passes it on to another service. And it can do that with a lot of content only taking a couple of seconds. In this case, we experimented with Algolia, but there's probably a ton of other use cases that can be adapted from this setup. We can't wait to hear about them – so feel free to tells us on your own blog, on twitter, and in our community Slack.