SazitoSazito SDKv1.2.2
Guides

Next.js Guide

App Router patterns for using Sazito SDK in both client and server contexts.

Runtime model

  • Use app/lib for shared SDK setup.
  • Use Client Components for browser interactions and token lifecycle.
  • Use Server Components for read-heavy rendering.
  • Use Server Actions for authenticated mutations.

1. Shared SDK files

// app/lib/sazito-client.ts
import { createSazitoClient } from '@sazito/client-sdk';

export const sazitoClient = createSazitoClient({
  domain: process.env.NEXT_PUBLIC_SAZITO_DOMAIN!,
  timeout: 15000,
});
// app/lib/sazito-server.ts
import { createSazitoClient } from '@sazito/client-sdk';

export function getSazitoServerClient() {
  return createSazitoClient({
    domain: process.env.SAZITO_STORE_DOMAIN!,
    timeout: 15000,
  });
}

2. Server Component example (parallel reads)

// app/[lang]/(store)/page.tsx
import { getSazitoServerClient } from '@/app/lib/sazito-server';

export default async function StorePage() {
  const client = getSazitoServerClient();

  const [productsRes, categoriesRes] = await Promise.all([
    client.products.list({ page: 1, pageSize: 12, sort: 'newest' }),
    client.categories.list({ page: 1, pageSize: 50 }),
  ]);

  if (productsRes.error || categoriesRes.error) {
    return <p>Failed to load storefront data.</p>;
  }

  return (
    <section>
      <h1>Storefront</h1>
      <p>Products: {productsRes.data?.items.length ?? 0}</p>
      <p>Categories: {categoriesRes.data?.categories.length ?? 0}</p>
    </section>
  );
}

3. Client Component example (interactive query)

// app/[lang]/(store)/search-box.tsx
'use client';

import { useState } from 'react';
import { sazitoClient } from '@/app/lib/sazito-client';

export function SearchBox() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState<any[]>([]);
  const [error, setError] = useState<string | null>(null);

  async function runSearch() {
    setError(null);

    const res = await sazitoClient.search.query(query, { page: 1, pageSize: 10 }, { timeout: 8000 });
    if (res.error) {
      setError(res.error.message);
      return;
    }

    setResults(res.data?.products.items ?? []);
  }

  return (
    <div>
      <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search products" />
      <button onClick={runSearch}>Search</button>
      {error ? <p>{error}</p> : null}
      <ul>{results.map((item) => <li key={item.url}>{item.name}</li>)}</ul>
    </div>
  );
}

4. Authenticated Server Action example

// app/[lang]/account/wallet/actions.ts
'use server';

import { cookies } from 'next/headers';
import { getSazitoServerClient } from '@/app/lib/sazito-server';

export async function getWalletBalanceAction() {
  const token = (await cookies()).get('user_id_token')?.value;
  const client = getSazitoServerClient();

  const res = await client.wallet.getBalance({
    headers: token ? { Authorization: token } : undefined,
    cache: false,
  });

  if (res.error) {
    throw new Error(res.error.message);
  }

  return res.data;
}

5. Usage in a Server Component

// app/[lang]/account/wallet/page.tsx
import { getWalletBalanceAction } from './actions';

export default async function WalletPage() {
  const wallet = await getWalletBalanceAction();
  return <pre>{JSON.stringify(wallet, null, 2)}</pre>;
}

6. Checklist

  • Keep NEXT_PUBLIC_SAZITO_DOMAIN for browser code and SAZITO_STORE_DOMAIN for server code.
  • Use Server Components for initial page payload and SEO-critical data.
  • Use Server Actions for authenticated writes and sensitive flows.
  • Always branch on res.error before using res.data.

On this page