Skip to content

@xid-kit/solid

SolidJS context provider, signal-based auth primitives, and headless components on top of @xid-kit/core.

Status

Package status is Current package. SolidJS context provider, signal-based primitives, and headless components are implemented. A real IdP round-trip on production infrastructure is still pending manual verification.

Provider setup

Wrap your app with XidProvider. It creates an XidClient, calls client.load() on mount to fetch the current session, and tears down via onCleanup.

import { XidProvider } from '@xid-kit/solid'

export function App() {
  return (
    <XidProvider publishableKey="pk_live_...">
      <Routes />
    </XidProvider>
  )
}

Auth primitives

Each primitive returns reactive Accessor<T> (getter functions). Call them in JSX or createEffect to track changes.

import { createAuth, createUser, createOrganization, createSession } from '@xid-kit/solid'
import { Show } from 'solid-js'

function Profile() {
  const auth = createAuth()
  // auth.isLoaded()  -- Accessor<boolean>
  // auth.isSignedIn() -- Accessor<boolean>
  // auth.userId()    -- Accessor<string | null>
  // auth.getToken()  -- () => Promise<Result<string, XidError>>
  // auth.signOut()   -- (options?) => Promise<Result<null, XidError>>

  return (
    <Show when={auth.isLoaded()} fallback={<p>Loading...</p>}>
      <Show when={auth.isSignedIn()} fallback={<p>Not signed in</p>}>
        <p>Signed in as {auth.userId()}</p>
        <button onClick={() => void auth.signOut()}>Sign out</button>
      </Show>
    </Show>
  )
}

createOrganization and createSession

const org = createOrganization()
// org() is CreateOrganizationReturn
if (org().isSignedIn) {
  console.log(org().organization?.name, org().membership?.role)
  await org().setActive('org_new_id')
}

const session = createSession()
if (session().isSignedIn) {
  const { value: token } = await session().getToken()
  // use token for backend requests
}

Headless components

import { SignInButton, SignOutButton, Protect } from '@xid-kit/solid'

// Navigates to /sign-in by default
<SignInButton signInUrl="/auth/sign-in" redirectUrl="/dashboard">
  Log in
</SignInButton>

// Signs out all sessions; pass sessionId to target one
<SignOutButton redirectUrl="/home">Log out</SignOutButton>

// Role and permission gate
<Protect role="org:admin" fallback={<p>Admins only</p>}>
  <Settings />
</Protect>

<Protect permission="org:member:write" fallback={null}>
  <InviteForm />
</Protect>

Exported API

Export Kind Purpose
XidProvider component Creates XidClient, calls load() on mount, tears down via onCleanup
createAuth primitive isLoaded, isSignedIn, userId, sessionId, session, getToken, signOut as Accessors
createUser primitive Accessor wrapping discriminated union on isLoaded / isSignedIn / user
createOrganization primitive Accessor returning organization, membership, and setActive for the active org
createSession primitive Accessor returning session and getToken for the active session
SignInButton component Headless button navigating to the sign-in URL on click
SignOutButton component Headless button that calls signOut on click
Protect component Role and permission gate with fallback prop

Token storage

  • Session tokens are HttpOnly cookies set by the XID Worker. The SDK never stores tokens in localStorage.
  • getToken() returns a short-lived JWT (60 s) cached by TokenManager in @xid-kit/core.
Navigation

Type to search...

Use arrow keys to navigateEnter to selectEscape to close