State and syncing
State is opt-in. Groups never synchronize merely because their labels happen to match.
Synchronize related groups
Give related groups the same explicit sync key and use stable tab value attributes. Try either group below—the other follows immediately.
Synchronized package-manager choice
Two separate groups share one explicit state key.
:::: code-group sync="package-manager"
::: code-tab label="npm" value="npm"
```sh
npm install package
```
:::
::: code-tab label="pnpm" value="pnpm"
```sh
pnpm add package
```
:::
::::npm install packagepnpm add packagenpm run devpnpm devSelecting pnpm updates every enhanced group with the same sync key that contains a pnpm value. Groups without that value remain unchanged.
Persist locally
Add persist="local" to remember a choice in localStorage. The namespaced key is rehype-code-group:<sync-key>. Storage failures are ignored so privacy modes and sandboxed embeds remain usable.
:::: code-group sync="package-manager" persist="local"Persist in the URL
Use persist="url" for shareable state. The client writes a query parameter such as ?rcg-package-manager=pnpm with history.replaceState, so selection does not reload the page.
:::: code-group sync="package-manager" persist="url"Observe changes
Every direct pointer or keyboard selection emits a bubbling rehype-code-group:change event with a small typed detail object.
import type { } from "rehype-code-group/client";
.("rehype-code-group:change", () => {
const { , , , } = (
as <>
).detailThe read-only detail property of the CustomEvent interface returns any data passed when initializing the event.
;
});The client also observes newly inserted markup. This supports client-side navigation and streamed content without reinitializing the whole document.
Change event payload
index is the selected zero-based panel index, value is the stable tab value, syncKey identifies related groups when present, and source distinguishes direct selection from synchronized updates.