After sign-in, isDeviceRegistrationRequired tells you whether the current device still needs approval. You don’t send the approval email — the backend emails the link automatically when a user signs in on an unrecognized device. isDeviceRegistrationRequired just reflects that the current device is still pending, so use it to render a “check your email” message.
TypeScript
React
import { getDefaultClient, isDeviceRegistrationRequired,} from '@dynamic-labs-sdk/client';// Returns the message to show, or an empty string when nothing is pending.function deviceApprovalMessage(): string { const { user } = getDefaultClient(); const needsApproval = Boolean(user && isDeviceRegistrationRequired(user)); return needsApproval ? 'Check your email to approve this device.' : '';}
import { useIsDeviceRegistrationRequired } from '@dynamic-labs-sdk/react-hooks';function DeviceApprovalGate() { const { data: required } = useIsDeviceRegistrationRequired(); if (!required) return null; return <p>Check your email to approve this device.</p>;}
List the user’s devices and let them revoke any — or all — from a settings screen.
Revoking the current device — or all devices — signs the user out immediately. revokeAllRegisteredDevices always logs out; revokeRegisteredDevice logs out when the device being revoked is the current one. The SDK fires the logout event with reason device-revoked or all-devices-revoked; listen for it and send the user to your login screen so they aren’t left on a dead session.
TypeScript
React
import { getRegisteredDevices, revokeRegisteredDevice, revokeAllRegisteredDevices, onEvent,} from '@dynamic-labs-sdk/client';async function listDevices(list: HTMLUListElement) { const devices = await getRegisteredDevices(); list.replaceChildren(); for (const device of devices) { const item = document.createElement('li'); const label = device.isCurrentDevice ? ' (this device)' : ''; item.textContent = `${device.userAgent ?? 'Unknown device'}${label}`; list.append(item); }}async function revoke(deviceRegistrationId: string) { await revokeRegisteredDevice({ deviceRegistrationId });}// setStatus is your implementation — e.g. a toast or banner.async function revokeAll(setStatus: (message: string) => void) { setStatus('Signing you out of every device…'); await revokeAllRegisteredDevices(); setStatus('All devices signed out. Redirecting you to sign in…');}// Revoking the current device (or all devices) logs the user out.// Send them to the login page when it happens.onEvent({ event: 'logout', listener: (metadata) => { const revokedCurrentSession = metadata?.reason === 'device-revoked' || metadata?.reason === 'all-devices-revoked'; if (revokedCurrentSession) { window.location.href = '/login'; } },});