[{"data":1,"prerenderedAt":817},["ShallowReactive",2],{"navigation":3,"\u002Freference\u002Fcontributing":178,"\u002Freference\u002Fcontributing-surround":814},[4,23,78,95,123,143,158],{"title":5,"path":6,"stem":7,"children":8,"icon":22},"Getting Started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,12,17],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F3.configuration","i-lucide-settings",false,{"title":24,"icon":22,"path":25,"stem":26,"children":27,"page":22},"Sign-in","\u002Fsign-in","2.sign-in",[28,33,38,43,48,53,58,63,68,73],{"title":29,"path":30,"stem":31,"icon":32},"Sign-in pages","\u002Fsign-in\u002Fpages","2.sign-in\u002F1.pages","i-lucide-log-in",{"title":34,"path":35,"stem":36,"icon":37},"Several accounts","\u002Fsign-in\u002Fmulti-session","2.sign-in\u002F10.multi-session","i-lucide-users-round",{"title":39,"path":40,"stem":41,"icon":42},"Account page","\u002Fsign-in\u002Faccount","2.sign-in\u002F2.account","i-lucide-circle-user",{"title":44,"path":45,"stem":46,"icon":47},"Other methods","\u002Fsign-in\u002Fmethods","2.sign-in\u002F3.methods","i-lucide-key-square",{"title":49,"path":50,"stem":51,"icon":52},"Sign-in providers","\u002Fsign-in\u002Fproviders","2.sign-in\u002F4.providers","i-lucide-share-2",{"title":54,"path":55,"stem":56,"icon":57},"Two-factor","\u002Fsign-in\u002Ftwo-factor","2.sign-in\u002F5.two-factor","i-lucide-shield-check",{"title":59,"path":60,"stem":61,"icon":62},"Passkeys","\u002Fsign-in\u002Fpasskeys","2.sign-in\u002F6.passkeys","i-lucide-fingerprint",{"title":64,"path":65,"stem":66,"icon":67},"Phone numbers","\u002Fsign-in\u002Fphone-numbers","2.sign-in\u002F7.phone-numbers","i-lucide-smartphone",{"title":69,"path":70,"stem":71,"icon":72},"Signing in devices","\u002Fsign-in\u002Fdevices","2.sign-in\u002F8.devices","i-lucide-tv",{"title":74,"path":75,"stem":76,"icon":77},"Security","\u002Fsign-in\u002Fsecurity","2.sign-in\u002F9.security","i-lucide-lock-keyhole",{"title":79,"path":80,"stem":81,"children":82,"icon":22},"Organizations","\u002Forganizations","3.organizations\u002F1.index",[83,85,90],{"title":79,"path":80,"stem":81,"icon":84},"i-lucide-building-2",{"title":86,"path":87,"stem":88,"icon":89},"Roles","\u002Forganizations\u002Froles","3.organizations\u002F2.roles","i-lucide-shield",{"title":91,"path":92,"stem":93,"icon":94},"Single sign-on","\u002Forganizations\u002Fsso","3.organizations\u002F3.sso","i-lucide-key-round",{"title":96,"path":97,"stem":98,"children":99,"icon":22},"Admin dashboard","\u002Fadmin","4.admin\u002F1.index",[100,103,108,113,118],{"title":101,"path":97,"stem":98,"icon":102},"Overview","i-lucide-layout-dashboard",{"title":104,"path":105,"stem":106,"icon":107},"Managing users","\u002Fadmin\u002Fusers","4.admin\u002F2.users","i-lucide-user-cog",{"title":109,"path":110,"stem":111,"icon":112},"Staff roles","\u002Fadmin\u002Froles","4.admin\u002F3.roles","i-lucide-shield-user",{"title":114,"path":115,"stem":116,"icon":117},"Audit log","\u002Fadmin\u002Faudit-log","4.admin\u002F4.audit-log","i-lucide-history",{"title":119,"path":120,"stem":121,"icon":122},"Your own pages","\u002Fadmin\u002Fextending","4.admin\u002F5.extending","i-lucide-layout-panel-left",{"title":124,"icon":22,"path":125,"stem":126,"children":127,"page":22},"Integrations","\u002Fintegrations","5.integrations",[128,133,138],{"title":129,"path":130,"stem":131,"icon":132},"Stripe","\u002Fintegrations\u002Fstripe","5.integrations\u002F1.stripe","i-simple-icons-stripe",{"title":134,"path":135,"stem":136,"icon":137},"API keys","\u002Fintegrations\u002Fapi-keys","5.integrations\u002F2.api-keys","i-lucide-key",{"title":139,"path":140,"stem":141,"icon":142},"Tokens","\u002Fintegrations\u002Ftokens","5.integrations\u002F3.tokens","i-lucide-ticket",{"title":144,"icon":22,"path":145,"stem":146,"children":147,"page":22},"Customization","\u002Fcustomization","6.customization",[148,153],{"title":149,"path":150,"stem":151,"icon":152},"Emails","\u002Fcustomization\u002Femails","6.customization\u002F1.emails","i-lucide-mail",{"title":154,"path":155,"stem":156,"icon":157},"Languages","\u002Fcustomization\u002Flanguages","6.customization\u002F2.languages","i-lucide-languages",{"title":159,"icon":22,"path":160,"stem":161,"children":162,"page":22},"Reference","\u002Freference","7.reference",[163,168,173],{"title":164,"path":165,"stem":166,"icon":167},"How it works","\u002Freference\u002Fhow-it-works","7.reference\u002F1.how-it-works","i-lucide-cog",{"title":169,"path":170,"stem":171,"icon":172},"API reference","\u002Freference\u002Fapi","7.reference\u002F2.api","i-lucide-braces",{"title":174,"path":175,"stem":176,"icon":177},"Contributing","\u002Freference\u002Fcontributing","7.reference\u002F3.contributing","i-lucide-git-pull-request",{"id":179,"title":174,"body":180,"description":807,"extension":808,"links":809,"meta":810,"navigation":811,"path":175,"seo":812,"stem":176,"__hash__":813},"docs\u002F7.reference\u002F3.contributing.md",{"type":181,"value":182,"toc":790},"minimark",[183,195,200,216,332,336,339,414,418,429,436,446,450,453,489,495,499,507,518,528,532,535,584,588,635,639,673,677,702,724,728,731,760,774,778,786],[184,185,186,187,194],"p",{},"Thanks for helping! Bug reports, fixes, docs and features are all welcome. For something big, open an\n",[188,189,193],"a",{"href":190,"rel":191},"https:\u002F\u002Fgithub.com\u002Ftreygrr\u002Fnuxt-better-auth-ui\u002Fissues",[192],"nofollow","issue"," first, so we can agree on the approach before you write\nit.",[196,197,199],"h2",{"id":198},"setting-up","Setting up",[184,201,202,203,207,208,211,212,215],{},"You need Node 22 or 24 and pnpm (the version in ",[204,205,206],"code",{},"package.json","'s ",[204,209,210],{},"packageManager","; ",[204,213,214],{},"corepack enable"," sets it up).",[217,218,220,225,270,274,290,293,297,316],"steps",{"level":219},"3",[221,222,224],"h3",{"id":223},"clone-and-install","Clone and install",[226,227,233],"pre",{"className":228,"code":229,"filename":230,"language":231,"meta":232,"style":232},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","git clone https:\u002F\u002Fgithub.com\u002Ftreygrr\u002Fnuxt-better-auth-ui.git\ncd nuxt-better-auth-ui\npnpm install\n","Terminal","bash","",[204,234,235,251,261],{"__ignoreMap":232},[236,237,240,244,248],"span",{"class":238,"line":239},"line",1,[236,241,243],{"class":242},"sBMFI","git",[236,245,247],{"class":246},"sfazB"," clone",[236,249,250],{"class":246}," https:\u002F\u002Fgithub.com\u002Ftreygrr\u002Fnuxt-better-auth-ui.git\n",[236,252,254,258],{"class":238,"line":253},2,[236,255,257],{"class":256},"s2Zo4","cd",[236,259,260],{"class":246}," nuxt-better-auth-ui\n",[236,262,264,267],{"class":238,"line":263},3,[236,265,266],{"class":242},"pnpm",[236,268,269],{"class":246}," install\n",[221,271,273],{"id":272},"configure-the-playground","Configure the playground",[226,275,277],{"className":228,"code":276,"filename":230,"language":231,"meta":232,"style":232},"cp playground\u002F.env.example playground\u002F.env\n",[204,278,279],{"__ignoreMap":232},[236,280,281,284,287],{"class":238,"line":239},[236,282,283],{"class":242},"cp",[236,285,286],{"class":246}," playground\u002F.env.example",[236,288,289],{"class":246}," playground\u002F.env\n",[184,291,292],{},"The defaults work as they are. Its comments explain the optional extras: GitHub sign-in, captcha keys, Spanish.",[221,294,296],{"id":295},"prepare-and-start-it","Prepare and start it",[226,298,300],{"className":228,"code":299,"filename":230,"language":231,"meta":232,"style":232},"pnpm dev:prepare\npnpm dev\n",[204,301,302,309],{"__ignoreMap":232},[236,303,304,306],{"class":238,"line":239},[236,305,266],{"class":242},[236,307,308],{"class":246}," dev:prepare\n",[236,310,311,313],{"class":238,"line":253},[236,312,266],{"class":242},[236,314,315],{"class":246}," dev\n",[184,317,318,319,323,324,327,328,331],{},"The playground runs on ",[188,320,321],{"href":321,"rel":322},"http:\u002F\u002Flocalhost:3001",[192],". Sign in as ",[204,325,326],{},"admin@example.com"," with ",[204,329,330],{},"password123",".",[196,333,335],{"id":334},"the-repository","The repository",[184,337,338],{},"It's a pnpm workspace:",[340,341,342,355],"table",{},[343,344,345],"thead",{},[346,347,348,352],"tr",{},[349,350,351],"th",{},"Folder",[349,353,354],{},"What it is",[356,357,358,381,391,404],"tbody",{},[346,359,360,366],{},[361,362,363],"td",{},[204,364,365],{},"src\u002F",[361,367,368,369,372,373,376,377,380],{},"The module: ",[204,370,371],{},"module.ts"," (its options and how it adds Better Auth's plugins), ",[204,374,375],{},"runtime\u002Fapp"," (pages, components, words), ",[204,378,379],{},"runtime\u002Fserver"," (its own routes and Better Auth plugins)",[346,382,383,388],{},[361,384,385],{},[204,386,387],{},"playground\u002F",[361,389,390],{},"A Nuxt app using the module with every feature on, and mock data",[346,392,393,398],{},[361,394,395],{},[204,396,397],{},"test\u002F",[361,399,400,401],{},"API tests, and browser tests in ",[204,402,403],{},"test\u002Fbrowser\u002F",[346,405,406,411],{},[361,407,408],{},[204,409,410],{},"docs\u002F",[361,412,413],{},"This site",[221,415,417],{"id":416},"the-playgrounds-data","The playground's data",[184,419,420,421,424,425,428],{},"On startup, the playground seeds an admin and 40 mock users from ",[204,422,423],{},"playground\u002F.env",": join dates over six months,\nverified and unverified emails, more admins, bans (permanent, expiring, expired), a moderator\n(",[204,426,427],{},"lucas.haddad@example.com","), linked GitHub, Google and Discord accounts, and sessions on different devices. Mock users\nshare the admin's password.",[184,430,431,432,435],{},"It only adds users that are missing, so delete ",[204,433,434],{},"playground\u002F.data\u002Fauth.sqlite"," to start over.",[184,437,438,439,442,443,331],{},"Emails and texts don't leave the playground: they go to an outbox, at ",[204,440,441],{},"\u002Fapi\u002F_playground\u002Foutbox"," and\n",[204,444,445],{},"\u002Fapi\u002F_playground\u002Fsms",[196,447,449],{"id":448},"checks","Checks",[184,451,452],{},"Run these before opening a pull request; CI runs them too, on Node 22 and 24.",[226,454,456],{"className":228,"code":455,"filename":230,"language":231,"meta":232,"style":232},"pnpm fmt        # Prettier (pnpm fmt:fix to fix)\npnpm typecheck  # the module, its server code and the playground\npnpm test       # builds everything, then runs the API and browser tests\n",[204,457,458,469,479],{"__ignoreMap":232},[236,459,460,462,465],{"class":238,"line":239},[236,461,266],{"class":242},[236,463,464],{"class":246}," fmt",[236,466,468],{"class":467},"sHwdD","        # Prettier (pnpm fmt:fix to fix)\n",[236,470,471,473,476],{"class":238,"line":253},[236,472,266],{"class":242},[236,474,475],{"class":246}," typecheck",[236,477,478],{"class":467},"  # the module, its server code and the playground\n",[236,480,481,483,486],{"class":238,"line":263},[236,482,266],{"class":242},[236,484,485],{"class":246}," test",[236,487,488],{"class":467},"       # builds everything, then runs the API and browser tests\n",[184,490,491,494],{},[204,492,493],{},"pnpm test"," builds the module and the playground, starts the playground once on port 3941 with a fresh database, and\nruns every test file against it: the API tests first, then the browser tests.",[221,496,498],{"id":497},"browser-tests","Browser tests",[184,500,501,502,506],{},"The browser tests drive Chromium through the pages: signing up and in, links and codes, two-factor, passkeys (with\nChromium's virtual authenticator), organizations, single sign-on and the admin. ",[503,504,505],"strong",{},"Any console error or warning fails\nthem",", so a hydration mismatch does.",[184,508,509,510,513,514,517],{},"They use ",[204,511,512],{},"CHROMIUM_PATH",", a system Chromium or Chrome, or Playwright's own (",[204,515,516],{},"npx playwright install chromium",").\nWithout one, they're skipped.",[519,520,521],"tip",{},[184,522,523,524,527],{},"Match toast messages exactly in browser tests: ",[204,525,526],{},"getByText('Saved', { exact: true })",". Nuxt UI repeats a toast's words\nfor screen readers, so a loose match finds two elements.",[196,529,531],{"id":530},"adding-a-feature","Adding a feature",[184,533,534],{},"Most features are one of Better Auth's plugins. A feature is done when it has:",[536,537,538,549,555,564,569,575],"ol",{},[539,540,541,544,545,548],"li",{},[503,542,543],{},"A module option"," in ",[204,546,547],{},"src\u002Fmodule.ts",", off by default, documented with Better Auth's defaults, that adds the\nplugin to the server and client configs.",[539,550,551,554],{},[503,552,553],{},"Pages that read the set-up at runtime",", from the capabilities route, so they also work when an app adds the\nplugin itself.",[539,556,557,560,561,331],{},[503,558,559],{},"Words in English and Spanish",", in ",[204,562,563],{},"src\u002Fruntime\u002Fapp\u002Fi18n\u002F",[539,565,566],{},[503,567,568],{},"A row on the admin's configuration page.",[539,570,571,574],{},[503,572,573],{},"Tests:"," an API test of what the server does, and a browser test when there's UI.",[539,576,577,580,581,331],{},[503,578,579],{},"A docs page",", or a section on one, in ",[204,582,583],{},"docs\u002Fcontent\u002F",[221,585,587],{"id":586},"ground-rules","Ground rules",[589,590,591,597,603,615,621],"ul",{},[539,592,593,596],{},[503,594,595],{},"Better Auth does the work."," Use its endpoints wherever it has them. The module's own routes are only for what\nBetter Auth has no endpoint for, and each checks the same Better Auth permission the action needs.",[539,598,599,602],{},[503,600,601],{},"Never change Better Auth's tables"," or replace its endpoints. The module's own data goes in its own tables,\nthrough Better Auth's migrations.",[539,604,605,608,609,614],{},[503,606,607],{},"Rely on documented behaviour."," Check ",[188,610,613],{"href":611,"rel":612},"https:\u002F\u002Fbetter-auth.com\u002Fdocs",[192],"Better Auth's docs"," for the version in use.\nWhen something only works through undocumented code (like the OAuth Popup plugin today), say so in the docs.",[539,616,617,620],{},[503,618,619],{},"No patched dependencies."," If a package needs patching to work, we replace it or work without it.",[539,622,623,626,627,630,631,634],{},[503,624,625],{},"Server-render pages."," Fetch page data with ",[204,628,629],{},"useFetch",", and render dates with ",[204,632,633],{},"\u003CNuxtTime>",", so the server and the\nbrowser agree.",[196,636,638],{"id":637},"commits-and-pull-requests","Commits and pull requests",[589,640,641,648,670],{},[539,642,643,644,647],{},"Branch from ",[204,645,646],{},"main",", and open your pull request against it.",[539,649,650,651,656,657,660,661,660,664,660,667,331],{},"Write commits as ",[188,652,655],{"href":653,"rel":654},"https:\u002F\u002Fwww.conventionalcommits.org",[192],"Conventional Commits",": ",[204,658,659],{},"feat(sso): sign in by organization slug",", ",[204,662,663],{},"fix(admin): …",[204,665,666],{},"docs: …",[204,668,669],{},"test(browser): …",[539,671,672],{},"Explain what changed and why in the pull request, and how you tested it.",[196,674,676],{"id":675},"the-docs","The docs",[226,678,680],{"className":228,"code":679,"filename":230,"language":231,"meta":232,"style":232},"pnpm docs:dev       # http:\u002F\u002Flocalhost:3002\npnpm docs:generate  # the static build, as GitHub Pages serves it\n",[204,681,682,692],{"__ignoreMap":232},[236,683,684,686,689],{"class":238,"line":239},[236,685,266],{"class":242},[236,687,688],{"class":246}," docs:dev",[236,690,691],{"class":467},"       # http:\u002F\u002Flocalhost:3002\n",[236,693,694,696,699],{"class":238,"line":253},[236,695,266],{"class":242},[236,697,698],{"class":246}," docs:generate",[236,700,701],{"class":467},"  # the static build, as GitHub Pages serves it\n",[184,703,704,705,707,708,713,714,717,718,720,721,723],{},"Pages are Markdown in ",[204,706,583],{},", with ",[188,709,712],{"href":710,"rel":711},"https:\u002F\u002Fui.nuxt.com\u002Fdocs\u002Ftypography",[192],"Nuxt UI's prose components",". Options\nuse ",[204,715,716],{},"::field{name type default}",". Pushes to ",[204,719,646],{}," that change ",[204,722,410],{}," publish the site.",[221,725,727],{"id":726},"screenshots","Screenshots",[184,729,730],{},"The screenshots come from the playground, in light and dark. Retake them after changing a page that's pictured:",[226,732,734],{"className":228,"code":733,"filename":230,"language":231,"meta":232,"style":232},"pnpm build && pnpm dev:build\npnpm docs:screenshots\n",[204,735,736,753],{"__ignoreMap":232},[236,737,738,740,743,747,750],{"class":238,"line":239},[236,739,266],{"class":242},[236,741,742],{"class":246}," build",[236,744,746],{"class":745},"sMK4o"," &&",[236,748,749],{"class":242}," pnpm",[236,751,752],{"class":246}," dev:build\n",[236,754,755,757],{"class":238,"line":253},[236,756,266],{"class":242},[236,758,759],{"class":246}," docs:screenshots\n",[184,761,762,763,766,767,770,771,331],{},"The script (",[204,764,765],{},"docs\u002Fscripts\u002Fscreenshots.mjs",") starts its own playground on port 3943 with a fresh database, so it never\ntouches your dev server. It sets up an example organization, then saves ",[204,768,769],{},"docs\u002Fpublic\u002Fscreenshots\u002F\u003Cname>-\u003Clight|dark>.webp",".\nShow one on a page with ",[204,772,773],{},":screenshot{name=\"admin-home\" alt=\"…\"}",[196,775,777],{"id":776},"license","License",[184,779,780,781,331],{},"By contributing, you agree that your contributions are licensed under the project's\n",[188,782,785],{"href":783,"rel":784},"https:\u002F\u002Fgithub.com\u002Ftreygrr\u002Fnuxt-better-auth-ui\u002Fblob\u002Fmain\u002FLICENSE",[192],"MIT license",[787,788,789],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}",{"title":232,"searchDepth":239,"depth":253,"links":791},[792,793,796,799,802,803,806],{"id":198,"depth":253,"text":199},{"id":334,"depth":253,"text":335,"children":794},[795],{"id":416,"depth":263,"text":417},{"id":448,"depth":253,"text":449,"children":797},[798],{"id":497,"depth":263,"text":498},{"id":530,"depth":253,"text":531,"children":800},[801],{"id":586,"depth":263,"text":587},{"id":637,"depth":253,"text":638},{"id":675,"depth":253,"text":676,"children":804},[805],{"id":726,"depth":263,"text":727},{"id":776,"depth":253,"text":777},"Set up the repository, run the playground and tests, and add a feature the way the module does.","md",null,{},{"icon":177},{"title":174,"description":807},"evPhdWcODMb8lblrqER3tVxAJP-JzAz1gLMyzZSOVaY",[815,809],{"title":169,"path":170,"stem":171,"description":816,"icon":172,"children":-1},"Every composable, component, utility and hook the module gives your app.",1793019845303]