Novu logo

novu

Multi-channel notification infrastructure and workflows

$ npx docs2skills add novu-notifications
SKILL.md

Novu

Multi-channel notification infrastructure and workflows

What this skill does

Novu provides a complete notification infrastructure that unifies email, SMS, push notifications, and in-app messaging into a single platform. It eliminates the complexity of managing multiple notification providers by offering workflow orchestration, template management, subscriber handling, and delivery tracking through a unified API.

Developers use Novu to build scalable notification systems without vendor lock-in, reduce integration complexity across multiple channels, and maintain consistent messaging experiences. It solves the problem of notification sprawl by providing a centralized hub for all notification logic, from simple transactional emails to complex multi-step notification workflows with conditions, delays, and channel fallbacks.

Prerequisites

  • Node.js 16+ or Python 3.7+ (for server-side SDKs)
  • Novu account with API key from dashboard.novu.co
  • Provider credentials (SendGrid, Twilio, Firebase, etc.) for channels you'll use
  • React 16.8+ (for in-app notification components)

Quick start

npm install @novu/node @novu/notification-center-react
// Server-side: Trigger notification
import { Novu } from '@novu/node';

const novu = new Novu(process.env.NOVU_API_KEY);

await novu.trigger('welcome-email', {
  to: {
    subscriberId: 'user-123',
    email: 'john@example.com',
  },
  payload: {
    firstName: 'John',
    organizationName: 'Acme Corp'
  }
});

// Client-side: In-app notifications
import { NovuProvider, NotificationBell } from '@novu/notification-center-react';

function App() {
  return (
    <NovuProvider subscriberId="user-123" applicationIdentifier="APP_ID">
      <NotificationBell />
    </NovuProvider>
  );
}

Core concepts

Workflows: Multi-step notification sequences with conditions, delays, and channel routing. Define once in dashboard or code, trigger from anywhere.

Subscribers: Recipients with unique IDs and channel preferences. Automatically managed with upsert behavior.

Templates: Reusable content with variable substitution. Support Handlebars syntax and conditional logic.

Providers: Channel integrations (SendGrid, Twilio, Firebase). Novu handles provider failover and routing.

Triggers: Events that start workflows. Include payload data for template personalization.

Channels: Email, SMS, push, in-app, chat. Each with provider-specific configurations.

Key API surface

// Triggering notifications
await novu.trigger(templateId, { to, payload, overrides })
await novu.bulkTrigger([{ templateId, to, payload }])

// Subscriber management  
await novu.subscribers.identify(subscriberId, data)
await novu.subscribers.update(subscriberId, updates)
await novu.subscribers.setCredentials(subscriberId, providerId, credentials)
await novu.subscribers.updatePreferences(subscriberId, templateId, preferences)

// Message management
await novu.messages.list({ subscriberId, channel })
await novu.messages.markAs(messageId, { seen: true, read: true })
await novu.messages.remove(messageId)

// Event tracking
await novu.events.trigger(name, { subscriberId, payload })
await novu.events.cancel(transactionId)

// Workflow management
await novu.workflows.create(workflowData)
await novu.workflows.update(workflowId, updates)

Common patterns

User onboarding sequence:

await novu.trigger('user-onboarding', {
  to: { subscriberId: userId, email: userEmail },
  payload: { 
    userName: user.name,
    activationUrl: `${baseUrl}/activate/${token}`
  }
});

Order status updates with fallback:

await novu.trigger('order-shipped', {
  to: { subscriberId: customerId },
  payload: { 
    orderNumber: order.id,
    trackingUrl: order.trackingUrl,
    estimatedDelivery: order.estimatedDelivery
  },
  overrides: {
    sms: { 
      to: customer.phoneNumber 
    }
  }
});

Bulk notifications:

const triggers = users.map(user => ({
  name: 'weekly-digest',
  to: { subscriberId: user.id, email: user.email },
  payload: { 
    digestContent: user.weeklyDigest,
    unsubscribeUrl: `${baseUrl}/unsubscribe/${user.token}`
  }
}));

await novu.bulkTrigger(triggers);

Real-time in-app notifications:

import { useSocket, useNotifications } from '@novu/notification-center-react';

function NotificationsList() {
  const { notifications, markAsRead } = useNotifications();
  
  return (
    <div>
      {notifications.map(notification => (
        <div key={notification._id} onClick={() => markAsRead(notification._id)}>
          {notification.content}
        </div>
      ))}
    </div>
  );
}

Configuration

Environment variables:

NOVU_API_KEY=your_api_key_here
NOVU_APPLICATION_IDENTIFIER=your_app_id  # For client-side

Provider setup (in dashboard or API):

await novu.integrations.create({
  providerId: 'sendgrid',
  channel: 'email',
  credentials: {
    apiKey: process.env.SENDGRID_API_KEY,
    from: { email: 'noreply@company.com', name: 'Company Name' }
  }
});

Subscriber preferences:

await novu.subscribers.updatePreferences(subscriberId, templateId, {
  enabled: true,
  channels: {
    email: true,
    sms: false,
    in_app: true
  }
});

Best practices

  • Use semantic workflow names that describe business events, not technical actions
  • Always include unsubscribe mechanisms in email workflows
  • Set up provider fallbacks for critical notifications
  • Batch trigger calls when sending to multiple users simultaneously
  • Use subscriber preferences to respect user communication choices
  • Include correlation IDs in payloads for debugging and analytics
  • Test workflows in development environment before production deployment
  • Monitor delivery rates and failed notifications through dashboard
  • Use workflow delays judiciously to avoid overwhelming users
  • Implement proper error handling for trigger failures

Gotchas and common mistakes

subscriberId must be consistent: Once set, always use the same subscriberId for a user across all triggers. Changing it creates a new subscriber.

Payload nesting limits: Template variables support up to 3 levels of nesting. Deeper objects get flattened or ignored.

Provider rate limits: Novu doesn't automatically handle provider rate limits. Configure delays in workflows for high-volume sends.

Workflow caching: Changes to workflows in dashboard take up to 2 minutes to propagate. Use workflow override during development.

Client-side security: Never use server API key in frontend code. Use applicationIdentifier for client-side components.

Duplicate triggers: Calling trigger multiple times with same transactionId only sends once. Use unique transactionId for each send.

Template compilation errors: Invalid Handlebars syntax fails silently. Test templates with sample data before production.

Channel prerequisites: In-app notifications require subscriber to be online. Use fallback channels for critical messages.

Bulk trigger limits: Maximum 100 events per bulkTrigger call. Batch larger lists into multiple calls.

Provider credentials: Wrong provider credentials cause silent failures. Check integration status in dashboard.

Timezone handling: All dates in workflows use UTC. Convert user timezones in payload data, not workflow configuration.

Message retention: Messages older than 30 days are automatically deleted. Export important delivery data regularly.