Skip to main content

Get started

JavaScript modules

What each optional script adds, how to load only the one you need, and what a page does without them.

Every LUZ page works without JavaScript. The scripts add behaviour on top: copying, highlighting, a cycling color mode button, players, tabs and sorting a table. The catalog adds its own: search, the cookie banner, the time of day for the color mode, a timeline and the scroll spy of the sidebar.

Load all of it, or one module

HTML
<script type="module" src="https://cdn.jsdelivr.net/npm/@luz-ds/core@0.3.0/dist/luz.min.js"></script>
JS
import { initTabs } from "@luz-ds/core/tabs";
initTabs();
  • luz.js starts every module when the page loads.
  • Importing a single module does nothing until you call its init function.
  • midi.js and table-sort.js are chunks of their own: luz.js loads each one on demand, and only on a page that needs it.
  • theme-mode.js is another: luz.js loads it only on a page with a <luz-theme-mode>. See Color mode.
  • The site search is in @luz-ds/catalog: see Search. So is the cookie banner, a module of its own that catalog.js does not include: see Cookie consent. The time of day for the color mode is a third module of the same kind, theme-time.js, loaded by catalog.js only on a page with a <luz-theme-time>: see Color mode by time of day.
  • The timeline and the sidebar's scroll spy are in @luz-ds/catalog too, as timeline.js and sidebar.js. catalog.js loads the first on a page with a <luz-timeline> and the second on a page with a .luz-sidebar, or a list marked data-luz-spy. Import them by name for a timeline or a sidebar added later: @luz-ds/catalog/timeline and @luz-ds/catalog/sidebar.
  • A page that loads only core has no scroll spy. The sidebar drawer is a native popover and works without a script.
  • The timeline has a small dictionary of its own for its four buttons (en and es only), then data-luz-label-* and the nearest lang. A language added with registerLocale() does not reach it: call initTimeline(document, t) with the t of core.

The modules

All 13 JavaScript modules of core
ModuleWhat it doesKey exports
luz.js
Entry: re-exports every module and initializes them all on load
Everything below
theme.js
Switching to a look of your own; the color mode is theme-mode.js's
applyTheme
theme-mode.js
The <luz-theme-mode> element, in a chunk of its own, loaded on demand
None: importing it defines the element
theme-boot.js
A classic script for the <head>: the color mode before the first paint
None
clipboard.js
Copy with visual feedback
copyToClipboard, initCopyButtons
modal.js
Fallback for the command and commandfor attributes in browsers without them
initModals, supportsCommands
highlight.js
Dependency-free syntax highlight for code blocks
highlightBlock, initHighlight
player.js
Video, audio and MIDI players with one UI
mountPlayer, mountMidiPlayer, initPlayers
tabs.js
Tab activation and keyboard support
activateTab, initTabs
i18n.js
Text the scripts write, in the language of the nearest lang: English in the entry, other languages fetched when a page uses them
t, getLang, registerLocale, loadLocales
utils.js
Pure helpers
formatTime, escapeHtml, calculateProgress
table-sort.js
Sorts a table in the browser: a heading marked data-luz-sort becomes a button. Loaded on demand, only on a page that has one
initTableSort(root, t)
midi.js
MIDI parser and Web Audio scheduler, loaded on demand
MidiPlayer

Languages and the strings scripts write

English is in the entry. Every other language LUZ ships is a small file, fetched at start for a page whose <html lang>, or any lang outside a link or an option, names it; a page in English makes no request.

With the individual modules, call loadLocales() yourself, and await loadLocales() before initHighlight() and initPlayers(). A file that cannot load is one console warning, and English.

For a language LUZ does not ship, set data-luz-label-* once on <html> or <body>, or call registerLocale() before the scripts start.

To check the file, put an import map with an integrity section for it before the first module script, on the pages in that language only. A modulepreload link with integrity is not a guard in Safari or Firefox: use it as a performance hint.

A language for LUZ is a pull request: the JSON file packages/core/src/i18n/<code>.json, one line in the files map of i18n.js and a budget row. The steps are in AGENTS.md.

Without JavaScript

What each behaviour falls back to when the script does not run:

ComponentWithout JavaScript
Links, and every panel stacked
The four radios still change the mode; Auto follows the system, and the choice is not remembered
No bar and no moments are shown; core's radios still change the mode, and no time of day is applied
Hidden; the text stays selectable
The browser's own media controls; MIDI shows its fallback text
Opens where the browser supports command; elsewhere the open button does nothing
Plain text, no colours
A heading with a link sorts on the server; a plain heading is not sortable. Rows are never hidden
An ordered list with a line and a dot per item; every item is visible
Works, drawer included; the current link does not follow the scroll
Table of contents and other data-luz-spy lists
Links to the sections; no link is marked as the one in view