Vanilla JS bundle
The listeners bundle for projects without React.
On this page
HTML projects without React get Systhema's client-side behaviour from one script in @systhemaui/core: scroll reveals, parallax, scroll classes, the accordion, the header menu and the cookie consent banner. It is the plain-JavaScript counterpart of the React listeners, and it starts itself, so the markup and classes from the rest of these pages work without any code of yours.
Loading the bundleLink to this section
Add the script at the end of <body>:
<script src="node_modules/@systhemaui/core/dist/js/bundle.global.js" defer></script>bundle.global.js is a minified IIFE (about 55 KB) that registers every listener when it loads and exposes the functions on window.SysthemaJS. Copy it into your public folder if your server doesn't serve node_modules.
With a bundler, import the ESM build instead. Importing it has the same effect, so a bare import is enough:
import '@systhemaui/core/js'What it doesLink to this section
| Function | Starts on load | Behaviour |
|---|---|---|
initAos() | yes | Adds animated to .aos / .animates-on-scroll elements as they scroll in, and removes it again below the fold unless they have animates-once. See Animation. |
initParallax() | yes | Moves .parallax media against the scroll. See Parallax. |
initScrollClasses() | yes | Toggles scroll-on-top (page at the top) and is-scrolling-down (after 150px of downward scroll) on <body>. |
initAccordion() | yes | A click on .accordion-title toggles its .accordion: data-state, data-expanded, and the title's aria-expanded and content's aria-hidden. |
initHeader() | yes | A click on .header-navigation-menu-toggle or .menu-toggle opens and closes .menu (is-open); the backdrop and in-menu links close it, and button.menu-navigation-item toggles its sub-navigation. |
initFixLoadTransitions() | yes | Removes no-transition from <body> on load, so transitions don't play while the page loads. |
initCookieConsent() | yes | Shows the cookie banner when window.__SYSTHEMA_COOKIE_CONSENT__.enabled is true. See below. |
The accordion and header listeners use event delegation on <body>, so they work for markup added later. addAnimationClasses() and updateParallax() run one pass of the scroll-reveal and parallax engines by hand.
To suppress transitions until the page has loaded, start with the class on <body> and add the matching CSS:
<body class="no-transition">@layer app {
.no-transition,
.no-transition * {
transition: none !important;
}
}Content swapped in laterLink to this section
The listeners pick up new markup on their own in most cases: the click handlers are delegated, and the scroll-reveal and parallax engines re-measure on every scroll. The bundle also listens for htmx's htmx:afterSwap event to re-check scroll reveals and reset the accordion and menu state. After any other kind of DOM swap, call the engines once:
window.SysthemaJS.addAnimationClasses()
window.SysthemaJS.updateParallax()Differences from the React listenersLink to this section
The bundle and the React listeners read the same classes, but the scroll-reveal engine is older and simpler:
- It measures on every
scroll,resizeandtouchmoveevent instead of using anIntersectionObserver. - On viewports 768px and wider, an element reveals when its vertical middle passes the bottom of the viewport; on narrower ones, when its top is 20px inside. The React
AosListenerreveals at 20px everywhere. - An element re-arms as soon as its top is below the fold, without the React listener's extra margin.
Both honour prefers-reduced-motion the same way: the CSS snaps reveals to their end state, and initParallax() writes no transform and follows the preference live.
Cookie consentLink to this section
Set the configuration before the bundle loads. The banner code (vanilla-cookieconsent) is imported only when enabled is true, so a page without consent pays nothing beyond the bundle itself.
<script>
window.__SYSTHEMA_COOKIE_CONSENT__ = {
enabled: true,
policyLinks: [{ label: 'Privacy policy', url: '/privacy-policy' }],
}
</script>
<script src="node_modules/@systhemaui/core/dist/js/bundle.global.js" defer></script>A link to #cookie-settings reopens the preferences, and theme forces a color-system mode on the banner. The full option list is in Cookie consent.