To implement your own UI for Feed in your react application we provide context providers and hooks.
If you are not using any of the In-build UI components while designing your custom UI for feed, you can use @suprsend/react-core SDK. These hooks and context providers are available in both @suprsend/react-core and @suprsend/react SDK’s. Integration steps mentioned in this guide are also same for both.

Pre-Requisite

Integrate SuprSendProvider as it is needed for creating SuprSend Client and authenticating user.

Installation

npm install @suprsend/react-core
In @suprsend/react-core v1.0.0, we have changed the pageInfo object data. Please refer to Migration guide for more details.

Integration

SuprSendFeedProvider

This provider internally creates InApp feed client instance and also removes it on unmounting. This should be called inside SuprSendProvider. FeedClient can be accessed using useFeedClient hook.
import { SuprSendProvider, SuprSendFeedProvider } from '@suprsend/react-core';
// import { SuprSendProvider, SuprSendFeedProvider } from '@suprsend/react'; // if you use our inbuilt react components

function Example() {
  return (
    <SuprSendProvider publicApiKey={YOUR_KEY} distinctId={YOUR_DISTINCT_ID}>
      <SuprSendFeedProvider>Your Feed Component</SuprSendFeedProvider>
    </SuprSendProvider>
  );
}

useFeedClient

This hook is used to get Feed client instance. Using this instance you can access feed methods like mark seen, archive, read etc. Use this hook inside SuprSendFeedProvider.
import {useFeedClient} from '@suprsend/react-core';
// import { useFeedClient } from '@suprsend/react'; // if you use our inbuilt react components

function MyComponent() {
const feedClient = useFeedClient();

return (
  <p
    onClick={() => {
      feedClient.markAsSeen(notificationId);
    }}
  >
    Click Me
  </p>
);
}

useFeedData

This hook returns react state that contains notification store data which includes notifications list and other meta data. This state gets updated internally when there is any update in store. Use this state to render UI in your application. Use this hook inside SuprSendFeedProvider.
import {useFeedData} from "@suprsend/react-core"
// import { useFeedData } from '@suprsend/react'; // if you use our inbuilt react components


function MyComponent() {
  const feedData = useFeedData();

  const notificationsList = feedData.notifications;
  return <div>{notificationsList.map(notification)=><p>{notification.n_id}</p>}</div>;
}

Example

import {
  SuprSendProvider,
  SuprSendFeedProvider,
  useFeedData,
  useFeedClient,
} from "@suprsend/react-core";

function Example() {
  return (
    <SuprSendProvider
      publicApiKey={"YOUR_PUBLIC_API_KEY"}
      distinctId={"YOUR_DISTINCT_ID"}
    >
      <SuprSendFeedProvider>
        <MyFeedComponent />
      </SuprSendFeedProvider>
    </SuprSendProvider>
  );
}

function MyFeedComponent() {
  const feedData = useFeedData();
  const feedInstance = useFeedClient();

  if (!feedData) return null;
  if (feedData.apiStatus === "LOADING") return <p>Loading Data</p>;
  if (feedData.apiStatus === "SUCCESS" && !feedData?.notifications?.length) {
    return <p>No Notifications</p>;
  }
  if (feedData.notifications) {
    return (
      <div>
        <div>
          {feedData.notifications.map((notification) => {
            return (
              <div
                key={notification.n_id}
                onClick={() => {
                  feedInstance.markAsRead(notification.n_id);
                }}
              >
                {notification.n_id}
              </div>
            );
          })}
        </div>
        {feedData.apiStatus === "FETCHING_MORE" ? (
          <p>Loading More</p>
        ) : (
          <div>
            {feedData.pageInfo.hasMore && (
              <button
                onClick={() => {
                  feedInstance.fetchNextPage();
                }}
              >
                Next
              </button>
            )}
          </div>
        )}
      </div>
    );
  }
  return null;
}

Using built-in components in headless implementation

We exported few inbuilt components you can use to save time while building your own UI. If you are using @suprsend/react-core and want to use these components please remove that package and install @suprsend/react, integration steps remain unchanged other than changing import statement.

NotificationCard component

This is single notification card component. It will be handy if you want to implement your own UI but want to just use our notification card as it has a bit complex logic and UI.
import { NotificationCard } from '@suprsend/react';

<NotificationCard notificationData={data} />
Please refer Customising CSS styles section to view typedefs for INotificationCardTheme.

BodyMarkdown component

This is simple div element but also supports rendering of markdown language. Read more about the component.

Sample Notification JSON Structure

{
  "tenant_id": "default",
  "is_expiry_visible": false,
  "seen_on": 1754346745613,
  "read_on": 1754346745613,
  "is_pinned": false,
  "archived": false,
  "created_on": 1753966489304,
  "n_category": "transactional",
  "interacted_on": 1754346745613,
  "n_id": "01K1G8SBGS4A1QG2CGYSVXQ517",
  "message": {
    "schema": "1.0",
    "header": "Your invoice for {{event.billing_month}} is ready",
    "text": "An invoice of **{{event.amount}}** has been generated for your workspace {{event.workspace_name}}.",
    "subtext": {
      "text": "View full billing history",
      "action_url": "https://app.suprsend.com/billing/history"
    },
    "avatar": {
      "avatar_url": "https://cdn-icons-png.flaticon.com/512/3144/3144456.png",
      "action_url": "https://app.suprsend.com/settings"
    },
    "url": "https://app.suprsend.com/billing/{{event.invoice_id}}",
    "extra_data": "{\n  \"workspace\": \"{{event.workspace_name}}\"\n}",
    "tags": [
      "billing",
      "finance"
    ],
    "expiry": {
      "format": "absolute",
      "expiry_type": "fixed",
      "is_expiry_visible": true,
      "value": "2025-09-30T23:59:59Z"
    },
    "is_pinned": true,
    "is_expiry_enabled": true,
    "actions": [
      {
        "url": "https://app.suprsend.com/billing/{{event.invoice_id}}",
        "name": "View Invoice"
      },
      {
        "url": "https://app.suprsend.com/billing/pay/{{event.invoice_id}}",
        "name": "Pay Now"
      }
    ]
  }
}
Fields and its description Top-level Fields
FieldTypeDescription
n_idstringUnique notification ID for a message.
n_categorystringCategory of the notification. Used to fetch and apply category-level preferences (e.g., transactional, marketing). You can also use categories to group notifications in different tabs.
created_onnumberTimestamp (epoch ms) when the notification reached the inbox.
seen_onnumberTimestamp (epoch ms) when the notification was first seen.
read_onnumberTimestamp (epoch ms) when the notification was marked as read using the markAsRead method.
interacted_onnumberTimestamp (epoch ms) when the user clicked or interacted with the notification.
messageobjectPayload containing the actual notification content and metadata.
tenant_idstringTenant identifier. Used to identify the tenant in a multi-tenant setup.
is_pinnedbooleanWhether the notification is pinned in the inbox. Pinned notifications remain fixed at the top of the inbox feed. Commonly used for critical messages that should not scroll down as new notifications arrive.
archivedbooleanWhether the notification has been archived by the user. Archived notifications are hidden from the inbox feed by default unless you explicitly pass is_archived = false in the store config.
is_expiry_visiblebooleanWhether the notification’s expiry is visible to the user. Expiry details are found inside the message object. Useful when you want notifications to auto-delete after a certain time.
message Object Fields
FieldTypeDescription
schemastringSchema version for the message format.
headerstringMain title/header of the notification.
textstringBody text of the notification; supports Markdown and HTML content. Default format is markdown.
subtextobjectSecondary text with optional action_url. Is visible below the main text. Generally used to show additional information or footer text.
avatarobjectAvatar image shown with the notification, generally used to show sender’s profile picture; can include an action link.
urlstringURL where user will be redirected when they click the notification.
extra_datastringJSON string for passing additional data that can be used to design custom notification card UI.
tagsarrayList of tags to classify the notification (e.g., feature_launch, mentions). Generally used to filter and organize notifications inside multiple tabs.
is_expiry_enabledbooleanWhether expiry handling is enabled for this notification. Expiry is set for notifications that are supposed to auto delete after a certain time (e.g., upcoming maintenances, events, etc.). Used to send notifications like upcoming maintenances, events, etc.
expiryobjectExpiry configuration (format, type, visibility, value) set when is_expiry_enabled is true.
is_pinnedbooleanWhether this message should pin at top of the notification feed. Generally used to send critical notifications to the user that you don’t want to go down when new notifications are added.
actionsarrayList of call-to-action buttons (each with url and name).
You can understand more about usage and details of message fields in it’s template documentation.