Framework recipes
Every integration follows one rule: register Orbz once in the browser, then drive its documented attributes or properties from framework-native state.
React and Next.js have a strict adapter. Vanilla JavaScript, Vue, Svelte, and Angular use the native element directly.
Vanilla JavaScript
Import the browser entry in your client entry module:
import "@neongate-ai/orbz/browser";
import type { OrbzElement } from "@neongate-ai/orbz";
const orb = document.querySelector<OrbzElement>("#assistant-orb");
if (orb) {
orb.state = "listening";
orb.size = 300;
orb.speed = 1.1;
}<orb-z
id="assistant-orb"
state="idle"
preset="neongate"
reduced-motion="system"
></orb-z>Open the Vanilla example · View source
React
Use @neongate-ai/orbz/react. The adapter registers the native element after
mount and accepts only the supported Orbz props.
import { useState } from "react";
import { Orbz, type OrbzState } from "@neongate-ai/orbz/react";
export function Assistant() {
const [state, setState] = useState<OrbzState>("idle");
return (
<div role="status" aria-live="polite">
<Orbz
state={state}
size={300}
preset="neongate"
reducedMotion="system"
elevated
/>
<span>Assistant is {state}</span>
<button type="button" onClick={() => setState("listening")}>
Listen
</button>
</div>
);
}Open the React example · View source
Next.js
The adapter is a Client Component. Place the component that renders Orbz
behind a "use client" boundary; the rest of the page can stay server-rendered.
"use client";
import { Orbz } from "@neongate-ai/orbz/react";
export function AssistantPresence() {
return (
<div role="status">
<Orbz state="thinking" size={300} preset="neongate" />
<span>Assistant is thinking</span>
</div>
);
}No dynamic import with ssr: false is required. Keep the initial props
deterministic and let the adapter register the element on the client.
Open the Next.js example · View source
Vue
Register Orbz from the application entry:
import "@neongate-ai/orbz/browser";
import { createApp } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");Tell the Vue compiler that orb-z is a native custom element:
import vue from "@vitejs/plugin-vue";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag === "orb-z",
},
},
}),
],
});Then bind application state in the template:
<orb-z
:state="state"
:size="`${size}px`"
:speed="speed"
:paused="paused"
:elevated="elevated"
:preset="activePreset"
:reduced-motion="reducedMotion"
></orb-z>Open the Vue example · View source
Svelte
Import the browser entry before mounting the app:
import "@neongate-ai/orbz/browser";
import { mount } from "svelte";
import App from "./App.svelte";
mount(App, { target: document.querySelector("#app")! });Use the native element in the component:
<script lang="ts">
import type { OrbzState } from "@neongate-ai/orbz";
let state: OrbzState = "idle";
let paused = false;
</script>
<orb-z
{state}
{paused}
size="300px"
preset="neongate"
reduced-motion="system"
></orb-z>Open the Svelte example · View source
Angular
Import the browser entry before bootstrapping:
import "@neongate-ai/orbz/browser";
import { bootstrapApplication } from "@angular/platform-browser";
import { AppComponent } from "./app/app.component";
bootstrapApplication(AppComponent);Allow custom elements in the component schema:
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
@Component({
selector: "app-root",
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
templateUrl: "./app.component.html",
})
export class AppComponent {}Use null to remove boolean attributes. The string "false" still counts as
present in HTML.
<orb-z
[attr.state]="state"
[attr.size]="size + 'px'"
[attr.paused]="paused ? '' : null"
[attr.elevated]="elevated ? '' : null"
[attr.preset]="activePreset"
[attr.reduced-motion]="reducedMotion"
></orb-z>Open the Angular example · View source
The invariant
Framework syntax changes, but the component does not. Do not reach into its
Shadow DOM or create framework-specific styling hooks. Keep voice orchestration
and semantic controls in the host, and pass the same strict visual contract to
orb-z everywhere.