How to Use Algolia with Astro: Complete Guide
Step-by-step guide to integrating Algolia with your Astro website.
Algolia is a hosted search API that delivers instant, typo-tolerant search results. If you have ever used a site where search results appear as you type with zero lag, there is a good chance Algolia is behind it. For Astro sites with a lot of content, blog posts, documentation, or product listings, Algolia makes search feel effortless for your visitors.
The setup involves two parts: indexing your content (pushing data to Algolia) and building the search UI (querying Algolia from the frontend). Both are straightforward once you understand the flow.
Prerequisites
- Node.js 22.12.0 or higher (Astro 6 dropped Node 18 and 20 entirely; odd-numbered versions like v23 are unsupported)
- An Astro project (
npm create astro@latest) - An Algolia account. The free "Build" plan gives you 10,000 search requests per month, up to 1,000,000 records, and 10 indices per application
Version note (checked 2026-05-29). This guide is written against
algoliasearch5.x,instantsearch.js4.x, and Astro 6.x. The Algolia JavaScript client v5 was a breaking rewrite, so several v4-era snippets you may find elsewhere (theinitIndexpattern, default-import client) no longer work. The code below uses the v5 API.
Installation
Install the Algolia client for indexing and the InstantSearch library for the frontend:
npm install algoliasearch instantsearch.js
This pulls algoliasearch 5.x and instantsearch.js 4.x. The algoliasearch package ships both the full admin client (algoliasearch) and a search-only lite build (algoliasearch/lite), so you do not need a separate package for the frontend.
If you want to use the React version of InstantSearch (useful for interactive Astro islands):
npm install algoliasearch react-instantsearch
Note that the older react-instantsearch-hooks-web and react-instantsearch-dom packages are deprecated. npm now reports "package has moved to react-instantsearch" for both, so install react-instantsearch (7.x) and import widgets directly from it.
Configuration
Get your API keys from the Algolia dashboard under Settings > API Keys. You need:
- Application ID (public, used on frontend)
- Search-Only API Key (public, used on frontend)
- Admin API Key (private, used only for indexing)
Add them to your .env:
PUBLIC_ALGOLIA_APP_ID=your_app_id
PUBLIC_ALGOLIA_SEARCH_KEY=your_search_only_key
ALGOLIA_ADMIN_KEY=your_admin_api_key
ALGOLIA_INDEX_NAME=blog_posts
Create a script to index your content. This runs at build time or as a separate step. Note the v5 API shape. The client is a named import, initIndex no longer exists, and saveObjects is called on the client with an indexName parameter:
// scripts/index-to-algolia.ts
import { algoliasearch } from "algoliasearch";
import fs from "fs";
import path from "path";
import matter from "gray-matter";
const client = algoliasearch(
process.env.PUBLIC_ALGOLIA_APP_ID!,
process.env.ALGOLIA_ADMIN_KEY!
);
const indexName = process.env.ALGOLIA_INDEX_NAME!;
const postsDir = path.join(process.cwd(), "src/content/posts");
const files = fs.readdirSync(postsDir).filter((f) => f.endsWith(".mdx"));
const records = files.map((file) => {
const raw = fs.readFileSync(path.join(postsDir, file), "utf-8");
const { data, content } = matter(raw);
return {
objectID: data.slug || file.replace(".mdx", ""),
title: data.title,
description: data.description,
content: content.slice(0, 5000), // keep records well under the 10KB limit
tags: data.tags,
publishDate: data.publishDate,
url: `/blog/${data.slug || file.replace(".mdx", "")}`,
};
});
// v5: saveObjects takes { indexName, objects } and returns a task you can await.
const { taskID } = await client.saveObjects({ indexName, objects: records });
await client.waitForTask({ indexName, taskID });
console.log(`Indexed ${records.length} posts to Algolia`);
Run it with npx tsx scripts/index-to-algolia.ts. The waitForTask call replaces the v4 .wait() helper and blocks until Algolia finishes applying the batch, which matters if your build deploys immediately after indexing.
Basic Usage
Build a search component using InstantSearch.js. Since Algolia's search UI needs client-side JavaScript, use an Astro island with a framework component or plain JS. The code runs in the browser, so it lives inside a <script> tag, which Astro bundles and ships to the client automatically. In v5 the search-only client is a named export, liteClient, so import it aliased as algoliasearch:
---
// src/components/Search.astro
---
<div id="searchbox"></div>
<div id="hits"></div>
<script>
import { liteClient as algoliasearch } from "algoliasearch/lite";
import instantsearch from "instantsearch.js";
import { searchBox, hits } from "instantsearch.js/es/widgets";
const searchClient = algoliasearch(
import.meta.env.PUBLIC_ALGOLIA_APP_ID,
import.meta.env.PUBLIC_ALGOLIA_SEARCH_KEY
);
const search = instantsearch({
indexName: "blog_posts",
searchClient,
});
search.addWidgets([
searchBox({
container: "#searchbox",
placeholder: "Search articles...",
}),
hits({
container: "#hits",
templates: {
item: (hit) => `
<a href="${hit.url}">
<h3>${hit._highlightResult.title.value}</h3>
<p>${hit._highlightResult.description.value}</p>
</a>
`,
},
}),
]);
search.start();
</script>
Use this component anywhere in your Astro pages:
---
import Search from "../components/Search.astro";
import BaseLayout from "../layouts/BaseLayout.astro";
---
<BaseLayout title="Search">
<h1>Search</h1>
<Search />
</BaseLayout>
Production Tips
Keep your index in sync. Add the indexing script to your build process or trigger it via a webhook whenever content changes. Stale search results frustrate users more than no search at all.
Trim your records. Algolia charges based on records and operations. Only index the fields users actually search against. You do not need the full HTML body in most cases.
Use faceting for filters. Algolia supports faceted search out of the box. Configure facets on fields like tags or category in your Algolia dashboard to let users filter results without extra API calls.
Configure ranking and relevance. In the Algolia dashboard, set your searchable attributes in priority order (title first, then description, then content). This ensures titles match higher than body text matches.
Implement search analytics. Algolia provides analytics on what users search for. Use this data to identify content gaps, popular topics, and queries with zero results.
You do not need server rendering for search. All Algolia querying happens in the browser against Algolia's API, so a fully static Astro site works perfectly. Leave Astro on its default output: 'static' mode and do not reach for an adapter just to add search. Adapters and on-demand rendering are only for routes that genuinely run on the server (auth, form handlers, dynamic data). If you do run output: 'server' for other reasons, add export const prerender = true to your search page so it stays static.
Using React InstantSearch (optional)
If you prefer building the search UI as a React island instead of the plain-JS widgets above, install react-instantsearch and import the components directly from it. Note the lite client is a named import here too:
// src/components/Search.tsx
import { liteClient as algoliasearch } from "algoliasearch/lite";
import { InstantSearch, SearchBox, Hits } from "react-instantsearch";
const searchClient = algoliasearch(
import.meta.env.PUBLIC_ALGOLIA_APP_ID,
import.meta.env.PUBLIC_ALGOLIA_SEARCH_KEY
);
export default function Search() {
return (
<InstantSearch indexName="blog_posts" searchClient={searchClient}>
<SearchBox />
<Hits />
</InstantSearch>
);
}
Mount it as an Astro island with a client directive so it hydrates in the browser:
---
import Search from "../components/Search.tsx";
---
<Search client:load />
Alternatives to Consider
- Pagefind if you want a free, build-time search that requires no external service. It generates a static search index during your Astro build.
- Meilisearch if you prefer an open-source search engine you can self-host with similar instant search capabilities.
- Orama if you want a search engine that runs entirely in the browser with no backend required.
Common Errors and Fixes
client.initIndex is not a function. You are following a v4 tutorial against the v5 client. The v5 upgrade guide is explicit that initIndex no longer exists. Drop the index object entirely and call methods directly on the client with an indexName parameter, as in the indexing script above (client.saveObjects({ indexName, objects })).
algoliasearch is not a function or "module has no default export". In v5 the client is a named export, not a default. Use import { algoliasearch } from "algoliasearch" for the admin client and import { liteClient as algoliasearch } from "algoliasearch/lite" for the search-only client. The bare default import from v4 will fail.
index.saveObjects(...).wait is not a function. The chained .wait() helper was removed in v5. Capture the returned taskID and call await client.waitForTask({ indexName, taskID }) instead.
npm warns "package has moved to react-instantsearch". You installed react-instantsearch-hooks-web or react-instantsearch-dom. Both are deprecated and now redirect to react-instantsearch. Uninstall the old package and install react-instantsearch, importing InstantSearch, SearchBox, and Hits from it.
Admin key exposed in the browser bundle. Only variables prefixed with PUBLIC_ are exposed to client code in Astro, but it is easy to accidentally reference the admin key in a <script>. Keep the Admin API Key out of any client-side file. The frontend must use the search-only key (PUBLIC_ALGOLIA_SEARCH_KEY) with the lite client. The admin key belongs only in your Node indexing script.
Records rejected for being too large. Algolia enforces a per-record size limit (10KB on the Build plan). The script slices content to 5,000 characters as a safeguard. If you still hit the limit, trim more fields or split long documents into multiple records.
Astro asks you to add an adapter or set output mode for search. It should not. If you saw this error you probably added export const prerender = false or set output: 'server' somewhere unrelated. Algolia search is client-side and works on a static build. Astro's default is output: 'static', and the hybrid mode that older guides mention was removed in Astro 5, so do not configure it.
Official Docs and Examples
- InstantSearch.js getting started guide: https://www.algolia.com/doc/guides/building-search-ui/getting-started/js
- Algolia JavaScript client v5 upgrade guide: https://www.algolia.com/doc/libraries/sdk/upgrade/javascript
saveObjectsmethod reference (v5): https://www.algolia.com/doc/libraries/javascript/v5/methods/search/save-object/- React InstantSearch package and quickstart: https://github.com/algolia/instantsearch/tree/master/packages/react-instantsearch
- InstantSearch monorepo with example apps (React, Vanilla JS, Vue): https://github.com/algolia/instantsearch/tree/master/examples
- Astro on-demand rendering guide (output modes and adapters): https://docs.astro.build/en/guides/on-demand-rendering/
Wrapping Up
Algolia and Astro make a strong pair for content-heavy sites that need fast, relevant search. The indexing pipeline is simple, the search UI libraries are mature, and the free Build plan covers small to medium sites. If your visitors are searching for content and the built-in browser search is not cutting it, Algolia is the industry standard for a reason.
Sources
Verified against these sources, checked on 2026-05-29:
- algoliasearch latest version (5.53.0): https://registry.npmjs.org/algoliasearch/latest
- instantsearch.js latest version (4.99.0): https://registry.npmjs.org/instantsearch.js/latest
- react-instantsearch latest version (7.33.1): https://registry.npmjs.org/react-instantsearch/latest
- react-instantsearch-hooks-web deprecation ("package has moved to react-instantsearch"): https://registry.npmjs.org/react-instantsearch-hooks-web/latest
- Astro latest version (6.4.2): https://registry.npmjs.org/astro/latest
- Algolia JavaScript client v5 upgrade guide (initIndex removed, named import, saveObjects + waitForTask): https://www.algolia.com/doc/libraries/sdk/upgrade/javascript
- Algolia saveObjects v5 method reference: https://www.algolia.com/doc/libraries/javascript/v5/methods/search/save-object/
- InstantSearch.js getting started guide: https://www.algolia.com/doc/guides/building-search-ui/getting-started/js
- React InstantSearch README (liteClient import + InstantSearch/SearchBox/Hits): https://github.com/algolia/instantsearch/tree/master/packages/react-instantsearch
- Astro on-demand rendering docs (static default, hybrid removed, prerender flag, adapters): https://docs.astro.build/en/guides/on-demand-rendering/
- Algolia pricing (free Build plan: 10K search requests/month, 1M records, 10 indices): https://www.algolia.com/pricing
Related Articles
How to Integrate Auth0 with Astro: Complete Guide
Step-by-step guide to integrating Auth0 with your Astro website. Setup, configuration, and best practices.
How to Use AWS Amplify with Astro: Complete Guide
Step-by-step guide to integrating AWS Amplify with your Astro website.
How to Use ButterCMS with Astro: Complete Guide
Step-by-step guide to integrating ButterCMS with your Astro website.