Skip to main content

Auth UI

Add auth to your app in 2 minutes. Magic links, passkeys, OTP — all configured from your dashboard.

Setup

npx create-scute-app
Or manually:
pnpm add @scute/js-core @scute/react-hooks @scute/auth-ui-react @scute/nextjs-handlers
# .env.local
NEXT_PUBLIC_SCUTE_APP_ID=your-app-id
NEXT_PUBLIC_SCUTE_BASE_URL=https://api.scute.io
SCUTE_SECRET=your-app-secret

Option 1: Drop-in component

import { ScuteAuthGate } from "@scute/auth-ui-react";

<ScuteAuthGate>
  <App />
</ScuteAuthGate>
Shows login when not authenticated. Renders your app when authenticated. Handles passkey registration, magic links, OTP — everything.

Option 2: Headless hook

Full control over the UI.
import { useScuteAuthFlow } from "@scute/auth-ui-react";

function Auth() {
  const auth = useScuteAuthFlow();

  if (auth.isAuthenticated) return <App />;

  if (auth.view === "login") {
    return (
      <form onSubmit={(e) => { e.preventDefault(); auth.submitIdentifier(); }}>
        <input
          value={auth.identifier}
          onChange={(e) => auth.setIdentifier(e.target.value)}
          placeholder="you@example.com"
        />
        <button>{auth.submitting ? "..." : "Continue"}</button>
      </form>
    );
  }

  if (auth.view === "magic_pending") {
    return <p>Check your email: {auth.identifier}</p>;
  }

  if (auth.view === "webauthn_register") {
    return (
      <div>
        <p>Register a passkey?</p>
        <button onClick={auth.registerPasskey}>Register</button>
        <button onClick={auth.skipPasskey}>Skip</button>
      </div>
    );
  }

  return <p>Loading...</p>;
}

Views

ViewWhat’s happening
loadingSDK initializing
loginShow email input
magic_pendingMagic link sent
magic_verifyingProcessing link from URL
otp_inputShow code input
webauthn_verifyPasskey prompt active
webauthn_registerOffer passkey registration
webauthn_register_successRegistered (auto-transitions)
errorShow auth.error + retry
authenticatedDone

Actions

ActionWhat it does
auth.setIdentifier(email)Set email before submit
auth.submitIdentifier()Send magic link or trigger passkey
auth.submitOtp(code)Verify OTP code
auth.registerPasskey()Register passkey on this device
auth.skipPasskey()Skip registration, sign in
auth.retry()Back to login
auth.signOut()Sign out

Frameworks

Next.jsnpx create-scute-app handles everything. Astro — use as a React island with client:only="react". Remix / TanStack Start — wrap with provider, use components. The CLI scaffolds the right files for each framework.

Styling

Default component uses data-scute-* attributes:
[data-scute-view="login"] { }
[data-scute-view="webauthn_register"] { }
[data-scute-input] { }
[data-scute-button="primary"] { }
[data-scute-error] { }
Or use the headless hook and bring your own components.