ForgeWP

Recipe: Verification Landing Page

Read an account link and submit verification explicitly with clear success and error states.

Recipe: verification landing page

Place this component on the public verification route. It reads the account ID and token from the email link, then lets the visitor submit verification once the page is ready.

src/components/VerifyMember.tsx
1import { useEffect, useState } from "react"
2import { WpAuthProvider, useWpAuth } from "@forgewp/auth"
3
4function VerifyMemberContent() {
5  const { verifyEmail, loading, error } = useWpAuth()
6  const [link, setLink] = useState<{ id: number; token: string } | null>(null)
7  const [complete, setComplete] = useState(false)
8  useEffect(() => {
9    const params = new URLSearchParams(window.location.search)
10    setLink({
11      id: Number(params.get("userId")),
12      token: params.get("token") || "",
13    })
14  }, [])
15  if (!link) return <p role="status">Reading your verification link…</p>
16  if (!Number.isInteger(link.id) || link.id <= 0 || !link.token) {
17    return (
18      <p role="alert">Open a complete verification link from your email.</p>
19    )
20  }
21  if (complete)
22    return (
23      <p role="status">Email verified. You can continue to your account.</p>
24    )
25  return (
26    <section>
27      <h1>Verify your email</h1>
28      <button
29        type="button"
30        disabled={loading}
31        onClick={async () => {
32          if (await verifyEmail(link.id, link.token)) setComplete(true)
33        }}
34      >
35        {loading ? "Verifying…" : "Verify email"}
36      </button>
37      {error && <p role="alert">{error}</p>}
38    </section>
39  )
40}
41
42export default function VerifyMember() {
43  return (
44    <WpAuthProvider>
45      <VerifyMemberContent />
46    </WpAuthProvider>
47  )
48}
Keep one-use actions explicit

This example reads the query in an effect but sends verification from a button. It avoids automatically consuming the same token twice when a development effect is replayed.

Do not protect the verification destination with the same rule that redirects unverified accounts to it. Provide normal-login and resend destinations in your theme's surrounding account navigation. Test invalid, mismatched and already-used links, plus a successful next page request after verification. See verification rules.