skills/manage-preferences/SKILL.md
Configure notification preferences in Novu at the workflow and subscriber level. Set default channel preferences (email, SMS, push, chat, in-app), mark preferences as read-only or subscriber-editable, and manage subscriber-specific overrides. Use when setting up notification opt-in/opt-out, configuring per-channel delivery preferences, or building a preferences management UI.
npx skillsauth add novuhq/skills novu-manage-preferencesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Novu has a two-level preference system:
Set default preferences when defining a workflow with @novu/framework:
import { workflow } from "@novu/framework";
const alertWorkflow = workflow("system-alert", execute, {
preferences: {
all: { enabled: true, readOnly: false },
channels: {
email: { enabled: true },
sms: { enabled: false },
push: { enabled: true },
chat: { enabled: false },
inApp: { enabled: true },
},
},
});
Authoring workflows in code? See
framework-integrationfor the full Framework setup, Bridge Endpoint, step controls, and deployment.
| Channel | Description |
| --- | --- |
| email | Email notifications |
| sms | SMS text messages |
| push | Mobile/web push notifications |
| chat | Slack, Discord, Teams, etc. |
| inApp | In-app Inbox notifications |
Set readOnly: true to hide a workflow's channels from the Preferences UI — subscribers can't toggle them on or off:
const criticalAlertWorkflow = workflow("critical-alert", execute, {
preferences: {
all: { enabled: true, readOnly: true }, // subscriber CANNOT disable
},
});
readOnly vs critical — pick the right oneThese are different mechanisms with different guarantees. See design-workflow/references/severity-and-critical.md for the full matrix.
| Flag | What it does |
| ------------------------------------ | ------------------------------------------------------------------------------------------- |
| preferences.all.readOnly: true | UI only. Hides the workflow from the Preferences UI so subscribers can't toggle it. |
| critical: true (workflow-level) | Runtime. Bypasses subscriber preferences, skips digest, runs without delays. |
If you need the notification to always be delivered (account suspended, security alert, password reset), set critical: true — readOnly: true alone won't override existing subscriber overrides at runtime.
const marketingWorkflow = workflow("weekly-newsletter", execute, {
preferences: {
all: { enabled: true, readOnly: false }, // subscriber CAN disable
channels: {
email: { enabled: true },
sms: { enabled: false }, // off by default, subscriber can enable
},
},
});
Subscribers can override workflow defaults (unless readOnly: true).
import { Novu } from "@novu/api";
const novu = new Novu({
secretKey: process.env.NOVU_SECRET_KEY,
});
const preferences = await novu.subscribers.preferences.list({
subscriberId: "subscriber-123",
});
await novu.subscribers.preferences.update(
{
workflowId: "weekly-newsletter",
channels: {
email: false, // opt out of email
inApp: true, // keep in-app
},
},
"subscriber-123"
);
Update preferences across all workflows by omitting workflowId:
await novu.subscribers.preferences.update(
{
channels: {
sms: false, // disable SMS for all workflows
},
},
"subscriber-123"
);
When Novu determines whether to deliver a notification:
The most specific preference wins. If a subscriber disables email for a specific workflow, that takes precedence even if their global email preference is enabled.
import { Inbox } from "@novu/react";
function App() {
return (
<Inbox
applicationIdentifier="YOUR_NOVU_APP_ID"
subscriberId="subscriber-123"
subscriberHash="HMAC_HASH"
>
{/* The Preferences panel is built into the Inbox */}
</Inbox>
);
}
The <Inbox /> component includes a built-in Preferences panel accessible via the settings icon.
Use the <Preferences /> component independently:
import { Inbox, Preferences } from "@novu/react";
function PreferencesPage() {
return (
<Inbox
applicationIdentifier="YOUR_NOVU_APP_ID"
subscriberId="subscriber-123"
>
<Preferences />
</Inbox>
);
}
preferences: {
all: { enabled: true, readOnly: true },
}
Subscribers cannot opt out. Use for security alerts, payment notifications, legal notices.
preferences: {
all: { enabled: true, readOnly: false },
channels: {
email: { enabled: true },
sms: { enabled: false },
},
}
Subscribers can toggle channels. SMS is off by default.
preferences: {
all: { enabled: false },
channels: {
inApp: { enabled: true },
},
}
Only in-app is on. Subscribers can enable other channels if desired.
readOnly: true is per-workflow, not per-channel — you set readOnly on the all level. Individual channels inherit it.readOnly workflows — if the workflow is read-only, subscriber preferences are ignored.enabled: false in the workflow default means the channel is off — subscribers can still enable it (unless readOnly: true).data-ai
Trigger Novu notification workflows to send messages across email, SMS, push, chat, and in-app channels. Supports single triggers, bulk triggers, broadcast to all subscribers, topic-based targeting, and cancellation. Use when sending transactional notifications, alerts, or any event-driven messages.
testing
Create, update, search, and delete subscribers in Novu. Manage topics for group-based notification targeting. Set subscriber credentials for push and chat channels. Use when managing notification recipients, creating subscriber records, organizing subscribers into topics, or configuring channel-specific credentials.
development
Integrate Novu's in-app notification inbox into web applications. Supports React, Next.js, and vanilla JavaScript. Includes the Inbox component (bell icon + notification feed), composable components (Bell, Notifications, InboxContent, Preferences), headless hooks, branded theming, custom render props, multi-tenancy via contexts, tabs, localization, and HMAC security. Use when adding an in-app notification center, bell icon, notification feed, real-time notification updates, or building a personalized and branded notification experience.
tools
Build code-first notification workflows with @novu/framework. Use when defining workflows in TypeScript (Zod / JSON Schema / Class Validator), composing channel steps (email, SMS, push, chat, in-app) with action steps (delay, digest, custom), exposing Step Controls for non-technical teammates, rendering React/Vue/Svelte Email templates, hosting the Bridge Endpoint inside Next.js, Express, NestJS, Remix, Nuxt, SvelteKit, H3, or AWS Lambda, syncing to Novu Cloud via CLI / GitHub Actions, securing production with HMAC, or implementing translations, hydration, multi-channel orchestration, and LLM-powered notification logic in code.