Docs
Systhema Design (opens in new tab)
Unreleased

SysthemaProvider

Wrap your app in SysthemaProvider to seed the client config, mount the scroll listeners and the cookie banner, and set the frontend locale.

On this page

SysthemaProvider goes once around your application, inside <body>. It renders no element of its own. It seeds the browser with the Systhema config and the client-token snapshot, mounts the three scroll listeners, and mounts the cookie consent banner when you pass a config. The Next.js provider also supplies the frontend locale and messages to Systhema's client components.

The provider has no visual output, so this page has no live preview. Every preview on this site runs inside one.

ImportLink to this section

import { SysthemaProvider } from '@systhemaui/next'

In a React app without Next.js, import it from @systhemaui/react. The two providers take different props; see Next.js.

UsageLink to this section

app/layout.tsx
import { SysthemaProvider } from '@systhemaui/next'
import type { ReactNode } from 'react'

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        <SysthemaProvider>{children}</SysthemaProvider>
      </body>
    </html>
  )
}

Put the header, <main> and the footer directly inside the provider, so they stay direct children of <body> (the header's mobile menu relies on that).

What it rendersLink to this section

In order, before your children:

  1. SysthemaConfigServer, which resolves the config and the client-token snapshot on the server and hands both to SysthemaConfigClient, so client components can read token values without shipping the token dataset.
  2. AosListener, which reveals .aos elements as they scroll into view.
  3. ScrollClassesListener, which keeps scroll-state classes such as scroll-on-top and is-scrolling-down on <body>.
  4. ParallaxListener, which drives .parallax media.
  5. CookieConsentBanner, only when cookieConsent is a config with enabled: true.

See Listeners for what each listener does and CookieConsentBanner for the banner.

ExamplesLink to this section

Resolve the config with getSysthemaCookieConsentConfig(). It returns null when cookieConsent.enabled is not true in systhema.config.ts, and the provider then leaves the banner out of the tree.

app/layout.tsx
import { SysthemaProvider, getSysthemaCookieConsentConfig } from '@systhemaui/next'
import type { ReactNode } from 'react'

export default function RootLayout({ children }: { children: ReactNode }) {
  const cookieConsent = getSysthemaCookieConsentConfig()
  return (
    <html lang="en">
      <body data-theme="default">
        <SysthemaProvider cookieConsent={cookieConsent}>{children}</SysthemaProvider>
      </body>
    </html>
  )
}

In a React app, import getSysthemaCookieConsentConfig from @systhemaui/core/client. See Cookie consent for the whole setup.

With a frontend localeLink to this section

On a multilingual Next.js site, pass the active locale and, for a locale without a shipped catalog, the resolved messages. Systhema's client components, such as the deferred video controls, then render their built-in text in that language.

app/[locale]/layout.tsx
import { SysthemaProvider } from '@systhemaui/next'
import type { ReactNode } from 'react'

type Props = { children: ReactNode; params: Promise<{ locale: string }> }

export default async function LocaleLayout({ children, params }: Props) {
  const { locale } = await params
  return (
    <html lang={locale}>
      <body>
        <SysthemaProvider locale={locale}>{children}</SysthemaProvider>
      </body>
    </html>
  )
}

Without locale the provider stays on English, the locale-off default. fallbackToEnglish uses English text for a locale Systhema ships no catalog for, instead of requiring one. See Messages and catalogs.

Resetting the listenersLink to this section

The React provider takes a resetKey and passes it to the three listeners. Change it (for example to the current path) when your router swaps pages without unmounting the provider, so the listeners pick up the new page's elements:

import { SysthemaProvider } from '@systhemaui/react'
import type { ReactNode } from 'react'

export function App({ path, children }: { path: string; children: ReactNode }) {
  return <SysthemaProvider resetKey={path}>{children}</SysthemaProvider>
}

The Next.js provider has no resetKey: its listeners reset on every route change by themselves.

Mounting the parts yourselfLink to this section

Render SysthemaConfigServer and the listeners directly when you need a different arrangement, for example listeners only on some routes. SysthemaConfigServer must come before any Systhema client component. See Provider and listeners in Next.js.

PropsLink to this section

@systhemaui/reactLink to this section

PropTypeDefaultDescription
children (required)ReactNode-
resetKeystring | number | null-
cookieConsentSysthemaCookieConsentConfig | null-Cookie consent runtime config. Pass null (or omit) to disable the banner. Pass a resolved SysthemaCookieConsentConfig (with enabled: true) to render it.

@systhemaui/nextLink to this section

PropTypeDefaultDescription
children (required)ReactNode-
cookieConsentSysthemaCookieConsentConfig | null-
localestring'en'Active frontend locale. Omit it to preserve the locale-off English default.
messagesReadonly<Record<string, unknown>>-Resolved built-in and consumer message catalog for this request.
fallbackToEnglishbooleanfalseExplicitly use English Systhema copy for an unshipped locale.

HTML and CSSLink to this section

There is no markup to copy. In an HTML project, the bundled vanilla listeners do the listeners' work; see Vanilla JavaScript.

Next.jsLink to this section

@systhemaui/next ships its own SysthemaProvider:

  • Its listeners are the Next versions, which re-run on route changes through usePathname(). There is no resetKey.
  • It takes locale, messages and fallbackToEnglish, and wraps the app in the frontend messages provider that Systhema's client components read.
  • cookieConsent works the same way.

See Provider and listeners in Next.js.

AccessibilityLink to this section

SysthemaProvider renders no landmarks. Render <main id="main-content"> around the page content and the skip link as the first element in <body>; the page templates do both. The listeners respect prefers-reduced-motion: reveals snap to their end state. See Landmarks and the skip link and Accessibility utilities.