SimpleAuth
ReactHooks

useVerifyEmail

Verify an email address using the token from the verification link.

Overview

useVerifyEmail wraps auth.verifyEmail({ token }). Pass { token } to auto-run once on mount, or call verify(token) yourself.

Signature

export function useVerifyEmail(options?: { token?: string })

Parameters

OptionTypeDescription
tokenstring | undefinedWhen set, the hook runs verify(token) automatically on first mount.

Returns

FieldTypeDescription
verify(token: string) => Promise<unknown>Calls auth.verifyEmail and updates state.
dataunknownLast successful response when present.
errorstring | nullHuman-readable error when verification fails.
isErrorbooleanConvenience flag from error.
isLoadingbooleanTrue while a verify request runs.
isSuccessbooleanTrue after a successful verification.
reset() => voidClears hook state and allows another auto-run if you remount with a new token.

Example

"use client"

import { useVerifyEmail } from "@/components/simpleauth"

export function VerifyFromUrl({ token }: { token: string }) {
  const { isLoading, error, isSuccess } = useVerifyEmail({ token })

  if (isLoading) return <p>Verifying…</p>
  if (error) return <p>{error}</p>
  if (isSuccess) return <p>Email verified. You can sign in.</p>
  return null
}

How it works

  • Uses useSimpleAuthClient() and a guarded useEffect so token triggers at most one automatic verify per mount.

Shipped by

npx @simpleauthjs/react add verify-email

Requires add sign-up first (ships VerifyEmailPrompt).

Source

components/simpleauth/hooks/use-verify-email.ts
"use client"

import { useCallback, useEffect, useRef, useState } from "react"
import { SimpleAuthError, type SuccessResponse } from "@simpleauthjs/core"
import { useSimpleAuthClient } from "../provider"

function getErrorMessage(error: unknown) {
  if (error instanceof SimpleAuthError) {
    return error.message
  }

  if (error instanceof Error) {
    return error.message
  }

  return "Unable to verify email."
}

type UseVerifyEmailOptions = {
  token?: string
}

export function useVerifyEmail(options: UseVerifyEmailOptions = {}) {
  const { token: initialToken } = options
  const auth = useSimpleAuthClient()
  const [isLoading, setIsLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [data, setData] = useState<SuccessResponse | null>(null)
  const autoRunRef = useRef(false)

  const verify = useCallback(
    async (token: string) => {
      setIsLoading(true)
      setError(null)

      try {
        const response = await auth.verifyEmail({ token })
        setData(response)
        return response
      } catch (requestError) {
        setData(null)
        setError(getErrorMessage(requestError))
        throw requestError
      } finally {
        setIsLoading(false)
      }
    },
    [auth],
  )

  useEffect(() => {
    if (!initialToken || autoRunRef.current) {
      return
    }

    autoRunRef.current = true
    verify(initialToken).catch(() => {})
  }, [initialToken, verify])

  function reset() {
    autoRunRef.current = false
    setData(null)
    setError(null)
    setIsLoading(false)
  }

  return {
    verify,
    data,
    error,
    isError: Boolean(error),
    isLoading,
    isSuccess: Boolean(data?.success),
    reset,
  }
}

On this page