@syncagent/nextjs
Next.js SDK for SyncAgent — server-safe helpers and components.
Install
npm install @syncagent/nextjs @syncagent/js @syncagent/react
Why use this instead of @syncagent/react directly?
The @syncagent/nextjs package provides server-side helpers that let you safely pass your database connection string from Server Components — it never reaches the browser bundle.
Quick Start
import { createServerConfig } from "@syncagent/nextjs/server";
import { SyncAgentChat } from "@syncagent/nextjs";
export default async function DashboardPage() {
const session = await getServerSession();
const config = createServerConfig({
apiKey: process.env.SYNCAGENT_KEY!,
connectionString: process.env.DATABASE_URL!,
filter: { organizationId: session.user.orgId },
operations: session.user.isAdmin
? ["read", "create", "update", "delete"]
: ["read"],
});
return (
<SyncAgentChat
config={config}
persistKey={session.user.id}
accentColor="#6366f1"
/>
);
}
From environment variables
import { createServerConfigFromEnv } from "@syncagent/nextjs/server";
const config = createServerConfigFromEnv({
filter: { orgId: session.user.orgId },
});
Environment variables
# .env.local
SYNCAGENT_KEY=sa_your_api_key
DATABASE_URL=mongodb+srv://user:pass@cluster/db
# Optional — for development
NEXT_PUBLIC_SYNCAGENT_BASE_URL=http://localhost:3100
All config options
createServerConfig accepts all SyncAgentConfig options. Serializable values (strings, numbers, booleans, objects) are passed from Server Components to Client Components automatically.
apiKey | string | ✅ | Your SyncAgent API key |
connectionString | string | ✅* | Your database URL — stays on the server. *Optional when toolsOnly: true. |
filter | Record<string,any> | — | Mandatory query filter for multi-tenancy |
operations | string[] | — | Restrict operations for this session |
toolsOnly | boolean | — | When true, disables all DB tools — agent only uses your custom tools |
systemInstruction | string | — | Custom agent instructions — personality, tone, rules |
confirmWrites | boolean | — | When true, agent asks for confirmation before writes |
language | string | — | Language the agent responds in (e.g. "French") |
maxResults | number | — | Default max records per query (default 50) |
sensitiveFields | string[] | — | Fields to mask in responses |
autoDetectPage | boolean | — | Auto-detect page from URL (default true) |
baseUrl | string | — | Override API URL (dev only) |
Full example — multi-tenant SaaS with customization
import { createServerConfig } from "@syncagent/nextjs/server";
import { SyncAgentChat } from "@syncagent/nextjs";
import { getSession } from "@/lib/auth";
import { getOrganization } from "@/lib/db";
export default async function AppPage({ params }: { params: { orgSlug: string } }) {
const session = await getSession();
const org = await getOrganization(params.orgSlug);
const config = createServerConfig({
apiKey: process.env.SYNCAGENT_KEY!,
connectionString: process.env.DATABASE_URL!,
filter: { organizationId: org.id },
operations: session.user.role === "admin"
? ["read", "create", "update", "delete"]
: ["read"],
systemInstruction: `You are the AI assistant for ${org.name}. Be professional and helpful.`,
language: org.language || "English",
confirmWrites: true,
maxResults: 25,
sensitiveFields: ["ssn", "salary", "password"],
});
return (
<div>
<h1>Welcome to {org.name}</h1>
<SyncAgentChat
config={config}
persistKey={`${org.id}-${session.user.id}`}
title={`${org.name} AI`}
accentColor={org.brandColor}
context={{
userId: session.user.id,
userRole: session.user.role,
orgName: org.name,
}}
/>
</div>
);
}
Tools-only mode
const config = createServerConfig({
apiKey: process.env.SYNCAGENT_KEY!,
toolsOnly: true,
systemInstruction: "You are a product search assistant.",
});
<ChatWithTools serverConfig={config} />
"use client";
import { SyncAgentChat } from "@syncagent/nextjs";
export function ChatWithTools({ serverConfig }) {
return (
<SyncAgentChat
config={{
...serverConfig,
tools: {
searchProducts: {
description: "Search products",
inputSchema: { query: { type: "string" } },
execute: async ({ query }) => {
const res = await fetch(`/api/products?q=${query}`);
return res.json();
},
},
},
}}
/>
);
}
Middleware hooks (client-side only)
Functions can't be serialized from Server Components. Define hooks in a Client Component:
"use client";
import { SyncAgentChat } from "@syncagent/nextjs";
export function Chat({ serverConfig }) {
return (
<SyncAgentChat
config={{
...serverConfig,
onBeforeToolCall: (name, args) => {
console.log(`[Audit] ${name}`, args);
return true;
},
onAfterToolCall: (name, args, result) => {
analytics.track("tool_call", { tool: name });
},
}}
/>
);
}
import { createServerConfig } from "@syncagent/nextjs/server";
import { Chat } from "./chat";
export default async function Page() {
const config = createServerConfig({
apiKey: process.env.SYNCAGENT_KEY!,
connectionString: process.env.DATABASE_URL!,
});
return <Chat serverConfig={config} />;
}
Client components
All components and hooks from @syncagent/react are re-exported:
import {
SyncAgentChat,
SyncAgentProvider,
useSyncAgent,
SyncAgentClient,
} from "@syncagent/nextjs";
License
MIT