ThemeScript
Sets page-level attributes before first paint, so nothing changes once the page has painted: the reader's saved theme (data-nz-theme from localStorage key nz-theme: light, dark or system) and data-nz-platform (apple or other). The rules are on themeScript. Render it in <head> (<head><ThemeScript nonce={nonce} /></head> in a root layout), put the app's default theme on <html> (data-nz-theme="system", or none for light), and put suppressHydrationWarning on <html>, whose attributes the script changes.
Import
import { ThemeScript } from '@nizivo/react/theme-script';Static or interactive
Server. It is no client module and hydrates nothing: it renders one inline <script> (379
bytes) that runs in <head> before the body is parsed. How to
choose.
In a client app (a Vite or React Router single-page app, or a 'use client' file) it is an ordinary React component: event handlers, refs and state work as usual. In a client app.
Examples
Basic
In a root layout, ThemeScript goes in <head>; here it runs where it is rendered. It restores the reader's saved theme (localStorage key nz-theme) and marks the page data-nz-platform="apple" on Apple devices, so the shortcut below reads ⌘K there and Ctrl+K elsewhere.
Search with ⌘KCtrl+K.
import type { JSX } from 'react';
import { Kbd } from '@nizivo/react/kbd';
import { ThemeScript } from '@nizivo/react/theme-script';
export function ThemeScriptExample(): JSX.Element {
return (
<p>
<ThemeScript />
Search with <Kbd keys="mod+k" />.
</p>
);
}
Props
Sets page-level attributes before first paint, so nothing changes once the page has painted: the reader's saved theme (data-nz-theme from localStorage key nz-theme: light, dark or system) and data-nz-platform (apple or other). The rules are on themeScript. Render it in <head> (<head><ThemeScript nonce={nonce} /></head> in a root layout), put the app's default theme on <html> (data-nz-theme="system", or none for light), and put suppressHydrationWarning on <html>, whose attributes the script changes.
Server component Renders no element of its own. Props: ThemeScriptProps. Source: src/theme-script/theme-script.tsx.
| Name | Type | Default | Description |
|---|---|---|---|
nonce | string | – | The CSP nonce for the inline script ( |
Other exports
ThemeScriptPropstypeimport type { ThemeScriptProps } from '@nizivo/react/theme-script'The props of
ThemeScript, listed above.themeScriptconstantimport { themeScript } from '@nizivo/react/theme-script'The script
ThemeScriptrenders, for frameworks that inline it themselves (Astro:<script is:inline set:html={themeScript} />; Vite: atransformIndexHtmltag) or that allow it by hash under a strict CSP. It runs in<head>, before<body>exists, and sets two attributes on<html>:-
data-nz-theme, the reader's saved theme. It readslocalStoragekeynz-theme; when the value is"light","dark"or"system", it setsdata-nz-themeto that value, replacing what the server rendered (the server's value is the app's default; the stored one is the reader's choice)."system"is set as is, not resolved: CSS follows the operating system from it, live, with no listener. With nothing stored, any other value, or storage blocked (a sandboxed frame, disabled site data), the attribute is left as the server rendered it. A theme switch saves the choice withlocalStorage.setItem('nz-theme', value)and sets the attribute itself. -data-nz-platform:"apple"when the platform string matches/mac|iphone|ipad|ipod/i, else"other". The platform string isnavigator.userAgentData.platformwhere the browser has it (Chromium:"macOS","Windows", …), elsenavigator.platform("MacIntel","iPhone","iPad"; iPadOS reports"MacIntel", which is still Apple). It never reads the user-agent string. A value already on<html>(set by the server, or by a test) is kept. Kbd reads the attribute to show⌘KorCtrl+K.Each half runs in its own
try, so blocked storage never stops the platform half, and the script never throws into the page.Under a strict CSP, allow it by hash:
script-src 'sha256-nA1HUQWDdDUFqqoxWbjzCzcYSjzWLEe0pwDdRCMGqOw='. The hash changes only when the script does, and a change is called out in the changelog.const themeScript: string
Data attributes and slots
Style parts by class (.nz-<slot>) and state by data attribute. Attribute meanings come from contracts/vocabulary.json.
This entry renders no element with a data-slot.
Accessibility
Nothing in this component takes focus or keyboard input.
Keyboard
None.
Figma
Node ids from design/component-map.json, which nz gen writes from component.json. The links open the Nizivo Figma library, which may ask you to sign in.
- Canonical: none
- Ghost masters: none
Textarea
A multi-line native text area, at least 112 px tall, that grows with its content where the browser supports field-sizing and can be resized vertically. Inside a Field it is labelled, described and validated by the Field.
Toast
A short message after an action, bottom-centre, with one optional action. toast() shows it from anywhere in your client code; one <Toaster /> in the root layout renders the stack and speaks each message to screen readers.