Next.js SDK

TypeScript client for Next.js App Router, Server Components, and edge runtime.

The Next.js SDK is a TypeScript-first client built around the App Router. It's safe to call from Server Components, supports streaming through RSC, and runs on the edge runtime when you need search results close to the user.

# Install

npm install @skryx/nextjs
# or: pnpm add @skryx/nextjs / yarn add @skryx/nextjs

# Configure

Add your API key to .env.local:

SKRYX_API_KEY=sk_live_xxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_SKRYX_PUBLIC_KEY=pk_live_xxxxxxxxxxxxxxxxxxxx
  • SKRYX_API_KEY — server-only (search-scoped). Used in Server Components, Route Handlers, Server Actions.
  • NEXT_PUBLIC_SKRYX_PUBLIC_KEY — exposed to the browser, used by the widget script tag.

# Server Component query

import { skryx } from '@skryx/nextjs';

export default async function SearchPage({ searchParams }: { searchParams: { q?: string } }) {
  const query = searchParams.q ?? '';
  const results = await skryx.index('products').search({
    query,
    limit: 20,
    facets: ['category', 'brand'],
  });

  return (
    <main>
      <h1>{results.total} results for "{query}"</h1>
      <ul>
        {results.hits.map((h) => (
          <li key={h.id}>{h.title}</li>
        ))}
      </ul>
    </main>
  );
}

# Route Handler example

// app/api/search/route.ts
import { NextResponse } from 'next/server';
import { skryx } from '@skryx/nextjs';

export async function GET(req: Request) {
  const { searchParams } = new URL(req.url);
  const query = searchParams.get('q') ?? '';
  const results = await skryx.index('products').search({ query });
  return NextResponse.json(results);
}

Add export const runtime = 'edge' to run on Vercel Edge / Cloudflare Workers — the SDK has zero Node.js-only dependencies.

# Streaming results

For long result sets (200+ hits), stream with RSC:

import { Suspense } from 'react';
import { skryx } from '@skryx/nextjs';

async function Results({ query }: { query: string }) {
  const results = await skryx.index('products').search({ query, limit: 200 });
  return <ResultList hits={results.hits} />;
}

export default function Page({ searchParams }: { searchParams: { q?: string } }) {
  return (
    <main>
      <SearchHeader />
      <Suspense fallback={<ResultsSkeleton />}>
        <Results query={searchParams.q ?? ''} />
      </Suspense>
    </main>
  );
}

# TypeScript

Index document shapes are inferred from a schema definition:

import { defineIndex } from '@skryx/nextjs';

const products = defineIndex<{
  id: string;
  title: string;
  price: number;
  brand: string;
  in_stock: boolean;
}>('products');

const { hits } = await products.search({ query: 'sony' });
hits[0].title;   // ✓ typed
hits[0].price;   // ✓ typed
hits[0].missing; // ✗ type error

# Widget vs SDK

Same advice as the Laravel SDK page — widget for the shopper-facing UI, SDK for server-side and custom search pages. Most apps use both.

# Versioning

Major versions of the SDK track Skryx REST API majors. Patches within a major are backward-compatible.

esc