docs/platform/subscription/customize-and-configure.mdx
The Subscription UI works within the existing Novu environment and uses the same provider and styling architecture as the <Inbox /> component.
You can configure which options are visible to your users, apply your brand's theme, or take full control of the rendering.
The preferences prop on the <Subscription /> component controls which workflows the component displays to the user.
If you want to simply filter which workflows are visible without changing their labels, then you can pass an array of workflow identifier strings. The component uses the workflow names defined in the Dashboard as the labels.
import { NovuProvider, Subscription } from '@novu/react';
export function Novu() {
return (
<NovuProvider
subscriber="SUBSCRIBER_ID"
applicationIdentifier="APPLICATION_IDENTIFIER"
>
<Subscription
topicKey="product-updates"
identifier="user-123"
// Only shows these two workflows
preferences={["workflow-identifier-1", "workflow-identifier-2"]}
/>
</NovuProvider>
)
}
You can filter using tags, workflow IDs, or both. You can also customize the labels, descriptions, or default states by passing an array of objects.
import { NovuProvider, Subscription, } from '@novu/react';
export function Novu() {
return (
<NovuProvider
subscriber="SUBSCRIBER_ID"
applicationIdentifier="APPLICATION_IDENTIFIER"
>
<Subscription
topicKey="product-updates"
identifier="user-123"
preferences={[
{
workflowId: "comment-on-task",
label: "New Comments",
enabled: true, // Force enabled by default
},
{
// Group multiple workflows under one label and filter using tags
filter: { tags: ['security', 'admin'] },
label: 'Security Alerts',
enabled: false,
},
{
// Group multiple workflows under one label and filter using workflow id
filter: { workflowIds: ['test-workflow1', 'test-workflow2'] },
label: 'Test Group',
enabled: false,
},
]}
/>
</NovuProvider>
);
}
You can also update the labels for the workflows with the dynamic prop of the localization. For full localization options, see the Inbox localization documentation.
The <Subscription /> component shares the same styling architecture as the Inbox component. You can use the appearance prop to customize elements, variables, icons and themes.
For full styling and theming options, see the Inbox styling documentation.
Novu provides subscriptionDarkTheme in the @novu/react/themes package to apply the built-in dark theme to the <Subscription /> component. You can apply this conditionally based on your app's state.
import { NovuProvider, Subscription } from '@novu/react';
import { subscriptionDarkTheme } from '@novu/react/themes';
export function Novu() {
const isDarkMode = true;
return (
<NovuProvider
subscriber="SUBSCRIBER_ID"
applicationIdentifier="APPLICATION_IDENTIFIER"
>
<Subscription
topicKey="product-updates"
identifier="user-123"
appearance={{
baseTheme: isDarkMode ? subscriptionDarkTheme : undefined,
}}
/>
</NovuProvider>
);
}
You can customize the text labels used in the component to support different languages or to match your app's voice. This works identically to Inbox localization.
import { NovuProvider, Subscription } from '@novu/react';
export function Novu() {
return (
<NovuProvider
subscriber="SUBSCRIBER_ID"
applicationIdentifier="APPLICATION_IDENTIFIER"
>
<Subscription
topicKey="product-updates"
identifier="user-123"
localization={{
"subscription.subscribe": "Join",
locale: "en-US",
}}
/>
</NovuProvider>
);
}
For full localization options, see the Inbox localization documentation.
The renderPreferences prop on the <Subscription /> component lets you override how the component displays the list of workflows while still relying on the component to handle data fetching and state management.
The function receives the current subscription object and a loading boolean. You can map over the preferences array and render your own HTML elements.
import { NovuProvider, Subscription, TopicSubscription } from '@novu/react';
export function Novu() {
return (
<NovuProvider
subscriber="SUBSCRIBER_ID"
applicationIdentifier="APPLICATION_IDENTIFIER"
>
<Subscription
topicKey="product-updates"
identifier="user-123"
preferences={["workflow-1", "workflow-2"]}
renderPreferences={(subscription?: TopicSubscription, loading?: boolean) => (
<div>
{subscription?.preferences.map((preference, idx) => (
<div key={`${subscription.identifier}-${idx}`}>
<label htmlFor={`pref-${idx}`}>{preference.label}</label>
<span>{preference.description}</span>
<input
id={`pref-${idx}`}
type="checkbox"
checked={preference.enabled}
onChange={(e) =>
preference.update({ value: e.target.checked })
}
/>
</div>
))}
</div>
)}
/>
</NovuProvider>
)
}