Create Algolia i18n indices

Published on November 8, 2023 (2y ago)
Let's say we're creating an index for posts in two locales: en
and de
. We'll need to create two indices: indexName-en
and indexName-de
. Each index will contain posts in the respective locale.
1. Fetch data from Sanity for each locale
// lib/sanity.ts
import groq from 'groq'
import { createClient } from 'next-sanity'
// Hereinafter I've omitted explicit type definitions for brevity
const sanityClient = createClient({
apiVersion: process.env.SANITY_API_VERSION,
dataset: process.env.SANITY_DATASET,
projectId: process.env.SANITY_PROJECT_ID
})
const query = groq`*[_type == "post" && !(_id in path("drafts.**")] {
"objectID": _id,
"title": title[$locale],
"slug": slug.current,
}`
export async function getPostsForLocale(
locale: 'en' | 'de'
): Promise<IPost[]> {
const data = await sanityClient.fetch(query, { locale })
return data
}
2. Create a script that runs the index creation process for each locale.
// scripts/createIndex.ts
import algoliasearch from 'algoliasearch'
import { getPostsForLocale } from '@/lib/sanity'
const algoliaInstance = algoliasearch(
process.env.ALGOLIA_APP_ID!,
process.env.ALGOLIA_SEARCH_ADMIN_KEY!
)
const ALGOLIA_INDICES = [
{
indexName: 'indexName-en',
locale: 'en'
},
{
indexName: 'indexName-de',
locale: 'de'
}
]
async function createIndexForLocale(indexName, locale) {
try {
const index = algoliaInstance.initIndex(indexName)
const data = await getPostsForLocale(locale)
await index.saveObjects(indexData)
console.log(
`Saved ${data.length} docs to index: ${index.indexName}`
)
return {
status: 200,
body: 'Success!'
}
} catch (error) {
console.error(error)
return {
status: 500,
body: error
}
}
}
export default async function createIndex() {
const promises = ALGOLIA_INDICES.map(({ indexName, locale }) =>
createIndexForLocale(indexName, locale)
)
const results = await Promise.all(promises)
return results
}
3. Create a route handler to run the script
// api/cron/route.ts
import createIndex from '@/scripts/createIndex'
export async function GET(req: Request) {
if (
req.headers.get('Authorization') !==
`Bearer ${process.env.CRON_SECRET}`
) {
return new Response(`Unauthorized`, { status: 401 })
}
try {
await generateIndex()
return new Response('Algolia index re-created', {
status: 200
})
} catch (e) {
const serializedError =
e instanceof Error
? JSON.stringify(e, Object.getOwnPropertyNames(e))
: 'Unknown error'
return new Response(serializedError, { status: 500 })
}
}
4. Setup Cron Job
Create a vercel.json
file in your project's root directory
{
"crons": [
{
"path": "/api/cron",
"schedule": "0 0 * * 0"
}
]
}
Cron is scheduled to run every Sunday at midnight. You can use crontab.guru to generate your own schedule.
5. Deploy to Vercel and test it out by running cron manually.

💡
Alternatively, you can choose to omit steps 3-5 and execute the script from step 2 directly as part of the build process.