AI-Powered Search for Static and Edge Sites
Add AI-powered search to Astro sites. Works with island hydration, static builds, and edge deployment.
Astro\'s zero-JS philosophy makes search tricky. You need something that respects static performance while delivering instant results.
Algolia pricing and complexity are designed for large apps. For a static Astro site, it's expensive overhead you don't need.
Lunr.js downloads the entire index to the client. Large content sites see multi-second load times with no typo tolerance.
Build-time indexing requires complex scripts, and there's no real-time updates when content changes in your CMS.
Drop-in search that respects Astro\'s island architecture. Hydrate only what you need, keep the rest static.
Search hydrates only the search UI island. The rest of your page stays static with zero JavaScript.
CDN-cached indexes + client-side search = zero server required. Works perfectly with astro build.
Deploys to Cloudflare Pages, Vercel Edge, and Netlify Edge. Sub-50ms search from the edge globally.
Auto-index .md and .mdx files from Astro content collections. No manual indexing scripts needed.
@searchjet/connect works anywhere JavaScript runs. Use it in Astro islands, vanilla scripts, or any component.
<10KB gzipped, only loads when the island hydrates. Your pages stay fast and lightweight.
Two approaches — Astro island or content collection indexing
---
// src/pages/search.astro
import SearchIsland from '../components/SearchIsland.tsx';
import BaseLayout from '../layouts/BaseLayout.astro';
// Pre-fetch content for SSR (optional)
const allPosts = await Astro.glob('../content/blog/*.md');
---
<BaseLayout title="Search">
<h1>Search Our Content</h1>
{/* SearchJet hydrates as an island — rest stays static */}
<SearchIsland
client:load
indexName="blog"
searchApiKey="your_search_api_key"
/>
</BaseLayout>// src/components/SearchIsland.tsx
import { SearchProvider, SearchBox, Hits, Highlight } from '@searchjet/react';
export default function SearchIsland({ indexName, searchApiKey }) {
return (
<SearchProvider indexName={indexName} searchApiKey={searchApiKey}>
<SearchBox placeholder="Search articles..." />
<Hits>
{({ hit }) => (
<article class="p-4 border-b">
<h3>
<Highlight attribute="title" hit={hit} />
</h3>
<p>
<Highlight attribute="description" hit={hit} />
</p>
<time>{hit.date}</time>
</article>
)}
</Hits>
</SearchProvider>
);
}
// Content Collection Indexing Script
// scripts/index-content.ts
import { defineConfig } from 'astro/config';
async function indexContent() {
const posts = await getCollection('blog');
const documents = posts.map(post => ({
objectID: post.slug,
title: post.data.title,
description: post.data.description,
content: post.body,
date: post.data.date.toISOString(),
tags: post.data.tags || [],
}));
await searchjet.index(documents);
console.log(`Indexed ${documents.length} posts`);
}Need a complete starter project?
View GitHub ExamplesEverything you need to know about SearchJet for Astro
Still have questions?
Contact our support teamJoin developers building exceptional search experiences with SearchJet
Already have an account? Log in
Explore more