VVEREID Docs
sdks

SDK — React

@vereid/react — hooks and headless components for VEREID Auth, Identity, and Social inside React 18+ and React 19 apps.

Last updated 2026-05-20

@vereid/react is built on top of @vereid/js. It contributes a VereidProvider, a set of hooks, and a small library of headless components that you can style however you like (or import the optional /styles.css to get the same look as auth.vereid.com).

  • Repo: github.com/vereid/sdk (packages/react)
  • License: MIT
  • React: 18.2+ and 19 RC supported
  • SSR: works in Next.js (App Router and Pages Router), Remix, and Astro

Install

npm install @vereid/react @vereid/js

Peer dependency on @vereid/js keeps the React layer small (~6 KB gzipped on top).

Provider

Wrap your app once. The provider initialises a client-safe VereidBrowser instance and manages auth state in a synchronously-readable store so SSR hydration stays consistent.

import { VereidProvider } from "@vereid/react";
 
export default function App({ children }: { children: React.ReactNode }) {
  return (
    <VereidProvider
      clientId={process.env.NEXT_PUBLIC_VEREID_CLIENT_ID!}
      redirectUri={process.env.NEXT_PUBLIC_VEREID_REDIRECT_URI!}
      scope="openid email profile vereid:verification"
    >
      {children}
    </VereidProvider>
  );
}

Hooks

import { useVereid, useAuth, useVerification, useProfile } from "@vereid/react";
 
function Header() {
  const { user, isLoading, login, logout } = useAuth();
  if (isLoading) return null;
  return user ? (
    <button onClick={logout}>Log out {user.preferred_username}</button>
  ) : (
    <button onClick={login}>Log in with VEREID</button>
  );
}
 
function TrustBadge() {
  const v = useVerification();
  if (!v?.badges?.includes("liveness")) return null;
  return <span className="badge">Liveness verified</span>;
}
 
function ProfileCard({ handle }: { handle: string }) {
  const { data, error } = useProfile(handle);
  if (error) return <div>Failed: {error.message}</div>;
  if (!data) return <div>Loading…</div>;
  return <h2>{data.display_name}</h2>;
}

Components

Headless by default. They render unstyled DOM with stable data-vereid-* attributes you can target from your own CSS or Tailwind.

import {
  LoginButton,
  ProfileBadge,
  VerifyButton,
  VerificationRequired,
} from "@vereid/react";
 
<LoginButton scope="openid email vereid:verification" />
 
<ProfileBadge handle="@mina" />
// renders the user's display name + the highest unlocked badge
 
<VerifyButton tiers={["T1", "T2"]} onComplete={(s) => router.push(`/done/${s.id}`)}>
  Verify your identity
</VerifyButton>
 
<VerificationRequired badge="liveness" fallback={<UpgradePrompt />}>
  <SensitiveAction />
</VerificationRequired>

<VerificationRequired> is the most-used component in practice — it gates any child UI on a specific badge being present in the user's vereid_verification.badges array.

Optional styled bundle

If you want a fast first cut that matches our hosted UI, import the styles:

import "@vereid/react/styles.css";

That ships ~3 KB of CSS variables and component selectors. Override any token to re-theme:

:root {
  --vereid-accent: #ff6a3d;
  --vereid-radius: 12px;
}

Server-side rendering

useAuth() returns { user: null, isLoading: true } on the server. Client-side hydration completes via a single GET to /userinfo and re-renders. To avoid the flash, wrap auth-aware UI in <Suspense> and use <AuthGuard>:

<Suspense fallback={<Skeleton />}>
  <AuthGuard>
    <Dashboard />
  </AuthGuard>
</Suspense>

<AuthGuard> redirects unauthenticated users to LoginButton's URL and is the only component that triggers a navigation as a side effect.

Testing

import { MockVereidProvider } from "@vereid/react/test";
 
render(
  <MockVereidProvider
    user={{ sub: "u_1", preferred_username: "mina" }}
    verification={{ tier: "T2", badges: ["photo", "liveness"] }}
  >
    <YourComponent />
  </MockVereidProvider>,
);

Compatibility

  • React 18.2+, 19 RC
  • Next.js 13.4+ (App Router fully supported)
  • Remix 2.x
  • Astro 4.x with client:load islands

Where to next