Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@syncagent/nextjs

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@syncagent/nextjs

SyncAgent Next.js SDK — server-safe helpers and components

latest
Source
npmnpm
Version
0.4.0
Version published
Weekly downloads
143
1488.89%
Maintainers
1
Weekly downloads
 
Created
Source

@syncagent/nextjs

Next.js SDK for SyncAgent — server-safe helpers that keep your database connection string out of the browser bundle.

Works with MongoDB, PostgreSQL, MySQL, SQLite, SQL Server, and Supabase.

npm version License: MIT

Get Your API Key

  • Sign up for a free account
  • Go to your DashboardNew Project → choose your database type
  • Copy your API key (starts with sa_)

Every new project gets a 14-day trial with 500 free requests — no credit card required. After the trial, you get 100 free requests/month on the Free plan.

Install

npm install @syncagent/nextjs @syncagent/js @syncagent/react

Why Use This Instead of @syncagent/react?

The @syncagent/nextjs package provides createServerConfig() which lets you safely pass your database connection string from Server Components — it never reaches the browser bundle. All config options from @syncagent/js are supported.

Quick Start

// app/dashboard/page.tsx — Server Component (no "use client")
import { createServerConfig } from "@syncagent/nextjs/server";
import { SyncAgentChat } from "@syncagent/nextjs";
import { getServerSession } from "next-auth";

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"
      context={{ userId: session.user.id, page: "dashboard" }}
    />
  );
}

From Environment Variables

import { createServerConfigFromEnv } from "@syncagent/nextjs/server";

// Reads SYNCAGENT_KEY and DATABASE_URL automatically
const config = createServerConfigFromEnv({
  filter: { orgId: session.user.orgId },
  language: "French",
});
# .env.local
SYNCAGENT_KEY=sa_your_api_key
DATABASE_URL=mongodb+srv://user:pass@cluster/db

All Config Options

createServerConfig accepts all SyncAgentConfig options:

OptionTypeRequiredDescription
apiKeystringYour SyncAgent API key
connectionStringstring✅*Your database URL — stays on the server. *Optional when toolsOnly: true.
filterRecord<string,any>Mandatory query filter for multi-tenancy
operationsstring[]Restrict operations for this session
toolsOnlybooleanDisables all DB tools — agent only uses custom tools
systemInstructionstringCustom agent instructions — personality, tone, rules
confirmWritesbooleanAsk for confirmation before writes
languagestringLanguage the agent responds in (e.g. "French")
maxResultsnumberDefault max records per query (default 50)
sensitiveFieldsstring[]Fields to mask in responses
autoDetectPagebooleanAuto-detect page from URL (default true)
baseUrlstringOverride API URL (dev only)

Full Example — Multi-tenant SaaS

// app/app/[orgSlug]/page.tsx — Server Component
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 (
    <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 }}
    />
  );
}

Tools-only Mode

// Server Component
import { createServerConfig } from "@syncagent/nextjs/server";
import { ChatWithTools } from "./chat-with-tools";

export default async function Page() {
  const config = createServerConfig({
    apiKey: process.env.SYNCAGENT_KEY!,
    toolsOnly: true,
    systemInstruction: "You are a product search assistant.",
  });
  return <ChatWithTools serverConfig={config} />;
}
// app/dashboard/chat-with-tools.tsx — "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();
            },
          },
        },
      }}
    />
  );
}

Customer Agent Mode

The createCustomerServerConfig server helper configures customer agent mode from a Server Component. It validates that externalUserId is provided — customer mode is automatically enabled when externalUserId is present.

Server Component

// app/support/page.tsx — Server Component
import { createCustomerServerConfig } from "@syncagent/nextjs/server";
import { getServerSession } from "next-auth";
import { CustomerSupportWidget } from "./customer-support-widget";

export default async function SupportPage() {
  const session = await getServerSession();

  const config = createCustomerServerConfig({
    apiKey: process.env.SYNCAGENT_KEY!,
    connectionString: process.env.DATABASE_URL!,
    externalUserId: session.user.id,
    filter: { organizationId: session.user.orgId },
  });

  return <CustomerSupportWidget config={config} />;
}

Client Component

// app/support/customer-support-widget.tsx — "use client"
"use client";

import { useCustomerChat } from "@syncagent/nextjs";
import { SyncAgentClient } from "@syncagent/nextjs";
import type { SyncAgentConfig } from "@syncagent/js";

export function CustomerSupportWidget({ config }: { config: SyncAgentConfig }) {
  const client = new SyncAgentClient(config);

  const {
    messages,
    sendMessage,
    isLoading,
    isEscalated,
    isResolved,
    welcomeMessage,
    rateConversation,
  } = useCustomerChat({ client });

  return (
    <div>
      {welcomeMessage && <p>{welcomeMessage}</p>}
      {messages.map((msg, i) => (
        <div key={i}>{msg.role}: {msg.content}</div>
      ))}
      {isEscalated && <p>You have been connected to a human agent.</p>}
      {isResolved && (
        <div>
          <p>Conversation resolved.</p>
          <button onClick={() => rateConversation(5)}>Rate 5 ⭐</button>
        </div>
      )}
      <input
        onKeyDown={(e) => {
          if (e.key === "Enter") sendMessage(e.currentTarget.value);
        }}
        disabled={isLoading}
      />
    </div>
  );
}

externalUserId Requirement

The externalUserId option is required when using createCustomerServerConfig. Omitting it throws an error:

Error: @syncagent/nextjs: externalUserId is required for customer mode

This ID scopes conversations to a specific customer and should always come from an authenticated session (e.g. session.user.id).

Re-exported Hook

useCustomerChat is re-exported from @syncagent/nextjs for convenience — no need to install @syncagent/react separately:

import { useCustomerChat } from "@syncagent/nextjs";

Guest Identification

The GuestIdentificationForm component and all guest identification utilities are re-exported from @syncagent/nextjs — no need to install @syncagent/react or @syncagent/js separately.

Available exports:

ExportKindDescription
GuestIdentificationFormComponentPre-built form for collecting guest name, email, and optional phone
GuestIdentificationFormPropsTypeProps interface for the form component
GuestIdentityTypeObject containing name, email, phone, and generated guestId
GuestFormConfigTypeConfiguration for customizing form text and placeholders
FieldValidationResultTypeValidation result for individual form fields
validateGuestFormFunctionValidates all guest form fields at once
validateNameFunctionValidates a name string (non-empty, non-whitespace)
validateEmailFunctionValidates an email string
generateGuestIdentifierFunctionGenerates a deterministic guest_-prefixed ID from an email
GuestIdentificationRequiredErrorClassError thrown when sending a message before identification

Usage in Next.js App Router

Important: The GuestIdentificationForm is a client component. You must add the "use client" directive at the top of any file that uses it in the Next.js App Router.

// app/support/guest-chat.tsx
"use client";

import {
  useCustomerChat,
  GuestIdentificationForm,
  SyncAgentClient,
} from "@syncagent/nextjs";
import type { SyncAgentConfig, GuestIdentity } from "@syncagent/nextjs";

export function GuestChat({ config }: { config: SyncAgentConfig }) {
  const client = new SyncAgentClient(config);

  const {
    messages,
    sendMessage,
    isLoading,
    isIdentified,
    guestIdentity,
    identifyGuest,
  } = useCustomerChat({
    client,
    onGuestIdentified: (identity: GuestIdentity) => {
      console.log("Guest identified:", identity.guestId);
    },
  });

  if (!isIdentified) {
    return (
      <GuestIdentificationForm
        onSubmit={(identity) => identifyGuest(identity)}
        config={{
          title: "Welcome to Support",
          subtitle: "Please introduce yourself to get started",
          submitButtonText: "Start Chat",
        }}
      />
    );
  }

  return (
    <div>
      {messages.map((msg, i) => (
        <div key={i}>{msg.role}: {msg.content}</div>
      ))}
      <input
        onKeyDown={(e) => {
          if (e.key === "Enter") sendMessage(e.currentTarget.value);
        }}
        disabled={isLoading}
      />
    </div>
  );
}
// app/support/page.tsx — Server Component (no "use client")
import { createCustomerServerConfig } from "@syncagent/nextjs/server";
import { GuestChat } from "./guest-chat";

export default async function SupportPage() {
  const config = createCustomerServerConfig({
    apiKey: process.env.SYNCAGENT_KEY!,
    connectionString: process.env.DATABASE_URL!,
    externalUserId: undefined, // omit to enable guest flow
  });

  return <GuestChat config={config} />;
}

When externalUserId is not provided, the useCustomerChat hook requires guest identification before messages can be sent. The GuestIdentificationForm collects the guest's details and the identity is persisted to localStorage so returning visitors are recognized automatically.

Dual Mode (Database + Customer Agent)

⚠️ Deprecated: createDual() will be removed in a future major version. Use createDualServerConfig() instead — it keeps your connection string on the server and returns separate db and support configs for Client Components.

Before (deprecated):

import { SyncAgentClient } from "@syncagent/js";

const { db, support } = SyncAgentClient.createDual({
  apiKey: process.env.SYNCAGENT_KEY!,
  connectionString: process.env.DATABASE_URL!,
  externalUserId: session.user.id,
});

After (recommended):

import { createDualServerConfig } from "@syncagent/nextjs/server";

const { db, support } = createDualServerConfig({
  apiKey: process.env.SYNCAGENT_KEY!,
  connectionString: process.env.DATABASE_URL!,
  externalUserId: session.user.id,
});

Legacy pattern (deprecated):

// app/dashboard/page.tsx — Server Component
import { SyncAgentClient } from "@syncagent/js";
import { getServerSession } from "next-auth";
import { AdminChat } from "./admin-chat";
import { CustomerWidget } from "./customer-widget";

export default async function DashboardPage() {
  const session = await getServerSession();

  const { db, support } = SyncAgentClient.createDual({
    apiKey: process.env.SYNCAGENT_KEY!,
    connectionString: process.env.DATABASE_URL!,
    externalUserId: session.user.id,
  });

  // Pass each client to its respective widget
  return (
    <div>
      <AdminChat config={db} />
      <CustomerWidget config={support} />
    </div>
  );
}

Unified Dual Mode

The createDualServerConfig() server helper creates a unified dual-mode configuration from a Server Component. It returns separate db and support config objects that you pass to Client Components — keeping your connection string out of the browser bundle while enabling both database agent and customer agent modes.

Server Component

// app/dashboard/page.tsx — Server Component
import { createDualServerConfig } from "@syncagent/nextjs/server";
import { getServerSession } from "next-auth";
import { AdminChat } from "./admin-chat";
import { CustomerWidget } from "./customer-widget";

export default async function DashboardPage() {
  const session = await getServerSession();

  const { db, support } = createDualServerConfig({
    apiKey: process.env.SYNCAGENT_KEY!,
    connectionString: process.env.DATABASE_URL!,
    externalUserId: session.user.id,
    filter: { organizationId: session.user.orgId },
  });

  return (
    <div>
      <AdminChat config={db} />
      <CustomerWidget config={support} />
    </div>
  );
}

DualServerConfig Return Type

interface DualServerConfig {
  db: SyncAgentConfig;
  support: SyncAgentConfig;
}
  • db — Configuration for the database agent mode (uses chat())
  • support — Configuration for the customer agent mode (uses customerChat())

Validation Rules

createDualServerConfig() validates the provided options and throws an error if required fields are missing:

ConditionError Message
apiKey is missing@syncagent/nextjs: apiKey is required
externalUserId is missing@syncagent/nextjs: externalUserId is required for dual mode
connectionString is missing (and toolsOnly is not true)@syncagent/nextjs: connectionString is required (or set toolsOnly: true)

When toolsOnly: true is set, connectionString is not required — the agent will only use custom tools without database access.

Re-exported Hook: useDualChat

useDualChat is re-exported from @syncagent/nextjs for client-side use — no need to install @syncagent/react separately:

import { useDualChat } from "@syncagent/nextjs";

Use useDualChat in your Client Components to manage both database and customer chat state from a single hook. See the @syncagent/react documentation for full useDualChat() API reference.

Middleware Hooks (Client-side Only)

Functions like onBeforeToolCall can't be serialized from Server Components. Define them in a Client Component:

// app/components/chat.tsx — "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;
        },
      }}
    />
  );
}

Re-exported Components

All components and hooks from @syncagent/react are re-exported:

import { SyncAgentChat, SyncAgentProvider, useSyncAgent, SyncAgentClient } from "@syncagent/nextjs";

API Reference

FunctionReturnsContextDescription
createServerConfig(options)SyncAgentConfigServer onlyCreate config with all options
createServerConfigFromEnv(overrides?)SyncAgentConfigServer onlyCreate config from SYNCAGENT_KEY + DATABASE_URL env vars
createCustomerServerConfig(options)SyncAgentConfigServer onlyCreate config for customer agent mode (requires externalUserId)
createDualServerConfig(options)DualServerConfigServer onlyCreate unified dual-mode config requiring externalUserId — returns { db, support }

TypeScript Types

The following types and hooks are re-exported from @syncagent/nextjs for client-side use:

import { useDualChat, DualChatReturn, UseDualChatOptions } from "@syncagent/nextjs";
ExportKindDescription
useDualChatHookManages both database and customer chat state from a single hook
DualChatReturnTypeReturn type of useDualChat() — contains db and support namespaces
UseDualChatOptionsTypeOptions interface for useDualChat() — accepts context, onData, onEscalated, onResolved

These are re-exported from @syncagent/react so you don't need to install it separately.

Security

  • Your database connection string is never stored on SyncAgent servers
  • createServerConfig ensures the connection string stays in the server bundle
  • API keys are hashed with bcrypt — raw keys are never stored
  • Never use NEXT_PUBLIC_ prefix for your database URL

Plans & Pricing

PlanRequests/moCollectionsPrice
Free (+ 14-day trial)100 (500 during trial)5GH₵0
Starter5,00020GH₵150/mo
Pro50,000UnlimitedGH₵500/mo
EnterpriseUnlimitedUnlimitedCustom

View full pricing →

Resources

License

MIT

Keywords

syncagent

FAQs

Package last updated on 21 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts