Provider and listeners in Next.js
SysthemaProvider in the App Router, why the listeners need next/navigation, and cookie consent.
On this page
The @systhemaui/next SysthemaProvider is the recommended way to set up Systhema in a Next app. It bundles:
SysthemaConfigServer(from@systhemaui/react) — server-side configuration.AosListener(Next version withusePathname()).ScrollClassesListener(Next version withusePathname()).ParallaxListener(Next version withusePathname()).CookieConsentBanner(when a non-nullcookieConsentconfig is passed).
For the props and the React provider, see SysthemaProvider.
UsageLink to this section
import { SysthemaProvider } from '@systhemaui/next'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<SysthemaProvider>{children}</SysthemaProvider>
</body>
</html>
)
}Cookie consentLink to this section
With cookie consent enabled — getSysthemaCookieConsentConfig() returns null when the feature is disabled, so the banner stays out of the tree at zero runtime cost:
import { SysthemaProvider, getSysthemaCookieConsentConfig } from '@systhemaui/next'
export default function RootLayout({ children }: { children: React.ReactNode }) {
const cookieConsent = getSysthemaCookieConsentConfig()
return (
<html lang="en">
<body data-theme="default">
<SysthemaProvider cookieConsent={cookieConsent}>{children}</SysthemaProvider>
</body>
</html>
)
}For Payload-based projects, the <RootLayout> from @systhemaui/payload/next resolves the cookie consent config from the general-settings global server-side and forwards it through <SysthemaProvider> automatically — see Rendering pages and Cookie consent.
Existing Next projects upgrading via systhema upgrade get this wired automatically by the add-cookie-consent-to-next-layout codemod (Next-only) or add-payload-instance-to-root-layout codemod (Payload).
Mounting the parts manuallyLink to this section
If you prefer fine-grained control, render the parts manually:
import { SysthemaConfigServer } from '@systhemaui/react'
import { AosListener, ParallaxListener, ScrollClassesListener } from '@systhemaui/next'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<SysthemaConfigServer />
<AosListener />
<ParallaxListener />
<ScrollClassesListener />
{children}
</body>
</html>
)
}But SysthemaProvider is the recommended path.
Why the listeners need next/navigationLink to this section
Standard JS event listeners work in multi-page apps:
window.addEventListener('load', initializeAnimations)
document.addEventListener('DOMContentLoaded', initializeAnimations)But with next/link:
- The browser doesn't fire
loadorDOMContentLoadedon navigation. - The page content changes, but the listeners aren't notified.
- Animations, parallax, and scroll classes don't re-initialise.
The fix:
import { usePathname } from 'next/navigation'
import { useEffect } from 'react'
const MyListener = () => {
const pathname = usePathname()
useEffect(() => {
initializeAnimations()
}, [pathname])
return null
}That's exactly how each Next listener in this package is implemented. See Listeners for each one.