Headless using Novu/JS

I am using the following snippet on our react js app const novu = useMemo(() => { return new Novu({ applicationIdentifier: applicationId, subscriberId: memberId, }); }, [applicationId, memberId]); novu.on('notifications.notification_received', data => { console.log('new notification =>', data); getNotifications(1); }); I see websockets being called in the inspector but the event does NOT get fired. Am I missing anything?
14 Replies
Mark Garcia
Mark GarciaOP5d ago
When I call list, it's always empty const getNovuNotifications = useCallback(async () => { const {data} = await novu.notifications.list({limit: 30}); setList(data?.notifications); console.log('NOVU-list', data?.notifications); }, [novu]); I know the subsciber has existing notifications when I call the novu api. https://api.novu.co/v1/messages?subscriberId=759291&page=0&limit=15 This is the default websocket url: wss://ws.novu.co/socket.io
Pawan Jain
Pawan Jain4d ago
@Mark Garcia Could you please share complete code?
Mark Garcia
Mark GarciaOP4d ago
parts redacted but this is how it's implemented in a Provider component export const GlobalNoticeProvider = ({ children, }: GlobalNoticeProviderProps): JSX.Element => { const applicationId = process.env.NEXT_PUBLIC_NOVU_APPLICATION_ID as string; const memberId = getUserIdFromStoredToken() as string; const novu = useMemo(() => { return new Novu({ applicationIdentifier: applicationId, subscriberId: memberId, }); }, [applicationId, memberId]); novu.on('notifications.notification_received', data => { console.log('new notification =>', data); getNotifications(1); }); const getNovuNotifications = useCallback(async () => { const {data} = await novu.notifications.list({limit: 30}); setList(data?.notifications); console.log('NOVU-list', data?.notifications); }, [novu]);

return ( <GlobalNoticeContext.Provider value={value}> <> {openNotice && ( <NoticeDialog notice={openNotice} onClose={handleOnClose} /> )} {children} </> </GlobalNoticeContext.Provider> ); }
Pawan Jain
Pawan Jain4d ago
Thanks. I will take a look
Mark Garcia
Mark GarciaOP4d ago
Hi @Pawan Jain just following up on this.
Pawan Jain
Pawan Jain3d ago
@Mark Garcia Checkout this code 👇🏻
"use client";

import { Novu } from "@novu/js";
import { useMemo, useState, useEffect } from "react";
import { env } from "@/env.mjs";

export const HeadlessNotification = () => {
const [list, setList] = useState<any[]>([]);
const applicationId = env.NEXT_PUBLIC_NOVU_APPLICATION_IDENTIFIER;
const memberId = env.NEXT_PUBLIC_SUBSCRIBER_ID;

const novu = useMemo(() => {
console.log("applicationId", applicationId);
return new Novu({
applicationIdentifier: applicationId,
subscriberId: memberId,
});
}, [applicationId, memberId]);

const getNovuNotifications = async () => {
try {
const { data } = await novu.notifications.list({
limit: 30,
useCache: false,
});

setList(data?.notifications || []);
console.log("NOVU-list", data?.notifications);
} catch (error) {
console.error("Error fetching notifications:", error);
}
};

useEffect(() => {
const handleNewNotification = (data: any) => {
console.log("new notification =>", data);
getNovuNotifications();
};

// Set up event listener
novu.on("notifications.notification_received", handleNewNotification);

// Initial fetch
getNovuNotifications();
}, [novu]);

return (
<div>
{list.length > 0 ? (
list.map((item) => (
<div key={item.id} dangerouslySetInnerHTML={{ __html: item.body }} />
))
) : (
<div>No notifications</div>
)}
</div>
);
};
"use client";

import { Novu } from "@novu/js";
import { useMemo, useState, useEffect } from "react";
import { env } from "@/env.mjs";

export const HeadlessNotification = () => {
const [list, setList] = useState<any[]>([]);
const applicationId = env.NEXT_PUBLIC_NOVU_APPLICATION_IDENTIFIER;
const memberId = env.NEXT_PUBLIC_SUBSCRIBER_ID;

const novu = useMemo(() => {
console.log("applicationId", applicationId);
return new Novu({
applicationIdentifier: applicationId,
subscriberId: memberId,
});
}, [applicationId, memberId]);

const getNovuNotifications = async () => {
try {
const { data } = await novu.notifications.list({
limit: 30,
useCache: false,
});

setList(data?.notifications || []);
console.log("NOVU-list", data?.notifications);
} catch (error) {
console.error("Error fetching notifications:", error);
}
};

useEffect(() => {
const handleNewNotification = (data: any) => {
console.log("new notification =>", data);
getNovuNotifications();
};

// Set up event listener
novu.on("notifications.notification_received", handleNewNotification);

// Initial fetch
getNovuNotifications();
}, [novu]);

return (
<div>
{list.length > 0 ? (
list.map((item) => (
<div key={item.id} dangerouslySetInnerHTML={{ __html: item.body }} />
))
) : (
<div>No notifications</div>
)}
</div>
);
};
Mark Garcia
Mark GarciaOP3d ago
Thanks @Pawan Jain but it still does NOT trigger the new_notification event. I've created custom hook for this implementation import {useEffect, useMemo} from 'react'; import {useNotification} from '@hooks/useNotification'; import {Novu} from '@novu/js'; import {useAuthentication} from './useAuthentication'; export const useNovuEvents = () => { const {getUserIdFromStoredToken} = useAuthentication(); const {getNotifications} = useNotification(); const applicationId = process.env.NEXT_PUBLIC_NOVU_APPLICATION_ID as string; const memberId = getUserIdFromStoredToken() as string; const novu = useMemo(() => { return new Novu({ applicationIdentifier: applicationId, subscriberId: memberId, }); }, [applicationId, memberId]); useEffect(() => { // Set up event listener novu.on('notifications.notification_received', data => { console.log('new notification =>', data); getNotifications(1); }); }, [novu, getNotifications]); }; Then calling this in our GlobalNotice provider useNovuEvents();
Mark Garcia
Mark GarciaOP3d ago
I can confirm websocket is established and the useEffect hook gets called.
No description
Mark Garcia
Mark GarciaOP3d ago
This is the generated websocket domain: wss://ws.novu.co/socket.io/?token=
Novu_Bot
Novu_Bot3d ago
@Mark Garcia, you just advanced to level 2!
Mark Garcia
Mark GarciaOP3d ago
curl --location 'https://api.novu.co/v1/events/trigger' \
--header 'Authorization: ApiKey {ApiKey}' \
--header 'Content-Type: application/json' \
--data '{"name":"CampaignRegistration","to": [{"subscriberId":"759291" }],"payload":{"Id":"123456","MemberId":759291,"Description":"Testing my new notification here.","Title":"New campaign title 7!","CampaignId":"1","CampaignUrl":"https://test.com","Market":"AUS","Type": "CampaignRegistration"}}'
curl --location 'https://api.novu.co/v1/events/trigger' \
--header 'Authorization: ApiKey {ApiKey}' \
--header 'Content-Type: application/json' \
--data '{"name":"CampaignRegistration","to": [{"subscriberId":"759291" }],"payload":{"Id":"123456","MemberId":759291,"Description":"Testing my new notification here.","Title":"New campaign title 7!","CampaignId":"1","CampaignUrl":"https://test.com","Market":"AUS","Type": "CampaignRegistration"}}'
Above is the sample curl I send out to trigger new notification but 'notifications.notification_received' event is not picking it up and it does NOT fire.
Mark Garcia
Mark GarciaOP3d ago
I confirm that I receive the notification.
No description
Pawan Jain
Pawan Jain2d ago
@Mark Garcia Did not get chance to check with wrapping this in hooks What is your usecase with wrapping it over a hook?
Mark Garcia
Mark GarciaOP2d ago
We want to eventually create a component that allows for multiple notification provider so we would like to place each provider in its own custom hook. But I also did the SUGGESTED implementation and I got the same result. Do you have any reports of anything blocking your websocket requests or interferring with it? I'll try to create a new project and try this there.

Did you find this page helpful?