Customizing the Inbox

ChimeKit’s React package gives you a ready-made Inbox, but it also exports primitives so you can design a completely custom experience. This guide covers both approaches.

Option A: Customize <Inbox /> via props

<Inbox /> is the fastest way to ship an in-app inbox. You can customize it through:

  • Presentation: variant (popover, modal, drawer) and width
  • Copy: labels for titles and tab labels
  • Branding: primaryColor
  • Callbacks: onActionCallback
  • Styling: slot-based classes.* overrides
  • Deeper customization: pass-through props like feedProps and messageDetailsProps

Customized Inbox

import { ChimeKitProvider, Inbox } from "@chimekit/react";
import "@chimekit/react/styles.css";
// Tailwind (optional): if you want utilities to override ChimeKit styles,
// use your global CSS instead:
// @import "@chimekit/react/styles.css" layer(components);

export function Notifications({ token }: { token: string }) {
  return (
    <ChimeKitProvider
      publicKey={process.env.NEXT_PUBLIC_CHIMEKIT_PUBLIC_KEY!}
      token={token}
      audienceMember={{ id: "user_123" }}
    >
      <Inbox
        variant="popover"
        labels={{
          title: "Notifications",
          tabs: { all: "All", unread: "New", archived: "Saved" },
        }}
        primaryColor="#2563eb"
        onActionCallback={(actionId) => {
          console.log("callback action:", actionId);
        }}
        feedProps={{ showCategory: true }}
      />
    </ChimeKitProvider>
  );
}

Styling with classes and data-chimekit-slot

All widgets include data-chimekit-slot attributes on key elements, and most expose a classes prop for slot-level class overrides.

If you want CSS-only customization, target slots directly:

Example overrides

[data-chimekit-slot="chimekit-bell"] {
  border-radius: 9999px;
}

Option B: Build your own inbox UI from primitives

If you want full control, compose the exported primitives:

  • Feed for the list
  • MessageDetails for the selected message
  • Preferences for preference management (optional)

Here’s a minimal “two-pane” inbox (feed on the left, details on the right):

Custom inbox layout

import * as React from "react";
import {
  ChimeKitProvider,
  Feed,
  MessageDetails,
} from "@chimekit/react";
import "@chimekit/react/styles.css";
// Tailwind (optional): if you want utilities to override ChimeKit styles,
// use your global CSS instead:
// @import "@chimekit/react/styles.css" layer(components);

export function CustomInbox({ token }: { token: string }) {
  const [messageId, setMessageId] = React.useState<string | null>(null);

  return (
    <ChimeKitProvider
      publicKey={process.env.NEXT_PUBLIC_CHIMEKIT_PUBLIC_KEY!}
      token={token}
      audienceMember={{ id: "user_123" }}
    >
      <div style={{ display: "grid", gridTemplateColumns: "360px 1fr", gap: 16 }}>
        <Feed onMessageClick={(m) => setMessageId(m.messageId)} />
        <MessageDetails messageId={messageId} displaySnippet />
      </div>
    </ChimeKitProvider>
  );
}

Next steps

  • Learn all widget props and exports: Client SDKs.
  • Send richer in-app content (actions, templates, categories): Messages.

Was this page helpful?