Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MrRobot993's avatar

Echo React persist notifications

Hi I'm taking a notifications from a private channel with Echo and pusher and I load incoming notification in my LayoutApp in this way:

export default function LayoutApp({ auth, header, children }) {
    //const {notifications} = usePage().props;

    const [notifications, setNotifications] = useState([]);

     if(auth.user) {
        useEffect(() => {
            window.Echo.private(`App.Models.User.${auth.user.id}`).notification(notification => {
                console.log(notification);
                setNotifications(() => [...notifications, notification]);
            })
        });
    }

it work's but when I change the page the notifications come back to 0. Someone can help me? ty

0 likes
12 replies
Sinnbeck's avatar

@MrRobot993 but how? Change it in the address bar? Or you have a link? If it's a link, show the code for it

Sinnbeck's avatar

@MrRobot993 ok if you don't want to show it, we will never get anywhere. Hope you figure it out :)

MrRobot993's avatar

@Sinnbeck I think is not the core of problem I only change route I can’t post all pages it’s a lot of code.. I only change route and they come back 0.. the state reset

Sinnbeck's avatar

Just making sure. If the user hits f5 the notifications are supposed to disappear or?

MrRobot993's avatar

@Sinnbeck I want to test your suggest but yeasterday I pushed into the repository and today after pull with another pc the data are not sent to pusher.. i'm a bit confused

MrRobot993's avatar

@Sinnbeck I changed only pc and if I try to post order and send notification to pusher i get: cURL error 60: SSL certificate problem: unable to get local issuer certificate

MrRobot993's avatar

@Sinnbeck Ok I have solved the problem on windows inserting a carcert.pem in php.ini. Now I'm trying to solve the notifications problem. I have setted persistent layout in all pages, and moved in navbar the Echo function. If i reload the page the notifications persists but if I change page they return back 0

LayoutApp
import Navbar from '@/Components/Navbar';
import { usePage, useRemember } from '@inertiajs/inertia-react';
import { useEffect, useState } from 'react';


export default function LayoutApp({ header, children }) {
    //const {notifications} = usePage().props;
    const {auth, errors} = usePage().props;

    return (
        <>
            <div className="min-h-screen bg-gray-100 flex flex-col pb-6">
                <Navbar auth={auth}/>

                {header && (
                    <header className="bg-white shadow">
                        <div className="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">{header}</div>
                    </header>
                )}

                <main>{children}</main>
            </div>
        </>
    );
}
Navbar
import { Fragment } from 'react'
import { useRemember } from '@inertiajs/inertia-react';
import { useEffect, useState } from 'react';
import { Disclosure, Menu, Transition, Popover } from '@headlessui/react'
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'
import NavLink from '@/Components/NavLink';
import ProfileLinks from './ProfileLinks';


const navigation = [
  { name: 'Sfoglia Menu', href: route('show-menus-page'), current: route().current('show-menus-page') },
 // { name: 'Ordina', href: route('show-order-menus'), current: route().current('show-order-menus') },
]

function classNames(...classes) {
  return classes.filter(Boolean).join(' ')
}

export default function Navbar({auth}) {

    const [notifications, setNotifications] = useRemember([]);

    if(auth.user) {
    useEffect(() => {
        window.Echo.private(`App.Models.User.${auth.user.id}`).notification(notification => {
            console.log(notification);
            setNotifications(() => [...notifications, notification]);
        })
    });
    }


    const notificationsCount = notifications !== null ? notifications.length : 0;


    return (
        <Disclosure as="nav" className="bg-gray-800">
        {({ open }) => (
            <>
            <div className="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8">
                <div className="relative flex h-16 items-center justify-between">
                <div className="absolute inset-y-0 left-0 flex items-center sm:hidden">
                    {/* Mobile menu button*/}
                    <Disclosure.Button className="inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white">
                    <span className="sr-only">Open main menu</span>
                    {open ? (
                        <XMarkIcon className="block h-6 w-6" aria-hidden="true" />
                    ) : (
                        <Bars3Icon className="block h-6 w-6" aria-hidden="true" />
                    )}
                    </Disclosure.Button>
                </div>
                <div className="flex flex-1 items-center justify-center sm:items-stretch sm:justify-start">
                    <div className="flex flex-shrink-0 items-center">
                    <img
                        className="block h-8 w-auto lg:hidden"
                        src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500"
                        alt="Your Company"
                    />
                    <img
                        className="hidden h-8 w-auto lg:block"
                        src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500"
                        alt="Your Company"
                    />
                    </div>
                    <div className="hidden sm:ml-6 sm:block">
                    <div className="flex space-x-4">
                        {navigation.map((item) => (
                        <a
                            key={item.name}
                            href={item.href}
                            className={classNames(
                            item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white',
                            'px-3 py-2 rounded-md text-sm font-medium'
                            )}
                            aria-current={item.current ? 'page' : undefined}
                        >
                            {item.name}
                        </a>
                        ))}
                    </div>
                    </div>
                </div>
                <div className="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0">
                    {/* Profile dropdown */}
                    <Menu as="div" className="relative ml-3">
                    {auth.user ? (
                    <>
                    <div className='flex items-center md:ml-6'>
                        <Popover className="relative">
                        <Popover.Button
                        className={`
                        ${open ? '' : 'text-opacity-90'}
                        group inline-flex items-center rounded-full px-2 py-2 text-base font-medium text-white hover:text-opacity-100 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800`}
                        >
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
                            <path strokeLinecap="round" strokeLinejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" />
                            </svg>
                            <span className="absolute -right-1 -top-1 badge mb-3 bg-blue-800 rounded-full px-2 py-1 text-center object-right-top text-white text-xs">{notificationsCount}</span>
                        </Popover.Button>
                        <Transition
                            as={Fragment}
                            enter="transition ease-out duration-200"
                            enterFrom="opacity-0 translate-y-1"
                            enterTo="opacity-100 translate-y-0"
                            leave="transition ease-in duration-150"
                            leaveFrom="opacity-100 translate-y-0"
                            leaveTo="opacity-0 translate-y-1"
                        >
                            <Popover.Panel className="absolute w-52 -left-16 z-10 mt-3 w-md max-w-md -translate-x-1/2 transform px-4 sm:px-0 lg:max-w-3xl">
                            <div className="overflow-hidden rounded-lg shadow-lg ring-1 ring-black ring-opacity-5">
                                <div className="relative bg-gray-50 p-4">
                                {notifications.map((notification) => (
                                    <a
                                    key={notification.id}
                                    href={route('new-orders')}
                                    className="flow-root rounded-md p-2 transition duration-150 ease-in-out hover:bg-gray-100 focus:outline-none focus-visible:ring focus-visible:ring-orange-500 focus-visible:ring-opacity-50"
                                    >
                                    <div className="">
                                        <p className="text-sm font-medium text-gray-900">
                                        <b>Nuovo ordine</b> tavolo: <b>{notification.order.table}</b>
                                        </p>
                                    </div>
                                    </a>
                                ))}
                                </div>
                            </div>
                            </Popover.Panel>
                        </Transition>
                        </Popover>
                        <div>
                        <Menu.Button className="flex ml-3 md:ml-5 rounded-full bg-gray-800 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800">
                            <span className="sr-only">Open user menu</span>
                            <img
                                className="h-8 w-8 rounded-full"
                                src={auth.user.avatar ? '/storage/avatars/'+auth.user.avatar : "https://ui-avatars.com/api/?name="+auth.user.name+auth.user.surname+"?rounded=true"}
                                alt=""
                            />
                        </Menu.Button>
                        </div>
                    </div>
                    <Transition
                        as={Fragment}
                        enter="transition ease-out duration-100"
                        enterFrom="transform opacity-0 scale-95"
                        enterTo="transform opacity-100 scale-100"
                        leave="transition ease-in duration-75"
                        leaveFrom="transform opacity-100 scale-100"
                        leaveTo="transform opacity-0 scale-95"
                    >
                        <Menu.Items className="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
                        <Menu.Item>
                            <ProfileLinks active={route().current('dashboard')} href={route('dashboard')} children="Dashboard" />
                        </Menu.Item>
                        <Menu.Item>
                            <ProfileLinks active={route().current('profile.edit')} href={route('profile.edit')} children="Profilo" />
                        </Menu.Item>
                        <Menu.Item>
                            <ProfileLinks active={route().current('login')} href={route('logout')} method="post" children="Logout" />
                        </Menu.Item>
                        </Menu.Items>
                    </Transition>
                    </>
                    ) : (
                    <>
                        <NavLink active={route().current('login')} href={route('login')} children="Login"/>
                        <NavLink active={route().current('register')} href={route('register')} children="Registrati"/>
                    </>
                    )}
                    </Menu>
                </div>
                </div>
            </div>

            <Disclosure.Panel>
                <div className="space-y-1 px-2 pt-2 pb-3">
                {navigation.map((item) => (
                    <Disclosure.Button
                    key={item.name}
                    as="a"
                    href={item.href}
                    className={classNames(
                        item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white',
                        'block px-3 py-2 rounded-md text-base font-medium'
                    )}
                    aria-current={item.current ? 'page' : undefined}
                    >
                    {item.name}
                    </Disclosure.Button>
                ))}
                </div>
            </Disclosure.Panel>
            </>
        )}
        </Disclosure>
    )
}

Please or to participate in this conversation.