i99dash docs
API referencei99dashReact bindings

React bindings

React bindings for i99dash — provider component and one hook per family. Every hook accepts a fallback for SSR / no-host / unsupported-family graceful degradation.

React bindings on top of i99dash. Single entry point — there's nothing here that wouldn't be tree-shaken if a consumer only uses one hook, so a flat export keeps the public surface visible at a glance.

pnpm add i99dash

The React bindings live behind the i99dash/react subpath of the single i99dash package. No separate install.

At a glance

import { useState } from 'react';
import { MiniAppProvider, useCarStatus, useMedia } from 'i99dash/react';
import { createClientOrSSR } from 'i99dash';

export default function App() {
  // Lazy init runs once per mount — stable reference across re-renders
  // so MiniAppProvider doesn't tear down and re-open the bridge sub.
  const [client] = useState(() => createClientOrSSR());

  return (
    <MiniAppProvider client={client}>
      <Dashboard />
    </MiniAppProvider>
  );
}

function Dashboard() {
  const { data: status } = useCarStatus();
  const { data: media } = useMedia();

  // External data is plain fetch() against a declared manifest.network
  // origin — no SDK hook wraps it.
  return <Layout status={status} media={media} />;
}

Provider

Mount once at the root of your tree. Every hook below reads the client through React context.

ComponentPurpose
MiniAppProviderBinds the client. null is a first-class value — pass null for SSR, jsdom, or Storybook stories.
useClient()Escape hatch for one-off client flows that don't fit a dedicated hook.

Family hooks

Each hook has the same shape:

const { data, error } = useFooBar({ fallback?: T });

While the bridge isn't reachable (SSR, jsdom, the host doesn't ship the family), data is the fallback you passed in (or undefined) and error is null. No throws.

HookFamily scopeReturns
useMiniAppContext— (always available){ data, error, loading } of MiniAppContext
useCarStatuscar.status.read{ data, error } of CarStatus
useMediamedia.read{ data, error } of MediaSnapshot
useClimateclimate.read{ data, error } of ClimateSnapshot
useVehicleDiagnosticsvehicle.diagnostics{ data, error } of VehicleDiagnosticsSnapshot
useVehicleEnvironmentvehicle.environment{ data, error } of VehicleEnvironmentSnapshot
useSystemsystem.read{ data, error } of SystemSnapshot
useConnectivityconnectivity.read{ data, error } of ConnectivitySnapshot
useLocationlocation.read{ data, error } of LocationSnapshot
useNavigationnav.read{ data, error } of NavigationSnapshot

SSR / no-host fallbacks

Every hook accepts an optional fallback so the component renders a sane shape when there's no bridge:

const { data: ctx } = useMiniAppContext({
  fallback: { locale: 'en', isDark: false, /* ... */ },
});

const { data: status } = useCarStatus({
  fallback: { speedKmh: 0, doorsLocked: true, staleness: 'very_stale', /* ... */ },
});

This is the right tool for:

  • Next.js / Nuxt SSR — server render shows the fallback; the hook re-renders with real data after hydration.
  • Storybook / jsdom — the host bridge doesn't exist; the hook stays on fallback indefinitely without throwing.
  • Older host builds — the family isn't available yet; same graceful-degradation as the unsupported-host case.

For dynamic capability checks (e.g. do not even try to call useMedia if the host doesn't ship it), reach for client.has(scope) at app start.

Source

On this page