Skip to Content
GuidesFramework recipes

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.

Last updated on