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