Augur

Getting started

Set up a Next.js or React Native site on the augur packages: install, theme, site config, providers, auth and SSR prefetch.

Getting started

Install

A Next.js site:

pnpm add @simpleapps-com/augur-api @simpleapps-com/augur-core @simpleapps-com/augur-utils \
  @simpleapps-com/augur-hooks @simpleapps-com/augur-server @simpleapps-com/augur-web \
  @simpleapps-com/augur-tailwind
pnpm add -D @simpleapps-com/augur-config

A React Native (Expo) app needs only the cross-platform packages: @simpleapps-com/augur-api, @simpleapps-com/augur-hooks and @simpleapps-com/augur-utils. It brings its own UI components and persistence.

Each package lists the peers it needs (React 19, TanStack Query 5, Zustand 5, Next.js 16, NextAuth 5, Tailwind 4, …) in its peerDependencies; the package pages give them too. Every package releases on its own CalVer schedule, so install each at its latest.

Theme

/* app/globals.css */
@import "tailwindcss";
@import "@simpleapps-com/augur-tailwind/base.css";
@plugin "tailwindcss-animate";

@theme {
  --font-sans: "Montserrat", sans-serif;
}

:root {
  --primary: 206 76% 42%; /* your brand color */
}

No tailwind.config.ts is needed: Tailwind 4 is configured in CSS and finds content sources itself. See augur-tailwind for every variable.

Site config and server site

// lib/augur-config.ts
import { defineSite } from "@simpleapps-com/augur-core";

export const siteConfig = defineSite({
  name: "example-site",
  mode: "b2b",
  analytics: { gtmId: process.env.NEXT_PUBLIC_GTM_ID! },
});
// lib/augur-site.ts
import { AugurAPI } from "@simpleapps-com/augur-api";
import { createServerSite } from "@simpleapps-com/augur-server/site";

const api = new AugurAPI({ siteId: process.env.AUGUR_SITE_ID!, bearerToken: process.env.AUGUR_JWT! });

export const site = createServerSite(api, { auth: { secret: process.env.AUTH_SECRET } });

Use the SDK directly; don't wrap AugurAPI in a class of your own.

Provider setup

// app/providers.tsx
"use client";
import { AugurSiteProvider } from "@simpleapps-com/augur-web/provider";
import { isServer, QueryClient, QueryClientProvider } from "@tanstack/react-query";
import "@simpleapps-com/augur-server/hooks"; // registers queryAction with augur-hooks
import { siteConfig } from "@/lib/augur-config";

let browserQueryClient: QueryClient | undefined;

// The server gets a new client per request; the browser keeps one for the page.
function getQueryClient() {
  if (isServer) return new QueryClient();
  return (browserQueryClient ??= new QueryClient());
}

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <QueryClientProvider client={getQueryClient()}>
      <AugurSiteProvider config={siteConfig}>{children}</AugurSiteProvider>
    </QueryClientProvider>
  );
}

With no api, the provider's proxy calls the server through the registered queryAction, so the JWT never reaches the browser (how the proxy is chosen). Pass api only for a site whose browser holds its own SDK client. AugurSiteProvider adds GTM analytics when config.analytics is set; without analytics you can use augur-hooks' AugurHooksProvider directly.

  • The QueryClient MUST NOT be created at module scope (const queryClient = new QueryClient() outside a function): on the server that one client would be shared by every request and never freed. Use the function above, or useState(() => new QueryClient()) in the component.
  • The provider SHOULD NOT set a finite gcTime in defaultOptions.queries: client components render on the server too, and a finite gcTime there keeps the request's whole cache in memory until its timer fires. The augur proxies already choose the right gcTime for each runtime.

Put SessionProvider (NextAuth) outside QueryClientProvider when the site uses it, and map the session into AugurSiteProvider's auth prop.

Auth

// auth.ts
import NextAuth from "next-auth";
import { site } from "@/lib/augur-site";

export const { handlers, signIn, signOut, auth } = NextAuth(site.auth!);

createServerSite builds the NextAuth config from the SDK client when given auth. For your own callbacks, use createAuthConfig.

Fetching data

// lib/augur-query.ts
"use client";
import { createServerQueryProxy } from "@simpleapps-com/augur-server/hooks";

export const q = createServerQueryProxy();
// app/products/[invMastUid]/page.tsx
import { dehydrate, HydrationBoundary } from "@tanstack/react-query";
import { createAugurOptions, getQueryClient } from "@simpleapps-com/augur-hooks/server";
import { site } from "@/lib/augur-site";
import { ProductDetails } from "@/components/products/ProductDetails";

export default async function ProductPage({ params }: { params: Promise<{ invMastUid: string }> }) {
  const invMastUid = Number((await params).invMastUid);
  const queryClient = getQueryClient();
  await queryClient.prefetchQuery(createAugurOptions(site.client).items.invMast.doc.get(invMastUid));

  return (
    <HydrationBoundary state={dehydrate(queryClient)}>
      <ProductDetails invMastUid={invMastUid} />
    </HydrationBoundary>
  );
}
// components/products/ProductDetails.tsx
"use client";
import { useQuery } from "@tanstack/react-query";
import { q } from "@/lib/augur-query";

export function ProductDetails({ invMastUid }: { invMastUid: number }) {
  const { data: item } = useQuery(q.items.invMast.doc.get(invMastUid));
  return <h1>{item?.itemDesc}</h1>;
}

The server and the browser build the same key for the same call, so the prefetched data hydrates without a second fetch. More patterns: Recipes.

Site layout

example-site/
├── app/            routes, layout.tsx (wraps children in Providers), globals.css
├── components/     layouts (header, footer, menus) and site compositions of augur-web
├── lib/
│   ├── augur-config.ts   defineSite()
│   ├── augur-site.ts     createServerSite()
│   └── augur-query.ts    createServerQueryProxy()
├── auth.ts         NextAuth(site.auth!)
├── eslint.config.mjs, prettier.config.mjs, tsconfig.json   from augur-config
└── next.config.ts

The site keeps its routes, layout components, brand CSS, next.config (images, redirects, headers), environment (AUGUR_SITE_ID, AUGUR_JWT, AUTH_SECRET, Redis URLs), site-specific server actions and integrations (GA4, ads, maps, reCAPTCHA).

Run pnpm augur-doctor to see how the site scores against the platform standard.