[{"data":1,"prerenderedAt":2013},["ShallowReactive",2],{"navigation_docs":3,"-core-concepts-route-protection":152,"-core-concepts-route-protection-surround":2008},[4,42,68,110,131],{"title":5,"path":6,"stem":7,"children":8,"icon":11},"Getting Started","/getting-started","1.getting-started/0.index",[9,12,17,22,27,32,37],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-sparkles",{"title":13,"path":14,"stem":15,"icon":16},"Installation","/getting-started/installation","1.getting-started/1.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Configuration","/getting-started/configuration","1.getting-started/2.configuration","i-lucide-settings",{"title":23,"path":24,"stem":25,"icon":26},"Client Setup","/getting-started/client-setup","1.getting-started/3.client-setup","i-lucide-monitor",{"title":28,"path":29,"stem":30,"icon":31},"Type Augmentation","/getting-started/type-augmentation","1.getting-started/4.type-augmentation","i-lucide-type",{"title":33,"path":34,"stem":35,"icon":36},"Schema Generation (NuxtHub)","/getting-started/schema-generation","1.getting-started/5.schema-generation","i-lucide-database",{"title":38,"path":39,"stem":40,"icon":41},"How It Works","/getting-started/how-it-works","1.getting-started/6.how-it-works","i-lucide-workflow",{"title":43,"path":44,"stem":45,"children":46,"page":67},"Core Concepts","/core-concepts","2.core-concepts",[47,51,55,59,63],{"title":48,"path":49,"stem":50},"serverAuth()","/core-concepts/server-auth","2.core-concepts/1.server-auth",{"title":52,"path":53,"stem":54},"Sessions","/core-concepts/sessions","2.core-concepts/2.sessions",{"title":56,"path":57,"stem":58},"Route Protection","/core-concepts/route-protection","2.core-concepts/3.route-protection",{"title":60,"path":61,"stem":62},"Auto‑Imports and Aliases","/core-concepts/auto-imports-aliases","2.core-concepts/4.auto-imports-aliases",{"title":64,"path":65,"stem":66},"Security & Caveats","/core-concepts/security-caveats","2.core-concepts/5.security-caveats",false,{"title":69,"path":70,"stem":71,"children":72,"page":67},"Guides","/guides","3.guides",[73,77,81,85,89,94,98,102,106],{"title":74,"path":75,"stem":76},"Role‑Based Access","/guides/role-based-access","3.guides/1.role-based-access",{"title":78,"path":79,"stem":80},"OAuth Providers","/guides/oauth-providers","3.guides/2.oauth-providers",{"title":82,"path":83,"stem":84},"Custom Database","/guides/custom-database","3.guides/3.custom-database",{"title":86,"path":87,"stem":88},"Database-less Mode","/guides/database-less-mode","3.guides/4.database-less-mode",{"title":90,"path":91,"stem":92,"icon":93},"External Auth Backend","/guides/external-auth-backend","3.guides/5.external-auth-backend","i-lucide-server",{"title":95,"path":96,"stem":97},"Migrating from nuxt-auth-utils","/guides/migrate-from-nuxt-auth-utils","3.guides/6.migrate-from-nuxt-auth-utils",{"title":99,"path":100,"stem":101},"Two-Factor Authentication (TOTP + Backup Codes)","/guides/two-factor-auth","3.guides/7.two-factor-auth",{"title":103,"path":104,"stem":105},"Testing","/guides/testing","3.guides/8.testing",{"title":107,"path":108,"stem":109},"Production Deployment","/guides/production-deployment","3.guides/9.production-deployment",{"title":111,"path":112,"stem":113,"children":114,"page":67},"Integrations","/integrations","4.integrations",[115,119,123,127],{"title":116,"path":117,"stem":118},"NuxtHub","/integrations/nuxthub","4.integrations/1.nuxthub",{"title":120,"path":121,"stem":122},"DevTools","/integrations/devtools","4.integrations/2.devtools",{"title":124,"path":125,"stem":126},"Convex","/integrations/convex","4.integrations/3.convex",{"title":128,"path":129,"stem":130},"i18n","/integrations/i18n","4.integrations/4.i18n",{"title":132,"path":133,"stem":134,"children":135,"page":67},"API Reference","/api","5.api",[136,140,144,148],{"title":137,"path":138,"stem":139},"Composables","/api/composables","5.api/1.composables",{"title":141,"path":142,"stem":143},"Server Utilities","/api/server-utils","5.api/2.server-utils",{"title":145,"path":146,"stem":147},"Components","/api/components","5.api/3.components",{"title":149,"path":150,"stem":151},"Types","/api/types","5.api/4.types",{"id":153,"title":56,"body":154,"description":2002,"extension":2003,"links":2004,"meta":2005,"navigation":184,"path":57,"seo":2006,"stem":58,"__hash__":2007},"docs/2.core-concepts/3.route-protection.md",{"type":155,"value":156,"toc":1984},"minimark",[157,251,256,337,342,350,397,412,505,509,523,754,759,897,909,921,944,947,951,960,1015,1019,1022,1118,1122,1128,1221,1225,1230,1315,1348,1351,1355,1358,1417,1428,1439,1442,1679,1683,1687,1691,1694,1760,1764,1871,1875,1881,1970,1973,1980],[158,159,160],"code-collapse",{},[161,162,168],"pre",{"className":163,"code":164,"filename":165,"language":166,"meta":167,"style":167},"language-txt shiki shiki-themes one-light synthwave-84 synthwave-84","Protect routes and API endpoints with @onmax/nuxt-better-auth.\n\n- Route Rules in `nuxt.config.ts`: `routeRules: { '/app/**': { auth: { only: 'user', redirectTo: '/login' } } }`\n- Guest-only pages: `{ auth: { only: 'guest', redirectTo: '/app' } }`\n- Role-based: `{ auth: { user: { role: 'admin' } } }` — arrays use OR logic\n- Page Meta: `definePageMeta({ auth: 'user' })` for per-page control\n- Server API: `await requireUserSession(event)` — throws 401 if not authenticated\n- Role + custom rules: `requireUserSession(event, { user: { role: 'admin' }, rule: ({ user }) => user.verified })`\n- Route rules auto-sync to client router for instant redirects\n- Always protect API endpoints with `requireUserSession` — route rules are UX only\n\nRead more: https://better-auth.nuxt.dev/raw/core-concepts/route-protection.md\nSource: https://github.com/nuxt-modules/better-auth\n","Prompt","txt","",[169,170,171,179,186,192,198,204,210,216,222,228,234,239,245],"code",{"__ignoreMap":167},[172,173,176],"span",{"class":174,"line":175},"line",1,[172,177,178],{},"Protect routes and API endpoints with @onmax/nuxt-better-auth.\n",[172,180,182],{"class":174,"line":181},2,[172,183,185],{"emptyLinePlaceholder":184},true,"\n",[172,187,189],{"class":174,"line":188},3,[172,190,191],{},"- Route Rules in `nuxt.config.ts`: `routeRules: { '/app/**': { auth: { only: 'user', redirectTo: '/login' } } }`\n",[172,193,195],{"class":174,"line":194},4,[172,196,197],{},"- Guest-only pages: `{ auth: { only: 'guest', redirectTo: '/app' } }`\n",[172,199,201],{"class":174,"line":200},5,[172,202,203],{},"- Role-based: `{ auth: { user: { role: 'admin' } } }` — arrays use OR logic\n",[172,205,207],{"class":174,"line":206},6,[172,208,209],{},"- Page Meta: `definePageMeta({ auth: 'user' })` for per-page control\n",[172,211,213],{"class":174,"line":212},7,[172,214,215],{},"- Server API: `await requireUserSession(event)` — throws 401 if not authenticated\n",[172,217,219],{"class":174,"line":218},8,[172,220,221],{},"- Role + custom rules: `requireUserSession(event, { user: { role: 'admin' }, rule: ({ user }) => user.verified })`\n",[172,223,225],{"class":174,"line":224},9,[172,226,227],{},"- Route rules auto-sync to client router for instant redirects\n",[172,229,231],{"class":174,"line":230},10,[172,232,233],{},"- Always protect API endpoints with `requireUserSession` — route rules are UX only\n",[172,235,237],{"class":174,"line":236},11,[172,238,185],{"emptyLinePlaceholder":184},[172,240,242],{"class":174,"line":241},12,[172,243,244],{},"Read more: https://better-auth.nuxt.dev/raw/core-concepts/route-protection.md\n",[172,246,248],{"class":174,"line":247},13,[172,249,250],{},"Source: https://github.com/nuxt-modules/better-auth\n",[252,253,255],"h2",{"id":254},"quick-reference","Quick Reference",[257,258,259,276],"table",{},[260,261,262],"thead",{},[263,264,265,270,273],"tr",{},[266,267,269],"th",{"align":268},"left","Method",[266,271,272],{"align":268},"Scope",[266,274,275],{"align":268},"Use Case",[277,278,279,298,311,324],"tbody",{},[263,280,281,288,291],{},[282,283,284],"td",{"align":268},[285,286,287],"strong",{},"Route Rules",[282,289,290],{"align":268},"Global",[282,292,293,294,297],{"align":268},"Protecting whole sections (e.g., ",[169,295,296],{},"/admin/**",").",[263,299,300,305,308],{},[282,301,302],{"align":268},[285,303,304],{},"Page Meta",[282,306,307],{"align":268},"Per-Page",[282,309,310],{"align":268},"Specific logic for a single page.",[263,312,313,318,321],{},[282,314,315],{"align":268},[285,316,317],{},"Middleware",[282,319,320],{"align":268},"Client",[282,322,323],{"align":268},"Complex client-side navigation logic.",[263,325,326,331,334],{},[282,327,328],{"align":268},[285,329,330],{},"Server Utils",[282,332,333],{"align":268},"API",[282,335,336],{"align":268},"Protecting API endpoints.",[338,339,341],"h3",{"id":340},"matching-logic","Matching Logic",[343,344,345,346,349],"p",{},"Role arrays use ",[285,347,348],{},"OR"," logic: the user needs any one of the listed values.",[161,351,355],{"className":352,"code":353,"language":354,"meta":167,"style":167},"language-ts shiki shiki-themes one-light synthwave-84 synthwave-84","// User needs role 'admin' OR 'moderator' (not both)\nauth: { user: { role: ['admin', 'moderator'] } }\n","ts",[169,356,357,363],{"__ignoreMap":167},[172,358,359],{"class":174,"line":175},[172,360,362],{"class":361},"st7cf","// User needs role 'admin' OR 'moderator' (not both)\n",[172,364,365,369,373,376,378,381,384,388,391,394],{"class":174,"line":181},[172,366,368],{"class":367},"sivOE","auth",[172,370,372],{"class":371},"s17Py",": { ",[172,374,375],{"class":367},"user",[172,377,372],{"class":371},[172,379,380],{"class":367},"role",[172,382,383],{"class":371},": [",[172,385,387],{"class":386},"sPAZv","'admin'",[172,389,390],{"class":371},", ",[172,392,393],{"class":386},"'moderator'",[172,395,396],{"class":371},"] } }\n",[343,398,399,400,403,404,407,408,411],{},"For ",[285,401,402],{},"AND"," logic (user needs multiple conditions), use ",[169,405,406],{},"requireUserSession"," with a ",[169,409,410],{},"rule"," callback in your server handlers:",[161,413,416],{"className":352,"code":414,"filename":415,"language":354,"meta":167,"style":167},"await requireUserSession(event, {\n  user: { role: 'admin' },\n  rule: ({ user }) => user.verified === true,\n})\n","server/api/admin/report.ts",[169,417,418,438,461,500],{"__ignoreMap":167},[172,419,420,424,428,431,435],{"class":174,"line":175},[172,421,423],{"class":422},"sqe1H","await",[172,425,427],{"class":426},"sfT9l"," requireUserSession",[172,429,430],{"class":371},"(",[172,432,434],{"class":433},"svFNh","event",[172,436,437],{"class":371},", {\n",[172,439,440,444,448,451,453,455,458],{"class":174,"line":181},[172,441,443],{"class":442},"sYvLG","  user",[172,445,447],{"class":446},"sVnqq",":",[172,449,450],{"class":371}," { ",[172,452,380],{"class":442},[172,454,447],{"class":446},[172,456,457],{"class":386}," 'admin'",[172,459,460],{"class":371}," },\n",[172,462,463,466,468,471,474,477,480,483,486,489,493,497],{"class":174,"line":188},[172,464,465],{"class":426},"  rule",[172,467,447],{"class":446},[172,469,470],{"class":371}," ({ ",[172,472,375],{"class":473},"sgisi",[172,475,476],{"class":371}," }) ",[172,478,479],{"class":422},"=>",[172,481,482],{"class":433}," user",[172,484,485],{"class":371},".",[172,487,488],{"class":442},"verified",[172,490,492],{"class":491},"sn-Jc"," ===",[172,494,496],{"class":495},"s3ZNE"," true",[172,498,499],{"class":371},",\n",[172,501,502],{"class":174,"line":194},[172,503,504],{"class":371},"})\n",[252,506,508],{"id":507},"_1-route-rules","1. Route Rules",[343,510,511,512,515,516,519,520,485],{},"The most efficient way to protect your app is using route rules in ",[169,513,514],{},"nuxt.config.ts",". You can define them under ",[169,517,518],{},"routeRules"," or ",[169,521,522],{},"nitro.routeRules",[161,524,526],{"className":352,"code":525,"filename":514,"language":354,"meta":167,"style":167},"export default defineNuxtConfig({\n  routeRules: {\n    // Authenticated users only\n    '/app/**': { auth: { only: 'user', redirectTo: '/login' } },\n    \n    // Guests only (e.g. login page)\n    '/login': { auth: { only: 'guest', redirectTo: '/app' } },\n    \n    // Admin role only\n    '/admin/**': { auth: { user: { role: 'admin' } } },\n    \n    // Admin OR Moderator\n    '/staff/**': { \n      auth: { \n        user: { role: ['admin', 'moderator'] } \n      } \n    }\n  }\n})\n",[169,527,528,543,553,558,594,599,604,637,641,646,676,680,685,695,705,731,737,743,749],{"__ignoreMap":167},[172,529,530,533,537,540],{"class":174,"line":175},[172,531,532],{"class":422},"export",[172,534,536],{"class":535},"sKg8T"," default",[172,538,539],{"class":426}," defineNuxtConfig",[172,541,542],{"class":371},"({\n",[172,544,545,548,550],{"class":174,"line":181},[172,546,547],{"class":442},"  routeRules",[172,549,447],{"class":446},[172,551,552],{"class":371}," {\n",[172,554,555],{"class":174,"line":188},[172,556,557],{"class":361},"    // Authenticated users only\n",[172,559,560,563,565,567,569,571,573,576,578,581,583,586,588,591],{"class":174,"line":194},[172,561,562],{"class":386},"    '/app/**'",[172,564,447],{"class":446},[172,566,450],{"class":371},[172,568,368],{"class":442},[172,570,447],{"class":446},[172,572,450],{"class":371},[172,574,575],{"class":442},"only",[172,577,447],{"class":446},[172,579,580],{"class":386}," 'user'",[172,582,390],{"class":371},[172,584,585],{"class":442},"redirectTo",[172,587,447],{"class":446},[172,589,590],{"class":386}," '/login'",[172,592,593],{"class":371}," } },\n",[172,595,596],{"class":174,"line":200},[172,597,598],{"class":371},"    \n",[172,600,601],{"class":174,"line":206},[172,602,603],{"class":361},"    // Guests only (e.g. login page)\n",[172,605,606,609,611,613,615,617,619,621,623,626,628,630,632,635],{"class":174,"line":212},[172,607,608],{"class":386},"    '/login'",[172,610,447],{"class":446},[172,612,450],{"class":371},[172,614,368],{"class":442},[172,616,447],{"class":446},[172,618,450],{"class":371},[172,620,575],{"class":442},[172,622,447],{"class":446},[172,624,625],{"class":386}," 'guest'",[172,627,390],{"class":371},[172,629,585],{"class":442},[172,631,447],{"class":446},[172,633,634],{"class":386}," '/app'",[172,636,593],{"class":371},[172,638,639],{"class":174,"line":218},[172,640,598],{"class":371},[172,642,643],{"class":174,"line":224},[172,644,645],{"class":361},"    // Admin role only\n",[172,647,648,651,653,655,657,659,661,663,665,667,669,671,673],{"class":174,"line":230},[172,649,650],{"class":386},"    '/admin/**'",[172,652,447],{"class":446},[172,654,450],{"class":371},[172,656,368],{"class":442},[172,658,447],{"class":446},[172,660,450],{"class":371},[172,662,375],{"class":442},[172,664,447],{"class":446},[172,666,450],{"class":371},[172,668,380],{"class":442},[172,670,447],{"class":446},[172,672,457],{"class":386},[172,674,675],{"class":371}," } } },\n",[172,677,678],{"class":174,"line":236},[172,679,598],{"class":371},[172,681,682],{"class":174,"line":241},[172,683,684],{"class":361},"    // Admin OR Moderator\n",[172,686,687,690,692],{"class":174,"line":247},[172,688,689],{"class":386},"    '/staff/**'",[172,691,447],{"class":446},[172,693,694],{"class":371}," { \n",[172,696,698,701,703],{"class":174,"line":697},14,[172,699,700],{"class":442},"      auth",[172,702,447],{"class":446},[172,704,694],{"class":371},[172,706,708,711,713,715,717,719,722,724,726,728],{"class":174,"line":707},15,[172,709,710],{"class":442},"        user",[172,712,447],{"class":446},[172,714,450],{"class":371},[172,716,380],{"class":442},[172,718,447],{"class":446},[172,720,721],{"class":371}," [",[172,723,387],{"class":386},[172,725,390],{"class":371},[172,727,393],{"class":386},[172,729,730],{"class":371},"] } \n",[172,732,734],{"class":174,"line":733},16,[172,735,736],{"class":371},"      } \n",[172,738,740],{"class":174,"line":739},17,[172,741,742],{"class":371},"    }\n",[172,744,746],{"class":174,"line":745},18,[172,747,748],{"class":371},"  }\n",[172,750,752],{"class":174,"line":751},19,[172,753,504],{"class":371},[343,755,756,757,447],{},"The same auth keys work under ",[169,758,522],{},[161,760,762],{"className":352,"code":761,"filename":514,"language":354,"meta":167,"style":167},"export default defineNuxtConfig({\n  nitro: {\n    routeRules: {\n      '/app/**': { auth: { only: 'user', redirectTo: '/login' } },\n      '/login': { auth: { only: 'guest', redirectTo: '/app' } },\n      '/admin/**': { auth: { user: { role: 'admin' } } },\n    },\n  },\n})\n",[169,763,764,774,783,792,823,854,883,888,893],{"__ignoreMap":167},[172,765,766,768,770,772],{"class":174,"line":175},[172,767,532],{"class":422},[172,769,536],{"class":535},[172,771,539],{"class":426},[172,773,542],{"class":371},[172,775,776,779,781],{"class":174,"line":181},[172,777,778],{"class":442},"  nitro",[172,780,447],{"class":446},[172,782,552],{"class":371},[172,784,785,788,790],{"class":174,"line":188},[172,786,787],{"class":442},"    routeRules",[172,789,447],{"class":446},[172,791,552],{"class":371},[172,793,794,797,799,801,803,805,807,809,811,813,815,817,819,821],{"class":174,"line":194},[172,795,796],{"class":386},"      '/app/**'",[172,798,447],{"class":446},[172,800,450],{"class":371},[172,802,368],{"class":442},[172,804,447],{"class":446},[172,806,450],{"class":371},[172,808,575],{"class":442},[172,810,447],{"class":446},[172,812,580],{"class":386},[172,814,390],{"class":371},[172,816,585],{"class":442},[172,818,447],{"class":446},[172,820,590],{"class":386},[172,822,593],{"class":371},[172,824,825,828,830,832,834,836,838,840,842,844,846,848,850,852],{"class":174,"line":200},[172,826,827],{"class":386},"      '/login'",[172,829,447],{"class":446},[172,831,450],{"class":371},[172,833,368],{"class":442},[172,835,447],{"class":446},[172,837,450],{"class":371},[172,839,575],{"class":442},[172,841,447],{"class":446},[172,843,625],{"class":386},[172,845,390],{"class":371},[172,847,585],{"class":442},[172,849,447],{"class":446},[172,851,634],{"class":386},[172,853,593],{"class":371},[172,855,856,859,861,863,865,867,869,871,873,875,877,879,881],{"class":174,"line":206},[172,857,858],{"class":386},"      '/admin/**'",[172,860,447],{"class":446},[172,862,450],{"class":371},[172,864,368],{"class":442},[172,866,447],{"class":446},[172,868,450],{"class":371},[172,870,375],{"class":442},[172,872,447],{"class":446},[172,874,450],{"class":371},[172,876,380],{"class":442},[172,878,447],{"class":446},[172,880,457],{"class":386},[172,882,675],{"class":371},[172,884,885],{"class":174,"line":212},[172,886,887],{"class":371},"    },\n",[172,889,890],{"class":174,"line":218},[172,891,892],{"class":371},"  },\n",[172,894,895],{"class":174,"line":224},[172,896,504],{"class":371},[898,899,900,901,903,904,906,907,485],"note",{},"If both ",[169,902,518],{}," and ",[169,905,522],{}," are present, the module reads ",[169,908,522],{},[343,910,911,912,914,915,390,918,297],{},"If ",[169,913,585],{}," is omitted, shorthand defaults apply (",[169,916,917],{},"'user' -> '/login'",[169,919,920],{},"'guest' -> '/'",[922,923,924,941],"tip",{},[343,925,911,926,929,930,932,933,936,937,940],{},[169,927,928],{},"auth: { user: { ... } }"," complains about missing fields (e.g. ",[169,931,380],{},"), ensure your Better Auth plugin fields are inferred or that you have a working ",[169,934,935],{},"#nuxt-better-auth"," type augmentation in a root ",[169,938,939],{},"*.d.ts"," file.",[942,943],"read-more",{"title":28,"to":29},[898,945,946],{},"These rules are automatically synced to the client-side router, ensuring instant redirects without server roundtrips for navigation.",[252,948,950],{"id":949},"_2-page-meta","2. Page Meta",[343,952,953,954,957,958,485],{},"For page-specific control, use ",[169,955,956],{},"definePageMeta"," within your Vue components. This overrides global ",[169,959,518],{},[161,961,966],{"className":962,"code":963,"filename":964,"language":965,"meta":167,"style":167},"language-vue shiki shiki-themes one-light synthwave-84 synthwave-84","\u003Cscript setup>\ndefinePageMeta({\n  auth: 'user'\n})\n\u003C/script>\n","pages/dashboard.vue","vue",[169,967,968,985,992,1002,1006],{"__ignoreMap":167},[172,969,970,974,978,982],{"class":174,"line":175},[172,971,973],{"class":972},"sL9le","\u003C",[172,975,977],{"class":976},"stweg","script",[172,979,981],{"class":980},"s0frj"," setup",[172,983,984],{"class":972},">\n",[172,986,987,989],{"class":174,"line":181},[172,988,956],{"class":426},[172,990,542],{"class":991},"sEEOt",[172,993,994,997,999],{"class":174,"line":188},[172,995,996],{"class":442},"  auth",[172,998,447],{"class":446},[172,1000,1001],{"class":386}," 'user'\n",[172,1003,1004],{"class":174,"line":194},[172,1005,504],{"class":991},[172,1007,1008,1011,1013],{"class":174,"line":200},[172,1009,1010],{"class":972},"\u003C/",[172,1012,977],{"class":976},[172,1014,984],{"class":972},[338,1016,1018],{"id":1017},"advanced-options","Advanced Options",[343,1020,1021],{},"You can pass an object for granular control:",[161,1023,1025],{"className":352,"code":1024,"language":354,"meta":167,"style":167},"definePageMeta({\n  auth: {\n    // Only allow authenticated users\n    only: 'user',\n    \n    // Redirect blocked users to a specific page\n    redirectTo: '/subscribe',\n    \n    // Match specific user properties\n    user: {\n      verified: true\n    }\n  }\n})\n",[169,1026,1027,1033,1041,1046,1057,1061,1066,1078,1082,1087,1096,1106,1110,1114],{"__ignoreMap":167},[172,1028,1029,1031],{"class":174,"line":175},[172,1030,956],{"class":426},[172,1032,542],{"class":371},[172,1034,1035,1037,1039],{"class":174,"line":181},[172,1036,996],{"class":442},[172,1038,447],{"class":446},[172,1040,552],{"class":371},[172,1042,1043],{"class":174,"line":188},[172,1044,1045],{"class":361},"    // Only allow authenticated users\n",[172,1047,1048,1051,1053,1055],{"class":174,"line":194},[172,1049,1050],{"class":442},"    only",[172,1052,447],{"class":446},[172,1054,580],{"class":386},[172,1056,499],{"class":371},[172,1058,1059],{"class":174,"line":200},[172,1060,598],{"class":371},[172,1062,1063],{"class":174,"line":206},[172,1064,1065],{"class":361},"    // Redirect blocked users to a specific page\n",[172,1067,1068,1071,1073,1076],{"class":174,"line":212},[172,1069,1070],{"class":442},"    redirectTo",[172,1072,447],{"class":446},[172,1074,1075],{"class":386}," '/subscribe'",[172,1077,499],{"class":371},[172,1079,1080],{"class":174,"line":218},[172,1081,598],{"class":371},[172,1083,1084],{"class":174,"line":224},[172,1085,1086],{"class":361},"    // Match specific user properties\n",[172,1088,1089,1092,1094],{"class":174,"line":230},[172,1090,1091],{"class":442},"    user",[172,1093,447],{"class":446},[172,1095,552],{"class":371},[172,1097,1098,1101,1103],{"class":174,"line":236},[172,1099,1100],{"class":442},"      verified",[172,1102,447],{"class":446},[172,1104,1105],{"class":495}," true\n",[172,1107,1108],{"class":174,"line":241},[172,1109,742],{"class":371},[172,1111,1112],{"class":174,"line":247},[172,1113,748],{"class":371},[172,1115,1116],{"class":174,"line":697},[172,1117,504],{"class":371},[252,1119,1121],{"id":1120},"_3-server-api-protection","3. Server API Protection",[343,1123,1124,1125,1127],{},"Protecting your API endpoints is critical. Use ",[169,1126,406],{}," to enforce authentication on server routes.",[161,1129,1132],{"className":352,"code":1130,"filename":1131,"language":354,"meta":167,"style":167},"export default defineEventHandler(async (event) => {\n  // Throws 401 if not logged in\n  const { user } = await requireUserSession(event)\n  \n  return { secret: 'data' }\n})\n","server/api/secret.get.ts",[169,1133,1134,1160,1165,1194,1199,1217],{"__ignoreMap":167},[172,1135,1136,1138,1140,1143,1145,1148,1151,1153,1156,1158],{"class":174,"line":175},[172,1137,532],{"class":422},[172,1139,536],{"class":535},[172,1141,1142],{"class":426}," defineEventHandler",[172,1144,430],{"class":371},[172,1146,1147],{"class":422},"async",[172,1149,1150],{"class":371}," (",[172,1152,434],{"class":473},[172,1154,1155],{"class":371},") ",[172,1157,479],{"class":422},[172,1159,552],{"class":371},[172,1161,1162],{"class":174,"line":181},[172,1163,1164],{"class":361},"  // Throws 401 if not logged in\n",[172,1166,1167,1170,1172,1175,1178,1182,1185,1187,1189,1191],{"class":174,"line":188},[172,1168,1169],{"class":422},"  const",[172,1171,450],{"class":371},[172,1173,375],{"class":1174},"s6Rhl",[172,1176,1177],{"class":371}," } ",[172,1179,1181],{"class":1180},"sQBpM","=",[172,1183,1184],{"class":422}," await",[172,1186,427],{"class":426},[172,1188,430],{"class":371},[172,1190,434],{"class":442},[172,1192,1193],{"class":371},")\n",[172,1195,1196],{"class":174,"line":194},[172,1197,1198],{"class":371},"  \n",[172,1200,1201,1204,1206,1209,1211,1214],{"class":174,"line":200},[172,1202,1203],{"class":422},"  return",[172,1205,450],{"class":371},[172,1207,1208],{"class":442},"secret",[172,1210,447],{"class":446},[172,1212,1213],{"class":386}," 'data'",[172,1215,1216],{"class":371}," }\n",[172,1218,1219],{"class":174,"line":206},[172,1220,504],{"class":371},[338,1222,1224],{"id":1223},"role-based-access","Role-Based Access",[343,1226,1227,1228,447],{},"You can also pass requirements to ",[169,1229,406],{},[161,1231,1233],{"className":352,"code":1232,"language":354,"meta":167,"style":167},"await requireUserSession(event, {\n  // User must match ALL conditions\n  user: {\n    role: 'admin',\n    verified: true,\n    // OR logic for array values\n    plan: ['pro', 'enterprise']\n  }\n})\n",[169,1234,1235,1247,1252,1260,1271,1282,1287,1307,1311],{"__ignoreMap":167},[172,1236,1237,1239,1241,1243,1245],{"class":174,"line":175},[172,1238,423],{"class":422},[172,1240,427],{"class":426},[172,1242,430],{"class":371},[172,1244,434],{"class":433},[172,1246,437],{"class":371},[172,1248,1249],{"class":174,"line":181},[172,1250,1251],{"class":361},"  // User must match ALL conditions\n",[172,1253,1254,1256,1258],{"class":174,"line":188},[172,1255,443],{"class":442},[172,1257,447],{"class":446},[172,1259,552],{"class":371},[172,1261,1262,1265,1267,1269],{"class":174,"line":194},[172,1263,1264],{"class":442},"    role",[172,1266,447],{"class":446},[172,1268,457],{"class":386},[172,1270,499],{"class":371},[172,1272,1273,1276,1278,1280],{"class":174,"line":200},[172,1274,1275],{"class":442},"    verified",[172,1277,447],{"class":446},[172,1279,496],{"class":495},[172,1281,499],{"class":371},[172,1283,1284],{"class":174,"line":206},[172,1285,1286],{"class":361},"    // OR logic for array values\n",[172,1288,1289,1292,1294,1296,1299,1301,1304],{"class":174,"line":212},[172,1290,1291],{"class":442},"    plan",[172,1293,447],{"class":446},[172,1295,721],{"class":371},[172,1297,1298],{"class":386},"'pro'",[172,1300,390],{"class":371},[172,1302,1303],{"class":386},"'enterprise'",[172,1305,1306],{"class":371},"]\n",[172,1308,1309],{"class":174,"line":218},[172,1310,748],{"class":371},[172,1312,1313],{"class":174,"line":224},[172,1314,504],{"class":371},[161,1316,1318],{"className":352,"code":1317,"language":354,"meta":167,"style":167},"// Custom fields (like 'plan') must be defined in your Better Auth schema\nauth: { user: { plan: ['pro', 'enterprise'] } }\n",[169,1319,1320,1325],{"__ignoreMap":167},[172,1321,1322],{"class":174,"line":175},[172,1323,1324],{"class":361},"// Custom fields (like 'plan') must be defined in your Better Auth schema\n",[172,1326,1327,1329,1331,1333,1335,1338,1340,1342,1344,1346],{"class":174,"line":181},[172,1328,368],{"class":367},[172,1330,372],{"class":371},[172,1332,375],{"class":367},[172,1334,372],{"class":371},[172,1336,1337],{"class":367},"plan",[172,1339,383],{"class":371},[172,1341,1298],{"class":386},[172,1343,390],{"class":371},[172,1345,1303],{"class":386},[172,1347,396],{"class":371},[942,1349],{"title":1350,"to":75},"Role-Based Access guide",[252,1352,1354],{"id":1353},"safe-redirects-after-login","Safe Redirects After Login",[343,1356,1357],{},"When redirecting unauthenticated users to your login page, this module automatically appends a return-to query param by default:",[161,1359,1361],{"className":352,"code":1360,"filename":514,"language":354,"meta":167,"style":167},"export default defineNuxtConfig({\n  auth: {\n    preserveRedirect: true, // default\n    redirectQueryKey: 'redirect', // default\n  },\n})\n",[169,1362,1363,1373,1381,1395,1409,1413],{"__ignoreMap":167},[172,1364,1365,1367,1369,1371],{"class":174,"line":175},[172,1366,532],{"class":422},[172,1368,536],{"class":535},[172,1370,539],{"class":426},[172,1372,542],{"class":371},[172,1374,1375,1377,1379],{"class":174,"line":181},[172,1376,996],{"class":442},[172,1378,447],{"class":446},[172,1380,552],{"class":371},[172,1382,1383,1386,1388,1390,1392],{"class":174,"line":188},[172,1384,1385],{"class":442},"    preserveRedirect",[172,1387,447],{"class":446},[172,1389,496],{"class":495},[172,1391,390],{"class":371},[172,1393,1394],{"class":361},"// default\n",[172,1396,1397,1400,1402,1405,1407],{"class":174,"line":194},[172,1398,1399],{"class":442},"    redirectQueryKey",[172,1401,447],{"class":446},[172,1403,1404],{"class":386}," 'redirect'",[172,1406,390],{"class":371},[172,1408,1394],{"class":361},[172,1410,1411],{"class":174,"line":200},[172,1412,892],{"class":371},[172,1414,1415],{"class":174,"line":206},[172,1416,504],{"class":371},[343,1418,1419,1420,1423,1424,1427],{},"Your login page can then read ",[169,1421,1422],{},"route.query.redirect"," (or your custom ",[169,1425,1426],{},"auth.redirectQueryKey",") to navigate back after a successful login.",[343,1429,1430,1431,1434,1435,1438],{},"You can also set ",[169,1432,1433],{},"auth.redirects.authenticated"," to define where users land after successful login/sign-up when ",[169,1436,1437],{},"onSuccess"," is not provided in the auth method call.",[343,1440,1441],{},"When preserving the original URL for post-login redirects, validate it to prevent open redirect attacks:",[161,1443,1446],{"className":352,"code":1444,"filename":1445,"language":354,"meta":167,"style":167},"const route = useRoute()\n\nfunction getSafeRedirect() {\n  const redirect = route.query.redirect as string\n  if (!redirect || !redirect.startsWith('/') || redirect.startsWith('//')) {\n    return '/'\n  }\n  return redirect\n}\n\nasync function login(email: string, password: string) {\n  await signIn.email(\n    { email, password },\n    { onSuccess: () => navigateTo(getSafeRedirect()) },\n  )\n}\n","pages/login.vue",[169,1447,1448,1465,1469,1480,1509,1558,1566,1570,1577,1582,1586,1618,1633,1646,1670,1675],{"__ignoreMap":167},[172,1449,1450,1453,1456,1459,1462],{"class":174,"line":175},[172,1451,1452],{"class":422},"const",[172,1454,1455],{"class":1174}," route",[172,1457,1458],{"class":1180}," =",[172,1460,1461],{"class":426}," useRoute",[172,1463,1464],{"class":371},"()\n",[172,1466,1467],{"class":174,"line":181},[172,1468,185],{"emptyLinePlaceholder":184},[172,1470,1471,1474,1477],{"class":174,"line":188},[172,1472,1473],{"class":422},"function",[172,1475,1476],{"class":426}," getSafeRedirect",[172,1478,1479],{"class":371},"() {\n",[172,1481,1482,1484,1487,1489,1491,1493,1496,1498,1501,1505],{"class":174,"line":194},[172,1483,1169],{"class":422},[172,1485,1486],{"class":1174}," redirect",[172,1488,1458],{"class":1180},[172,1490,1455],{"class":433},[172,1492,485],{"class":371},[172,1494,1495],{"class":442},"query",[172,1497,485],{"class":371},[172,1499,1500],{"class":442},"redirect",[172,1502,1504],{"class":1503},"snT_2"," as",[172,1506,1508],{"class":1507},"sr8De"," string\n",[172,1510,1511,1514,1516,1519,1521,1524,1527,1529,1531,1534,1536,1539,1541,1544,1546,1548,1550,1552,1555],{"class":174,"line":200},[172,1512,1513],{"class":422},"  if",[172,1515,1150],{"class":371},[172,1517,1518],{"class":491},"!",[172,1520,1500],{"class":433},[172,1522,1523],{"class":491}," ||",[172,1525,1526],{"class":491}," !",[172,1528,1500],{"class":433},[172,1530,485],{"class":371},[172,1532,1533],{"class":426},"startsWith",[172,1535,430],{"class":371},[172,1537,1538],{"class":386},"'/'",[172,1540,1155],{"class":371},[172,1542,1543],{"class":491},"||",[172,1545,1486],{"class":433},[172,1547,485],{"class":371},[172,1549,1533],{"class":426},[172,1551,430],{"class":371},[172,1553,1554],{"class":386},"'//'",[172,1556,1557],{"class":371},")) {\n",[172,1559,1560,1563],{"class":174,"line":206},[172,1561,1562],{"class":422},"    return",[172,1564,1565],{"class":386}," '/'\n",[172,1567,1568],{"class":174,"line":212},[172,1569,748],{"class":371},[172,1571,1572,1574],{"class":174,"line":218},[172,1573,1203],{"class":422},[172,1575,1576],{"class":433}," redirect\n",[172,1578,1579],{"class":174,"line":224},[172,1580,1581],{"class":371},"}\n",[172,1583,1584],{"class":174,"line":230},[172,1585,185],{"emptyLinePlaceholder":184},[172,1587,1588,1590,1593,1596,1598,1601,1603,1606,1608,1611,1613,1615],{"class":174,"line":236},[172,1589,1147],{"class":422},[172,1591,1592],{"class":422}," function",[172,1594,1595],{"class":426}," login",[172,1597,430],{"class":371},[172,1599,1600],{"class":473},"email",[172,1602,447],{"class":491},[172,1604,1605],{"class":1507}," string",[172,1607,390],{"class":371},[172,1609,1610],{"class":473},"password",[172,1612,447],{"class":491},[172,1614,1605],{"class":1507},[172,1616,1617],{"class":371},") {\n",[172,1619,1620,1623,1626,1628,1630],{"class":174,"line":241},[172,1621,1622],{"class":422},"  await",[172,1624,1625],{"class":433}," signIn",[172,1627,485],{"class":371},[172,1629,1600],{"class":426},[172,1631,1632],{"class":371},"(\n",[172,1634,1635,1638,1640,1642,1644],{"class":174,"line":247},[172,1636,1637],{"class":371},"    { ",[172,1639,1600],{"class":433},[172,1641,390],{"class":371},[172,1643,1610],{"class":433},[172,1645,460],{"class":371},[172,1647,1648,1650,1652,1654,1657,1659,1662,1664,1667],{"class":174,"line":697},[172,1649,1637],{"class":371},[172,1651,1437],{"class":426},[172,1653,447],{"class":446},[172,1655,1656],{"class":371}," () ",[172,1658,479],{"class":422},[172,1660,1661],{"class":426}," navigateTo",[172,1663,430],{"class":371},[172,1665,1666],{"class":426},"getSafeRedirect",[172,1668,1669],{"class":371},"()) },\n",[172,1671,1672],{"class":174,"line":707},[172,1673,1674],{"class":371},"  )\n",[172,1676,1677],{"class":174,"line":733},[172,1678,1581],{"class":371},[1680,1681,1682],"warning",{},"Always validate redirect URLs. Accepting arbitrary URLs allows attackers to redirect users to malicious sites after login.",[252,1684,1686],{"id":1685},"advanced-api-patterns","Advanced API Patterns",[338,1688,1690],{"id":1689},"custom-rule-callback","Custom Rule Callback",[343,1692,1693],{},"For complex authorization logic:",[161,1695,1697],{"className":352,"code":1696,"filename":415,"language":354,"meta":167,"style":167},"const session = await requireUserSession(event, {\n  user: { emailVerified: true },\n  rule: ({ user }) => user.subscriptionActive\n})\n",[169,1698,1699,1718,1735,1756],{"__ignoreMap":167},[172,1700,1701,1703,1706,1708,1710,1712,1714,1716],{"class":174,"line":175},[172,1702,1452],{"class":422},[172,1704,1705],{"class":1174}," session",[172,1707,1458],{"class":1180},[172,1709,1184],{"class":422},[172,1711,427],{"class":426},[172,1713,430],{"class":371},[172,1715,434],{"class":433},[172,1717,437],{"class":371},[172,1719,1720,1722,1724,1726,1729,1731,1733],{"class":174,"line":181},[172,1721,443],{"class":442},[172,1723,447],{"class":446},[172,1725,450],{"class":371},[172,1727,1728],{"class":442},"emailVerified",[172,1730,447],{"class":446},[172,1732,496],{"class":495},[172,1734,460],{"class":371},[172,1736,1737,1739,1741,1743,1745,1747,1749,1751,1753],{"class":174,"line":188},[172,1738,465],{"class":426},[172,1740,447],{"class":446},[172,1742,470],{"class":371},[172,1744,375],{"class":473},[172,1746,476],{"class":371},[172,1748,479],{"class":422},[172,1750,482],{"class":433},[172,1752,485],{"class":371},[172,1754,1755],{"class":442},"subscriptionActive\n",[172,1757,1758],{"class":174,"line":194},[172,1759,504],{"class":371},[338,1761,1763],{"id":1762},"websocket-handlers","WebSocket Handlers",[161,1765,1768],{"className":352,"code":1766,"filename":1767,"language":354,"meta":167,"style":167},"import { defineWebSocketHandler } from 'h3'\n\nexport default defineWebSocketHandler({\n  open: async (peer) => {\n    await requireUserSession(peer.ctx.event, { user: { role: 'member' } })\n  },\n})\n","server/api/ws.ts",[169,1769,1770,1788,1792,1803,1824,1863,1867],{"__ignoreMap":167},[172,1771,1772,1775,1777,1780,1782,1785],{"class":174,"line":175},[172,1773,1774],{"class":422},"import",[172,1776,450],{"class":371},[172,1778,1779],{"class":442},"defineWebSocketHandler",[172,1781,1177],{"class":371},[172,1783,1784],{"class":422},"from",[172,1786,1787],{"class":386}," 'h3'\n",[172,1789,1790],{"class":174,"line":181},[172,1791,185],{"emptyLinePlaceholder":184},[172,1793,1794,1796,1798,1801],{"class":174,"line":188},[172,1795,532],{"class":422},[172,1797,536],{"class":535},[172,1799,1800],{"class":426}," defineWebSocketHandler",[172,1802,542],{"class":371},[172,1804,1805,1808,1810,1813,1815,1818,1820,1822],{"class":174,"line":194},[172,1806,1807],{"class":426},"  open",[172,1809,447],{"class":446},[172,1811,1812],{"class":422}," async",[172,1814,1150],{"class":371},[172,1816,1817],{"class":473},"peer",[172,1819,1155],{"class":371},[172,1821,479],{"class":422},[172,1823,552],{"class":371},[172,1825,1826,1829,1831,1833,1835,1837,1840,1842,1844,1847,1849,1851,1853,1855,1857,1860],{"class":174,"line":200},[172,1827,1828],{"class":422},"    await",[172,1830,427],{"class":426},[172,1832,430],{"class":371},[172,1834,1817],{"class":433},[172,1836,485],{"class":371},[172,1838,1839],{"class":442},"ctx",[172,1841,485],{"class":371},[172,1843,434],{"class":442},[172,1845,1846],{"class":371},", { ",[172,1848,375],{"class":442},[172,1850,447],{"class":446},[172,1852,450],{"class":371},[172,1854,380],{"class":442},[172,1856,447],{"class":446},[172,1858,1859],{"class":386}," 'member'",[172,1861,1862],{"class":371}," } })\n",[172,1864,1865],{"class":174,"line":206},[172,1866,892],{"class":371},[172,1868,1869],{"class":174,"line":212},[172,1870,504],{"class":371},[252,1872,1874],{"id":1873},"csrf-protection","CSRF Protection",[343,1876,1877,1878,447],{},"Better Auth includes CSRF protection by default. Always use the auth client methods instead of raw ",[169,1879,1880],{},"fetch",[161,1882,1884],{"className":352,"code":1883,"language":354,"meta":167,"style":167},"// ✓ Correct: uses auth client\nawait signIn.email({ email, password })\n\n// ✗ Incorrect: bypasses CSRF protection\nawait fetch('/api/auth/sign-in/email', { method: 'POST', body: JSON.stringify({ email, password }) })\n",[169,1885,1886,1891,1913,1917,1922],{"__ignoreMap":167},[172,1887,1888],{"class":174,"line":175},[172,1889,1890],{"class":361},"// ✓ Correct: uses auth client\n",[172,1892,1893,1895,1897,1899,1901,1904,1906,1908,1910],{"class":174,"line":181},[172,1894,423],{"class":422},[172,1896,1625],{"class":433},[172,1898,485],{"class":371},[172,1900,1600],{"class":426},[172,1902,1903],{"class":371},"({ ",[172,1905,1600],{"class":433},[172,1907,390],{"class":371},[172,1909,1610],{"class":433},[172,1911,1912],{"class":371}," })\n",[172,1914,1915],{"class":174,"line":188},[172,1916,185],{"emptyLinePlaceholder":184},[172,1918,1919],{"class":174,"line":194},[172,1920,1921],{"class":361},"// ✗ Incorrect: bypasses CSRF protection\n",[172,1923,1924,1926,1929,1931,1934,1936,1939,1941,1944,1946,1949,1951,1954,1956,1959,1961,1963,1965,1967],{"class":174,"line":200},[172,1925,423],{"class":422},[172,1927,1928],{"class":426}," fetch",[172,1930,430],{"class":371},[172,1932,1933],{"class":386},"'/api/auth/sign-in/email'",[172,1935,1846],{"class":371},[172,1937,1938],{"class":442},"method",[172,1940,447],{"class":446},[172,1942,1943],{"class":386}," 'POST'",[172,1945,390],{"class":371},[172,1947,1948],{"class":442},"body",[172,1950,447],{"class":446},[172,1952,1953],{"class":1174}," JSON",[172,1955,485],{"class":371},[172,1957,1958],{"class":426},"stringify",[172,1960,1903],{"class":371},[172,1962,1600],{"class":433},[172,1964,390],{"class":371},[172,1966,1610],{"class":433},[172,1968,1969],{"class":371}," }) })\n",[942,1971],{"title":1972,"to":65},"Security Caveats",[1974,1975,1976,1977,1979],"important",{},"Route Rules and Page Meta are primarily for UX (redirects). Always protect your API endpoints with ",[169,1978,406],{}," to ensure real security.",[1981,1982,1983],"style",{},"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 .st7cf, html code.shiki .st7cf{--shiki-light:#A0A1A7;--shiki-light-font-style:italic;--shiki-default:#848BBD;--shiki-default-font-style:italic;--shiki-dark:#848BBD;--shiki-dark-font-style:italic}html pre.shiki code .sivOE, html code.shiki .sivOE{--shiki-light:#383A42;--shiki-default:#FE4450;--shiki-dark:#FE4450}html pre.shiki code .s17Py, html code.shiki .s17Py{--shiki-light:#383A42;--shiki-default:#BBBBBB;--shiki-dark:#BBBBBB}html pre.shiki code .sPAZv, html code.shiki .sPAZv{--shiki-light:#50A14F;--shiki-default:#FF8B39;--shiki-dark:#FF8B39}html pre.shiki code .sqe1H, html code.shiki .sqe1H{--shiki-light:#A626A4;--shiki-default:#FEDE5D;--shiki-dark:#FEDE5D}html pre.shiki code .sfT9l, html code.shiki .sfT9l{--shiki-light:#4078F2;--shiki-default:#36F9F6;--shiki-dark:#36F9F6}html pre.shiki code .svFNh, html code.shiki .svFNh{--shiki-light:#383A42;--shiki-default:#FF7EDB;--shiki-dark:#FF7EDB}html pre.shiki code .sYvLG, html code.shiki .sYvLG{--shiki-light:#E45649;--shiki-default:#FF7EDB;--shiki-dark:#FF7EDB}html pre.shiki code .sVnqq, html code.shiki .sVnqq{--shiki-light:#0184BC;--shiki-default:#B6B1B1;--shiki-dark:#B6B1B1}html pre.shiki code .sgisi, html code.shiki .sgisi{--shiki-light:#383A42;--shiki-light-font-style:inherit;--shiki-default:#FF7EDB;--shiki-default-font-style:italic;--shiki-dark:#FF7EDB;--shiki-dark-font-style:italic}html pre.shiki code .sn-Jc, html code.shiki .sn-Jc{--shiki-light:#0184BC;--shiki-default:#FEDE5D;--shiki-dark:#FEDE5D}html pre.shiki code .s3ZNE, html code.shiki .s3ZNE{--shiki-light:#986801;--shiki-default:#F97E72;--shiki-dark:#F97E72}html pre.shiki code .sKg8T, html code.shiki .sKg8T{--shiki-light:#E45649;--shiki-default:#FEDE5D;--shiki-dark:#FEDE5D}html pre.shiki code .sL9le, html code.shiki .sL9le{--shiki-light:#383A42;--shiki-default:#36F9F6;--shiki-dark:#36F9F6}html pre.shiki code .stweg, html code.shiki .stweg{--shiki-light:#E45649;--shiki-default:#72F1B8;--shiki-dark:#72F1B8}html pre.shiki code .s0frj, html code.shiki .s0frj{--shiki-light:#986801;--shiki-light-font-style:inherit;--shiki-default:#FEDE5D;--shiki-default-font-style:italic;--shiki-dark:#FEDE5D;--shiki-dark-font-style:italic}html pre.shiki code .sEEOt, html code.shiki .sEEOt{--shiki-light:#383A42;--shiki-default:#FFFFFFEE;--shiki-dark:#FFFFFFEE}html pre.shiki code .s6Rhl, html code.shiki .s6Rhl{--shiki-light:#986801;--shiki-default:#FF7EDB;--shiki-dark:#FF7EDB}html pre.shiki code .sQBpM, html code.shiki .sQBpM{--shiki-light:#0184BC;--shiki-default:#FFFFFFEE;--shiki-dark:#FFFFFFEE}html pre.shiki code .snT_2, html code.shiki .snT_2{--shiki-light:#383A42;--shiki-default:#FEDE5D;--shiki-dark:#FEDE5D}html pre.shiki code .sr8De, html code.shiki .sr8De{--shiki-light:#0184BC;--shiki-default:#FE4450;--shiki-dark:#FE4450}",{"title":167,"searchDepth":181,"depth":181,"links":1985},[1986,1989,1990,1993,1996,1997,2001],{"id":254,"depth":181,"text":255,"children":1987},[1988],{"id":340,"depth":188,"text":341},{"id":507,"depth":181,"text":508},{"id":949,"depth":181,"text":950,"children":1991},[1992],{"id":1017,"depth":188,"text":1018},{"id":1120,"depth":181,"text":1121,"children":1994},[1995],{"id":1223,"depth":188,"text":1224},{"id":1353,"depth":181,"text":1354},{"id":1685,"depth":181,"text":1686,"children":1998},[1999,2000],{"id":1689,"depth":188,"text":1690},{"id":1762,"depth":188,"text":1763},{"id":1873,"depth":181,"text":1874},"Learn how to protect your pages and API routes using a layered approach.","md",null,{},{"title":56,"description":2002},"sIrLFFYYGBiJL45BSb0kIYmHvOgqs_RjnxS3N7_I3aA",[2009,2011],{"title":52,"path":53,"stem":54,"description":2010,"children":-1},"Access reactive session state with SSR support using `useUserSession()`.",{"title":60,"path":61,"stem":62,"description":2012,"children":-1},"What the module registers for you.",1775080953388]