mcpField
N
novu-manage-preferences

novu-manage-preferences

github.com/novuhqDevelopment4467 installsUpdated 19w ago
Repository

About novu-manage-preferences

A skill for developers configuring Novu notification preferences in workflows and for subscribers. It explains defaults, subscriber overrides, channel settings, and how preferences affect delivery and the UI.

Key features

  1. 01Configure workflow-level channel defaults
  2. 02Read and update subscriber preferences
  3. 03Set global or workflow-specific overrides
  4. 04Explain preference resolution order
  5. 05Embed the Preferences UI in React

Use cases

  1. 01Let subscribers opt out of marketing channels
  2. 02Set channels on or off by default
  3. 03Manage email settings across workflows

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/novuhq/skills --skill novu-manage-preferences

After installing, type/novu-manage-preferencesin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
preferences-ui-examples.md
subscriber-preferences-examples.md
workflow-preferences-examples.md

Details

From the project README

Manage Preferences

Novu has a two-level preference system:

  1. Workflow defaults — configured in the dashboard for UI based workflows or via code in framework based workflows, apply to all subscribers.
  2. Subscriber overrides — set by end users, override workflow defaults

Workflow-Level Preferences

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-integration for the full Framework setup, Bridge Endpoint, step controls, and deployment.

Channel Types
ChannelDescription
emailEmail notifications
smsSMS text messages
pushMobile/web push notifications
chatSlack, Discord, Teams, etc.
inAppIn-app Inbox notifications
Read-Only Preferences

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 one

These are different mechanisms with different guarantees. See design-workflow/references/severity-and-critical.md for the full matrix.

FlagWhat it does
preferences.all.readOnly: trueUI 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.

Optional (Subscriber-Editable) Preferences
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
    },
  },
});

Subscriber-Level Preferences

Subscribers can override workflow defaults (unless readOnly: true).

Get Subscriber Preferences
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",
});
Update Subscriber Preferences
await novu.subscribers.preferences.update(
  {
    workflowId: "weekly-newsletter",
    channels: {
      email: false,   // opt out of email
      inApp: true,    // keep in-app
    },
  },
  "subscriber-123"
);
Global Preferences

Update preferences across all workflows by omitting workflowId:

await novu.subscribers.preferences.update(
  {
    channels: {
      sms: false,  // disable SMS for all workflows
    },
  },
  "subscriber-123"
);

Preference Resolution Order

When Novu determines whether to deliver a notification:

  1. Subscriber workflow preference (most specific) — subscriber's override for this specific workflow
  2. Subscriber global preference — subscriber's default across all workflows
  3. Workflow default — developer-defined default in code
  4. System default — all channels enabled

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.

Preferences UI Component

React
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.

Standalone Preferences

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>
  );
}

Common Patterns

Critical Alerts (Always On)
preferences: {
  all: { enabled: true, readOnly: true },
}

Subscribers cannot opt out. Use for security alerts, payment notifications, legal notices.

Marketing (Opt-Out Friendly)
preferences: {
  all: { enabled: true, readOnly: false },
  channels: {
    email: { enabled: true },
    sms: { enabled: false },
  },
}

Subscribers can toggle channels. SMS is off by default.

In-App Only by Default
preferences: {
  all: { enabled: false },
  channels: {
    inApp: { enabled: true },
  },
}

Only in-app is on. Subscribers can enable other channels if desired.

Common Pitfalls

  1. readOnly: true is per-workflow, not per-channel — you set readOnly on the all level. Individual channels inherit it.
  2. Subscriber overrides don't apply to readOnly workflows — if the workflow is read-only, subscriber preferences are ignored.
  3. enabled: false in the workflow default means the channel is off — subscribers can still enable it (unless readOnly: true).
  4. The Preferences UI only shows non-readOnly workflows — read-only workflows are hidden from the subscriber's preference panel.
  5. Global preferences apply across all non-readOnly workflows — they're a convenient "disable all email" setting, but workflow-specific preferences take precedence.

References

Comments

Markdown supported