> algolia-deploy-integration

Deploy Algolia-powered apps to Vercel, Fly.io, and Cloud Run with proper API key management and InstantSearch frontend integration. Trigger: "deploy algolia", "algolia Vercel", "algolia production deploy", "algolia Cloud Run", "algolia Fly.io", "algolia InstantSearch".

fetch
$curl "https://skillshub.wtf/jeremylongshore/claude-code-plugins-plus-skills/algolia-deploy-integration?format=md"
SKILL.mdalgolia-deploy-integration

Algolia Deploy Integration

Overview

Deploy Algolia-powered applications to production platforms with proper API key separation (Admin on backend, Search-Only on frontend) and InstantSearch widget integration.

Prerequisites

  • Algolia App ID + Admin key (backend) + Search-Only key (frontend)
  • Platform CLI installed (vercel, fly, or gcloud)
  • algoliasearch v5 for backend, react-instantsearch or instantsearch.js for frontend

Instructions

Step 1: Backend API Key Configuration

Vercel

# Environment variables in Vercel
vercel env add ALGOLIA_APP_ID production       # Your Application ID
vercel env add ALGOLIA_ADMIN_KEY production     # Admin key (server-side only)
vercel env add ALGOLIA_SEARCH_KEY production    # Search-only key (can be public)

# For client-side access (Next.js convention)
vercel env add NEXT_PUBLIC_ALGOLIA_APP_ID production
vercel env add NEXT_PUBLIC_ALGOLIA_SEARCH_KEY production

Fly.io

fly secrets set \
  ALGOLIA_APP_ID=YourApplicationID \
  ALGOLIA_ADMIN_KEY=your_admin_key \
  ALGOLIA_SEARCH_KEY=your_search_key

Google Cloud Run

# Store in Secret Manager
echo -n "your_admin_key" | gcloud secrets create algolia-admin-key --data-file=-
echo -n "your_search_key" | gcloud secrets create algolia-search-key --data-file=-

# Deploy with secrets mounted as env vars
gcloud run deploy search-service \
  --image gcr.io/$PROJECT_ID/search-service \
  --set-secrets=ALGOLIA_ADMIN_KEY=algolia-admin-key:latest,ALGOLIA_SEARCH_KEY=algolia-search-key:latest \
  --region us-central1

Step 2: Backend Search API (Next.js API Route)

// app/api/search/route.ts
import { algoliasearch } from 'algoliasearch';
import { NextRequest, NextResponse } from 'next/server';

const client = algoliasearch(
  process.env.ALGOLIA_APP_ID!,
  process.env.ALGOLIA_ADMIN_KEY!
);

export async function GET(request: NextRequest) {
  const query = request.nextUrl.searchParams.get('q') || '';
  const page = parseInt(request.nextUrl.searchParams.get('page') || '0');

  const { hits, nbHits, nbPages } = await client.searchSingleIndex({
    indexName: 'products',
    searchParams: {
      query,
      hitsPerPage: 20,
      page,
      attributesToRetrieve: ['name', 'price', 'image_url', 'category'],
      attributesToHighlight: ['name'],
    },
  });

  return NextResponse.json({ hits, totalHits: nbHits, totalPages: nbPages, page });
}

Step 3: Frontend with InstantSearch (React)

npm install react-instantsearch algoliasearch
// components/AlgoliaSearch.tsx
import { liteClient } from 'algoliasearch/lite';
import {
  InstantSearch,
  SearchBox,
  Hits,
  RefinementList,
  Pagination,
  Highlight,
} from 'react-instantsearch';

const searchClient = liteClient(
  process.env.NEXT_PUBLIC_ALGOLIA_APP_ID!,
  process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_KEY!
);

function Hit({ hit }: { hit: any }) {
  return (
    <article>
      <h3><Highlight attribute="name" hit={hit} /></h3>
      <p>${hit.price}</p>
      <p>{hit.category}</p>
    </article>
  );
}

export default function AlgoliaSearch() {
  return (
    <InstantSearch searchClient={searchClient} indexName="products">
      <SearchBox placeholder="Search products..." />
      <div style={{ display: 'flex', gap: '2rem' }}>
        <aside>
          <h4>Category</h4>
          <RefinementList attribute="category" />
          <h4>Brand</h4>
          <RefinementList attribute="brand" searchable />
        </aside>
        <main>
          <Hits hitComponent={Hit} />
          <Pagination />
        </main>
      </div>
    </InstantSearch>
  );
}

Step 4: Frontend with Vanilla InstantSearch.js

npm install instantsearch.js algoliasearch
import instantsearch from 'instantsearch.js';
import { searchBox, hits, refinementList, pagination } from 'instantsearch.js/es/widgets';
import { liteClient } from 'algoliasearch/lite';

const searchClient = liteClient('YourAppID', 'YourSearchOnlyKey');

const search = instantsearch({
  indexName: 'products',
  searchClient,
});

search.addWidgets([
  searchBox({ container: '#searchbox' }),
  hits({
    container: '#hits',
    templates: {
      item: (hit, { html, components }) => html`
        <article>
          <h3>${components.Highlight({ hit, attribute: 'name' })}</h3>
          <p>$${hit.price}</p>
        </article>
      `,
    },
  }),
  refinementList({ container: '#category-filter', attribute: 'category' }),
  pagination({ container: '#pagination' }),
]);

search.start();

Step 5: Health Check Endpoint

// app/api/health/route.ts
import { algoliasearch } from 'algoliasearch';

const client = algoliasearch(process.env.ALGOLIA_APP_ID!, process.env.ALGOLIA_ADMIN_KEY!);

export async function GET() {
  const start = Date.now();
  try {
    const { items } = await client.listIndices();
    return Response.json({
      status: 'healthy',
      algolia: {
        connected: true,
        latencyMs: Date.now() - start,
        indexCount: items.length,
      },
    });
  } catch (error) {
    return Response.json({
      status: 'degraded',
      algolia: { connected: false, error: String(error) },
    }, { status: 503 });
  }
}

Error Handling

IssueCauseSolution
NEXT_PUBLIC_ var undefinedNot set in Vercel envAdd with vercel env add
InstantSearch shows no resultsWrong Search-Only keyVerify key ACL includes search
Backend write fails on VercelUsing search key for indexingUse ALGOLIA_ADMIN_KEY (non-public)
Cold start timeoutLarge client initUse lite client where possible

Resources

Next Steps

For event tracking and analytics, see algolia-webhooks-events.

┌ stats

installs/wk0
░░░░░░░░░░
github stars1.7K
██████████
first seenMar 23, 2026
└────────────

┌ repo

jeremylongshore/claude-code-plugins-plus-skills
by jeremylongshore
└────────────