---
title: "Implementing Algolia SSR in Next.js App Router"
url: https://monogram.io/blog/integrating-algolia-with-ssr-in-next-js-app-router
description: "Learn how to implement robust search functionality in a Next.js app using Algolia and server-side rendering (SSR)."
date: 2024-07-26
authors: ["Drayke"]
---

# Integrating Algolia with SSR in Next.js App Router

**Published:** Jul 26, 2024 | **Authors:** Drayke, Engineer

---

Implement Algolia search with SSR in your Next.js app. Install, sync content, and integrate instant search for fast, responsive results.

To introduce search functionality to the Monogram blog, we prioritized implementing a robust search solution capable of handling our expanding content efficiently. After careful evaluation, we chose Algolia for its speed, relevance, and seamless integration capabilities. By integrating Algolia with Next.js using server-side rendering (SSR), we ensure a fast, responsive search experience with quick load times. Here's a guide on how we achieved this.

## Adding our content to Algolia

**Step 1: Install and Initialize Algolia Client**
First, install the Algolia search client and Initialize it using your Algolia API credentials:

```
import algoliasearch from 'algoliasearch'

const algoliaClient = algoliasearch(
	process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,
	process.env.ALGOLIA_WRITE_API_KEY
)
```

**Step 2: Create a Script to Synchronize Content
**To keep your Algolia index up-to-date with your content, create a script for indexing. This involves:

Fetching Content: Retrieve your content from your CMS.

Preparing Batch Operations: Create batch operations to add or delete records from the index.

Executing the Batch Request: Send the batch request to Algolia to update the index.

```
import algoliasearch from 'algoliasearch'

const algoliaClient = algoliasearch(
  process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,
  process.env.ALGOLIA_WRITE_API_KEY
)

async function reIndexBlog() {
  const index = algoliaClient.initIndex(process.env.NEXT_PUBLIC_ALGOLIA_BLOG_INDEX)
  const blogPosts = await getBlogPosts()
  
  const algoliaBatchContent = blogPosts.map(post => ({
    action: 'addObject',
    body: {
      objectID: post.id,
      // Add other fields as necessary
    },
  }))
  
  let algoliaObjectIds = []
  
  await index.browseObjects({
    attributesToRetrieve: ['objectID'],
    batch: batch => {
      algoliaObjectIds = algoliaObjectIds.concat(batch.map(hit => hit.objectID))
    }
  })
  
  const postsToDeleteFromAlgolia = algoliaObjectIds.filter(
    objectID => !blogPosts.some(post => post.id === objectID)
  )
  
  postsToDeleteFromAlgolia.forEach((objectID) => {
		algoliaBatchContent.push({
			action: 'deleteObject',
			body: { objectID },
		})
	})
  
  const { taskID } = await index.batch(algoliaBatchContent)
  await index.waitTask(taskID)
}
```

In this script:

`algoliaBatchContent`: Prepares the content to be added or updated in the index.

`algoliaObjectIds`: Collects the IDs of the objects currently in the index.

`postsToDeleteFromAlgolia`: Determines which posts need to be removed from the index by comparing IDs in Algolia that are no longer in our CMS.

`index.batch()`: Executes the batch operation to update the index.

**Step 3: Set Up Re-Index Webhook with Next.js API Routes
**We use Next.js API routes to handle re-indexing via webhooks from our CMS. When a blog post is created or updated a `POST` request is sent to our API route with the data of the post that was created or updated. Here’s the simplified version:

```
import algoliasearch from 'algoliasearch'
import { normalizeAlgoliaBlogPost } from '@/src/lib/algolia/normalize'

const algoliaBlogIndex = process.env.NEXT_PUBLIC_ALGOLIA_BLOG_INDEX

const secret = process.env.WEBHOOK_SECRET
const algolia = algoliasearch(
	process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,
	process.env.ALGOLIA_WRITE_API_KEY
)
const algoliaClient = algolia.initIndex(algoliaBlogIndex)

export async function POST(req: Request) {
	// Verify webhook secret
	const webhookSecret = req.headers.get('webhook-secret')

	if (webhookSecret !== secret) {
		const message = 'Invalid webhook secret'
		return new Response(message, { status: 401 })
	}

	const post = (await req.json())

	if (!post) {
		const message = 'No post found in request body'
		return new Response(message, { status: 400 })
	}

	try {
		await algoliaClient.saveObject(normalizeAlgoliaBlogPost(post))

		return new Response(
			`✅ "${post.title}" blog post was added/updated in Algolia index: "${algoliaBlogIndex}"`,
			{ status: 200 }
		)
	} catch (error) {
		const message = error instanceof Error ? error.message : String(error)

		return new Response(message, { status: 500 })
	}
}

```

## Integrating Instant Search with Next.js

**Step 1: Install Required Libraries
**Install `react-instantsearch` and `react-instantsearch-nextjs`

```bash
npm install react-instantsearch react-instantsearch-nextjs
```

**Step 2: Create a Layout Component for Search Context**
Create a layout component that provides the Algolia search context to your components:

```
'use client'

import algoliasearch from 'algoliasearch/lite'
import { InstantSearchNext } from 'react-instantsearch-nextjs'

const searchClient = algoliasearch(
  process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,
  process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_API_KEY
)

export default function BlogLayout({ children }) {
  return (
    <InstantSearchNext
      indexName={process.env.NEXT_PUBLIC_ALGOLIA_BLOG_INDEX}
      searchClient={searchClient}
    >
      {children}
    </InstantSearchNext>
  )
}
```

**Step 3: Build Search Components**
The `SearchBox` Component Handles user input and updates the search query.

```
'use client'

import { useRef, useState } from 'react'
import { useSearchBox } from 'react-instantsearch'

export default function SearchBox() {
  const { query, refine } = useSearchBox()
  const [inputValue, setInputValue] = useState(query)
  const inputRef = useRef<HTMLInputElement>(null)

  function setQuery(newQuery: string) {
    setInputValue(newQuery)
    refine(newQuery)
  }

  return (
    <form role="search" onSubmit={event => event.preventDefault()}>
      <input
        ref={inputRef}
        autoComplete="off"
        autoCorrect="off"
        autoCapitalize="off"
        placeholder="Search our knowledge..."
        spellCheck={false}
        type="search"
        value={inputValue}
        onChange={event => setQuery(event.currentTarget.value)}
      />
    </form>
  )
}
```

The `BlogFeed` Component Displays search results retrieved from Algolia.

```
'use client'

import Link from 'next/link'
import { useHits } from 'react-instantsearch'

export default function BlogFeed() {
  const { results } = useHits()

  if (!results) return null

  return (
    <div>
      {results.hits.map(hit => (
        <Link key={hit.objectID} href={`/blog/${hit.slug}`}>
          <time dateTime={hit.publishedDate}>{hit.publishedDate}</time>
          <h3>{hit.title}</h3>
          <p>{hit.excerpt}</p>
        </Link>
      ))}
    </div>
  )
}
```

**Step 4: Integrate Components into the Blog Home Page**
Combine the `SearchBox` and `BlogFeed` components into your blog's home page:

```
import SearchBox from '@/components/blogSearch/SearchBox'
import BlogFeed from '@/components/blogSearch/BlogFeed'

export default function BlogHome() {
  return (
    <>
      <SearchBox />
      <BlogFeed />
    </>
  )
}
```

By integrating Algolia with Next.js, we have built a powerful search experience for the Monogram blog. The use of server-side rendering (SSR) ensures that users receive a fast and relevant search experience from the start. Client-side components then handle dynamic interactions, ensuring that search results are updated in real-time.

## Contact Us

[Build what comes next](https://monogram.io/#contact) | Email: [hello+llm@monogram.io](mailto:hello+llm@monogram.io)

Provide your contact details and claim a time to meet. We'll help you do the rest.

Monogram is an Applied AI Studio based in Atlanta that designs and deploys production AI systems — connecting models, data, workflows, and enterprise software to automate real work.

The contact form collects: name, email, company, estimated budget (USD), a project description, and how you heard about Monogram.

Not sure where to start? Tell us what you're trying to automate or build — we'll help you figure out where AI fits.


---

**More content:** [Home](/.md) | [About](/about.md) | [Work](/work.md) | [Engineering](/engineering.md)

Monogram helps companies, organizations, and firms adopt AI by designing and building proof of concepts (POCs), MVPs, intelligent workflows, and production-ready AI applications.

Website designed and developed by [Monogram](https://monogram.io)