Logo

React SDK

React hooks and components for integrating Quotient into React applications

Installation

npm install @quotientjs/react

QuotientProvider

Context provider that initializes and manages the SDK. Wrap your app with this component to use Quotient hooks in child components.

PropTypeRequiredDescription
clientOptions.apiKeystringYesYour public API key
clientOptions.baseUrlstringNoCustom API endpoint
autoTrackPageViewsbooleanNoAuto-track page views on mount (default false)
import { QuotientProvider } from "@quotientjs/react";

function App() {
  return (
    <QuotientProvider
      clientOptions={{ apiKey: "pk_your_public_api_key" }}
      autoTrackPageViews={true}
    >
      {children}
    </QuotientProvider>
  );
}

useQuotient

Access the Quotient client and context within React components.

import { useQuotient } from "@quotientjs/react";

function MyComponent() {
  const {
    client, // QuotientClient instance or null
    error, // Error or null if initialization failed
    reset, // () => void: Clear storage and reinitialize
  } = useQuotient();
}
FieldTypeDescription
clientQuotientClient | nullThe initialized client instance
errorError | nullSet if initialization failed
reset() => voidClear all stored data and reinitialize

useBlogs

Fetch a paginated list of blogs within a client component. Must be inside a <QuotientProvider>.

ParamTypeRequiredDescription
pagenumberNoPage number
limitnumberNoResults per page
statusesBlogStatus[]NoFilter by status
"use client";
import { BlogStatus, useBlogs } from "@quotientjs/react";

export default function BlogList({
  page,
  limit,
  statuses,
}: {
  page: number;
  limit: number;
  statuses: BlogStatus[];
}) {
  const { data, isLoading } = useBlogs({
    page,
    limit,
    statuses,
  });

  const { blogs, pageData } = data;
  return (
    {/* Render blog list */}
  );
}

Common Patterns

User Identification on Login

"use client";
import { useQuotient } from "@quotientjs/react";

function LoginHandler() {
  const { client } = useQuotient();

  const handleLogin = async (user) => {
    await client?.audience.people.upsert({
      emailAddress: user.email,
      firstName: user.firstName,
      lastName: user.lastName,
      lists: ["customers"],
    });
  };

  return <button onClick={() => handleLogin(user)}>Login</button>;
}

Marketing Preference Center

"use client";
import { useQuotient } from "@quotientjs/react";
import { useState } from "react";

function EmailPreferences({ userEmail }) {
  const [state, setState] = useState("SUBSCRIBED");
  const [lists, setLists] = useState(["newsletter", "promotions"]);
  const { client } = useQuotient();

  const updatePreferences = async () => {
    try {
      await client.audience.people.upsert({
        emailAddress: userEmail,
        emailMarketingState: state,
        lists: state === "SUBSCRIBED" ? lists : [],
      });

      toast.success("Preferences updated");
    } catch (error) {
      toast.error("Failed to update preferences");
    }
  };

  return (
    <div>
      <label>
        <input
          type="radio"
          checked={state === "SUBSCRIBED"}
          onChange={() => setState("SUBSCRIBED")}
        />
        Subscribed - Receive marketing emails
      </label>

      <label>
        <input
          type="radio"
          checked={state === "UNSUBSCRIBED"}
          onChange={() => setState("UNSUBSCRIBED")}
        />
        Unsubscribed - No marketing emails
      </label>

      {state === "SUBSCRIBED" && (
        <div>
          <h3>Email Lists:</h3>
          <label>
            <input
              type="checkbox"
              checked={lists.includes("newsletter")}
              onChange={(e) => {
                if (e.target.checked) {
                  setLists([...lists, "newsletter"]);
                } else {
                  setLists(lists.filter((l) => l !== "newsletter"));
                }
              }}
            />
            Weekly Newsletter
          </label>
          {/* More list options... */}
        </div>
      )}

      <button onClick={updatePreferences}>Save Preferences</button>
    </div>
  );
}

Next Steps