[{"data":1,"prerenderedAt":2009},["ShallowReactive",2],{"navigation_docs":3,"-core-concepts-route-protection":152,"-core-concepts-route-protection-surround":2004},[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":1998,"extension":1999,"links":2000,"meta":2001,"navigation":184,"path":57,"seo":2002,"stem":58,"__hash__":2003},"docs/2.core-concepts/3.route-protection.md",{"type":155,"value":156,"toc":1980},"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,1675,1679,1683,1687,1690,1756,1760,1867,1871,1877,1966,1969,1976],[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()\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,1443,1444,1461,1465,1476,1505,1554,1562,1566,1573,1578,1582,1614,1629,1642,1666,1671],{"__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],{"class":174,"line":181},[172,1464,185],{"emptyLinePlaceholder":184},[172,1466,1467,1470,1473],{"class":174,"line":188},[172,1468,1469],{"class":415},"function",[172,1471,1472],{"class":419}," getSafeRedirect",[172,1474,1475],{"class":364},"() {\n",[172,1477,1478,1480,1483,1485,1487,1489,1492,1494,1497,1501],{"class":174,"line":194},[172,1479,1165],{"class":415},[172,1481,1482],{"class":1170}," redirect",[172,1484,1454],{"class":1176},[172,1486,1451],{"class":426},[172,1488,478],{"class":364},[172,1490,1491],{"class":435},"query",[172,1493,478],{"class":364},[172,1495,1496],{"class":435},"redirect",[172,1498,1500],{"class":1499},"snT_2"," as",[172,1502,1504],{"class":1503},"sr8De"," string\n",[172,1506,1507,1510,1512,1515,1517,1520,1523,1525,1527,1530,1532,1535,1537,1540,1542,1544,1546,1548,1551],{"class":174,"line":200},[172,1508,1509],{"class":415},"  if",[172,1511,1146],{"class":364},[172,1513,1514],{"class":484},"!",[172,1516,1496],{"class":426},[172,1518,1519],{"class":484}," ||",[172,1521,1522],{"class":484}," !",[172,1524,1496],{"class":426},[172,1526,478],{"class":364},[172,1528,1529],{"class":419},"startsWith",[172,1531,423],{"class":364},[172,1533,1534],{"class":379},"'/'",[172,1536,1151],{"class":364},[172,1538,1539],{"class":484},"||",[172,1541,1482],{"class":426},[172,1543,478],{"class":364},[172,1545,1529],{"class":419},[172,1547,423],{"class":364},[172,1549,1550],{"class":379},"'//'",[172,1552,1553],{"class":364},")) {\n",[172,1555,1556,1559],{"class":174,"line":206},[172,1557,1558],{"class":415},"    return",[172,1560,1561],{"class":379}," '/'\n",[172,1563,1564],{"class":174,"line":212},[172,1565,744],{"class":364},[172,1567,1568,1570],{"class":174,"line":218},[172,1569,1199],{"class":415},[172,1571,1572],{"class":426}," redirect\n",[172,1574,1575],{"class":174,"line":224},[172,1576,1577],{"class":364},"}\n",[172,1579,1580],{"class":174,"line":230},[172,1581,185],{"emptyLinePlaceholder":184},[172,1583,1584,1586,1589,1592,1594,1597,1599,1602,1604,1607,1609,1611],{"class":174,"line":671},[172,1585,1143],{"class":415},[172,1587,1588],{"class":415}," function",[172,1590,1591],{"class":419}," login",[172,1593,423],{"class":364},[172,1595,1596],{"class":466},"email",[172,1598,440],{"class":484},[172,1600,1601],{"class":1503}," string",[172,1603,383],{"class":364},[172,1605,1606],{"class":466},"password",[172,1608,440],{"class":484},[172,1610,1601],{"class":1503},[172,1612,1613],{"class":364},") {\n",[172,1615,1616,1619,1622,1624,1626],{"class":174,"line":676},[172,1617,1618],{"class":415},"  await",[172,1620,1621],{"class":426}," signIn",[172,1623,478],{"class":364},[172,1625,1596],{"class":419},[172,1627,1628],{"class":364},"(\n",[172,1630,1631,1634,1636,1638,1640],{"class":174,"line":682},[172,1632,1633],{"class":364},"    { ",[172,1635,1596],{"class":426},[172,1637,383],{"class":364},[172,1639,1606],{"class":426},[172,1641,453],{"class":364},[172,1643,1644,1646,1648,1650,1653,1655,1658,1660,1663],{"class":174,"line":693},[172,1645,1633],{"class":364},[172,1647,1433],{"class":419},[172,1649,440],{"class":439},[172,1651,1652],{"class":364}," () ",[172,1654,472],{"class":415},[172,1656,1657],{"class":419}," navigateTo",[172,1659,423],{"class":364},[172,1661,1662],{"class":419},"getSafeRedirect",[172,1664,1665],{"class":364},"()) },\n",[172,1667,1668],{"class":174,"line":703},[172,1669,1670],{"class":364},"  )\n",[172,1672,1673],{"class":174,"line":729},[172,1674,1577],{"class":364},[1676,1677,1678],"warning",{},"Always validate redirect URLs. Accepting arbitrary URLs allows attackers to redirect users to malicious sites after login.",[239,1680,1682],{"id":1681},"advanced-api-patterns","Advanced API Patterns",[332,1684,1686],{"id":1685},"custom-rule-callback","Custom Rule Callback",[235,1688,1689],{},"For complex authorization logic:",[161,1691,1693],{"className":345,"code":1692,"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,1694,1695,1714,1731,1752],{"__ignoreMap":167},[172,1696,1697,1699,1702,1704,1706,1708,1710,1712],{"class":174,"line":175},[172,1698,1448],{"class":415},[172,1700,1701],{"class":1170}," session",[172,1703,1454],{"class":1176},[172,1705,1180],{"class":415},[172,1707,420],{"class":419},[172,1709,423],{"class":364},[172,1711,427],{"class":426},[172,1713,430],{"class":364},[172,1715,1716,1718,1720,1722,1725,1727,1729],{"class":174,"line":181},[172,1717,436],{"class":435},[172,1719,440],{"class":439},[172,1721,443],{"class":364},[172,1723,1724],{"class":435},"emailVerified",[172,1726,440],{"class":439},[172,1728,489],{"class":488},[172,1730,453],{"class":364},[172,1732,1733,1735,1737,1739,1741,1743,1745,1747,1749],{"class":174,"line":188},[172,1734,458],{"class":419},[172,1736,440],{"class":439},[172,1738,463],{"class":364},[172,1740,368],{"class":466},[172,1742,469],{"class":364},[172,1744,472],{"class":415},[172,1746,475],{"class":426},[172,1748,478],{"class":364},[172,1750,1751],{"class":435},"subscriptionActive\n",[172,1753,1754],{"class":174,"line":194},[172,1755,497],{"class":364},[332,1757,1759],{"id":1758},"websocket-handlers","WebSocket Handlers",[161,1761,1764],{"className":345,"code":1762,"filename":1763,"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,1765,1766,1784,1788,1799,1820,1859,1863],{"__ignoreMap":167},[172,1767,1768,1771,1773,1776,1778,1781],{"class":174,"line":175},[172,1769,1770],{"class":415},"import",[172,1772,443],{"class":364},[172,1774,1775],{"class":435},"defineWebSocketHandler",[172,1777,1173],{"class":364},[172,1779,1780],{"class":415},"from",[172,1782,1783],{"class":379}," 'h3'\n",[172,1785,1786],{"class":174,"line":181},[172,1787,185],{"emptyLinePlaceholder":184},[172,1789,1790,1792,1794,1797],{"class":174,"line":188},[172,1791,525],{"class":415},[172,1793,529],{"class":528},[172,1795,1796],{"class":419}," defineWebSocketHandler",[172,1798,535],{"class":364},[172,1800,1801,1804,1806,1809,1811,1814,1816,1818],{"class":174,"line":194},[172,1802,1803],{"class":419},"  open",[172,1805,440],{"class":439},[172,1807,1808],{"class":415}," async",[172,1810,1146],{"class":364},[172,1812,1813],{"class":466},"peer",[172,1815,1151],{"class":364},[172,1817,472],{"class":415},[172,1819,545],{"class":364},[172,1821,1822,1825,1827,1829,1831,1833,1836,1838,1840,1843,1845,1847,1849,1851,1853,1856],{"class":174,"line":200},[172,1823,1824],{"class":415},"    await",[172,1826,420],{"class":419},[172,1828,423],{"class":364},[172,1830,1813],{"class":426},[172,1832,478],{"class":364},[172,1834,1835],{"class":435},"ctx",[172,1837,478],{"class":364},[172,1839,427],{"class":435},[172,1841,1842],{"class":364},", { ",[172,1844,368],{"class":435},[172,1846,440],{"class":439},[172,1848,443],{"class":364},[172,1850,373],{"class":435},[172,1852,440],{"class":439},[172,1854,1855],{"class":379}," 'member'",[172,1857,1858],{"class":364}," } })\n",[172,1860,1861],{"class":174,"line":206},[172,1862,888],{"class":364},[172,1864,1865],{"class":174,"line":212},[172,1866,497],{"class":364},[239,1868,1870],{"id":1869},"csrf-protection","CSRF Protection",[235,1872,1873,1874,440],{},"Better Auth includes CSRF protection by default. Always use the auth client methods instead of raw ",[169,1875,1876],{},"fetch",[161,1878,1880],{"className":345,"code":1879,"language":347,"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,1881,1882,1887,1909,1913,1918],{"__ignoreMap":167},[172,1883,1884],{"class":174,"line":175},[172,1885,1886],{"class":354},"// ✓ Correct: uses auth client\n",[172,1888,1889,1891,1893,1895,1897,1900,1902,1904,1906],{"class":174,"line":181},[172,1890,416],{"class":415},[172,1892,1621],{"class":426},[172,1894,478],{"class":364},[172,1896,1596],{"class":419},[172,1898,1899],{"class":364},"({ ",[172,1901,1596],{"class":426},[172,1903,383],{"class":364},[172,1905,1606],{"class":426},[172,1907,1908],{"class":364}," })\n",[172,1910,1911],{"class":174,"line":188},[172,1912,185],{"emptyLinePlaceholder":184},[172,1914,1915],{"class":174,"line":194},[172,1916,1917],{"class":354},"// ✗ Incorrect: bypasses CSRF protection\n",[172,1919,1920,1922,1925,1927,1930,1932,1935,1937,1940,1942,1945,1947,1950,1952,1955,1957,1959,1961,1963],{"class":174,"line":200},[172,1921,416],{"class":415},[172,1923,1924],{"class":419}," fetch",[172,1926,423],{"class":364},[172,1928,1929],{"class":379},"'/api/auth/sign-in/email'",[172,1931,1842],{"class":364},[172,1933,1934],{"class":435},"method",[172,1936,440],{"class":439},[172,1938,1939],{"class":379}," 'POST'",[172,1941,383],{"class":364},[172,1943,1944],{"class":435},"body",[172,1946,440],{"class":439},[172,1948,1949],{"class":1170}," JSON",[172,1951,478],{"class":364},[172,1953,1954],{"class":419},"stringify",[172,1956,1899],{"class":364},[172,1958,1596],{"class":426},[172,1960,383],{"class":364},[172,1962,1606],{"class":426},[172,1964,1965],{"class":364}," }) })\n",[938,1967],{"title":1968,"to":65},"Security Caveats",[1970,1971,1972,1973,1975],"important",{},"Route Rules and Page Meta are primarily for UX (redirects). Always protect your API endpoints with ",[169,1974,399],{}," to ensure real security.",[1977,1978,1979],"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":1981},[1982,1985,1986,1989,1992,1993,1997],{"id":241,"depth":181,"text":242,"children":1983},[1984],{"id":334,"depth":188,"text":335},{"id":500,"depth":181,"text":501},{"id":945,"depth":181,"text":946,"children":1987},[1988],{"id":1013,"depth":188,"text":1014},{"id":1116,"depth":181,"text":1117,"children":1990},[1991],{"id":1219,"depth":188,"text":1220},{"id":1349,"depth":181,"text":1350},{"id":1681,"depth":181,"text":1682,"children":1994},[1995,1996],{"id":1685,"depth":188,"text":1686},{"id":1758,"depth":188,"text":1759},{"id":1869,"depth":181,"text":1870},"Learn how to protect your pages and API routes using a layered approach.","md",null,{},{"title":56,"description":1998},"ImM7Q2JC5M3R2r4bcwEwA1sOXNCApPDe-bE3Q4FeJ0o",[2005,2007],{"title":52,"path":53,"stem":54,"description":2006,"children":-1},"Access reactive session state with SSR support using `useUserSession()`.",{"title":60,"path":61,"stem":62,"description":2008,"children":-1},"What the module registers for you.",1777450760655]