[{"data":1,"prerenderedAt":707},["ShallowReactive",2],{"navigation":3,"/docs/recipes/auth-guards-and-permissions":186,"/docs/recipes/auth-guards-and-permissions-surround":702},[4],{"title":5,"path":6,"stem":7,"children":8,"page":39},"Docs","/docs","docs",[9,40,60,78,100,114,158],{"title":10,"path":11,"stem":12,"children":13,"page":39},"Guide","/docs/guide","docs/1.guide",[14,19,24,29,34],{"title":15,"path":16,"stem":17,"icon":18},"Getting Started","/docs/guide/get-started","docs/1.guide/1.get-started","i-lucide-rocket",{"title":20,"path":21,"stem":22,"icon":23},"Basics","/docs/guide/basics","docs/1.guide/2.basics","i-lucide-book-open",{"title":25,"path":26,"stem":27,"icon":28},"Authentication","/docs/guide/auth","docs/1.guide/3.auth","i-lucide-shield-check",{"title":30,"path":31,"stem":32,"icon":33},"Permissions","/docs/guide/permissions","docs/1.guide/4.permissions","i-lucide-shield",{"title":35,"path":36,"stem":37,"icon":38},"Core Concepts","/docs/guide/concepts","docs/1.guide/5.concepts","i-lucide-lightbulb",false,{"title":41,"path":42,"stem":43,"children":44,"page":39},"Data Fetching","/docs/data-fetching","docs/2.data-fetching",[45,50,55],{"title":46,"path":47,"stem":48,"icon":49},"Fetching Data","/docs/data-fetching/queries","docs/2.data-fetching/1.queries","i-lucide-database",{"title":51,"path":52,"stem":53,"icon":54},"Pagination","/docs/data-fetching/pagination","docs/2.data-fetching/2.pagination","i-lucide-list",{"title":56,"path":57,"stem":58,"icon":59},"Caching & Data Reuse","/docs/data-fetching/caching-reuse","docs/2.data-fetching/3.caching-reuse","i-lucide-database-zap",{"title":61,"path":62,"stem":63,"children":64,"page":39},"Mutations","/docs/mutations","docs/3.mutations",[65,69,74],{"title":61,"path":66,"stem":67,"icon":68},"/docs/mutations/mutations","docs/3.mutations/1.mutations","i-lucide-pen-tool",{"title":70,"path":71,"stem":72,"icon":73},"Actions","/docs/mutations/actions","docs/3.mutations/2.actions","i-lucide-zap",{"title":75,"path":76,"stem":77,"icon":73},"Optimistic Updates","/docs/mutations/optimistic-updates","docs/3.mutations/3.optimistic-updates",{"title":79,"path":80,"stem":81,"children":82,"page":39},"Auth Security","/docs/auth-security","docs/4.auth-security",[83,87,91,95],{"title":84,"path":85,"stem":86,"icon":28},"Permissions Setup","/docs/auth-security/permissions-setup","docs/4.auth-security/0.permissions-setup",{"title":25,"path":88,"stem":89,"icon":90},"/docs/auth-security/authentication","docs/4.auth-security/1.authentication","i-lucide-lock",{"title":92,"path":93,"stem":94,"icon":33},"Permissions Reference","/docs/auth-security/permissions","docs/4.auth-security/2.permissions",{"title":96,"path":97,"stem":98,"icon":99},"Standard Role Template","/docs/auth-security/standard-role-template","docs/4.auth-security/3.standard-role-template","i-lucide-file-check",{"title":101,"path":102,"stem":103,"children":104,"page":39},"Server Side","/docs/server-side","docs/5.server-side",[105,110],{"title":106,"path":107,"stem":108,"icon":109},"Server Routes","/docs/server-side/server-routes","docs/5.server-side/1.server-routes","i-lucide-server",{"title":111,"path":112,"stem":113,"icon":109},"SSR & Hydration","/docs/server-side/ssr-hydration","docs/5.server-side/2.ssr-hydration",{"title":115,"path":116,"stem":117,"children":118,"page":39},"Advanced","/docs/advanced","docs/6.advanced",[119,124,129,134,139,144,149,154],{"title":120,"path":121,"stem":122,"icon":123},"Connection State","/docs/advanced/connection-state","docs/6.advanced/1.connection-state","i-lucide-wifi",{"title":125,"path":126,"stem":127,"icon":128},"Client Access","/docs/advanced/client-access","docs/6.advanced/2.client-access","i-lucide-box",{"title":130,"path":131,"stem":132,"icon":133},"Performance","/docs/advanced/performance","docs/6.advanced/3.performance","i-lucide-gauge",{"title":135,"path":136,"stem":137,"icon":138},"Error Handling","/docs/advanced/error-handling","docs/6.advanced/4.error-handling","i-lucide-alert-circle",{"title":140,"path":141,"stem":142,"icon":143},"File Storage","/docs/advanced/file-storage","docs/6.advanced/5.file-storage","i-lucide-upload",{"title":145,"path":146,"stem":147,"icon":148},"Logging","/docs/advanced/logging","docs/6.advanced/6.logging","i-lucide-scroll-text",{"title":150,"path":151,"stem":152,"icon":153},"Module Configuration","/docs/advanced/module-config","docs/6.advanced/7.module-config","i-lucide-settings",{"title":155,"path":156,"stem":157,"icon":54},"API Surface","/docs/advanced/api-surface","docs/6.advanced/8.api-surface",{"title":159,"path":160,"stem":161,"children":162,"page":39},"Recipes","/docs/recipes","docs/7.recipes",[163,168,173,178,182],{"title":164,"path":165,"stem":166,"icon":167},"Protected Dashboard","/docs/recipes/protected-dashboard","docs/7.recipes/1.protected-dashboard","i-lucide-layout-dashboard",{"title":169,"path":170,"stem":171,"icon":172},"Real-Time Feed","/docs/recipes/realtime-feed","docs/7.recipes/2.realtime-feed","i-lucide-messages-square",{"title":174,"path":175,"stem":176,"icon":177},"User Augmentation","/docs/recipes/user-augmentation","docs/7.recipes/3.user-augmentation","i-lucide-user-round-cog",{"title":179,"path":180,"stem":181,"icon":28},"Auth Guards and Permissions","/docs/recipes/auth-guards-and-permissions","docs/7.recipes/4.auth-guards-and-permissions",{"title":183,"path":184,"stem":185,"icon":73},"Instant List → Detail Navigation","/docs/recipes/instant-list-detail-cache-reuse","docs/7.recipes/5.instant-list-detail-cache-reuse",{"id":187,"title":179,"body":188,"description":694,"extension":695,"links":696,"meta":697,"navigation":698,"path":180,"seo":699,"sitemap":700,"stem":181,"__hash__":701},"docs/docs/7.recipes/4.auth-guards-and-permissions.md",{"type":189,"value":190,"toc":687},"minimark",[191,196,200,204,465,469,500,504,652,656,683],[192,193,195],"h2",{"id":194},"goal","Goal",[197,198,199],"p",{},"Compose authentication, authorization, and graceful session-expiry behavior with minimal app glue code.",[192,201,203],{"id":202},"configure-auth-guards-unauthorized-redirects","Configure Auth Guards + Unauthorized Redirects",[205,206,212],"pre",{"className":207,"code":208,"filename":209,"language":210,"meta":211,"style":211},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  modules: ['better-convex-nuxt'],\n  convex: {\n    url: process.env.CONVEX_URL,\n    auth: {\n      enabled: true,\n      routeProtection: {\n        redirectTo: '/auth/signin',\n        preserveReturnTo: true,\n      },\n      unauthorized: {\n        enabled: true,\n        redirectTo: '/auth/signin',\n        includeQueries: false, // start conservative\n      },\n    },\n    permissions: true,\n  },\n})\n","nuxt.config.ts","ts","",[213,214,215,239,267,278,302,312,326,336,354,366,372,382,394,409,427,432,438,450,456],"code",{"__ignoreMap":211},[216,217,220,224,227,231,235],"span",{"class":218,"line":219},"line",1,[216,221,223],{"class":222},"s7zQu","export",[216,225,226],{"class":222}," default",[216,228,230],{"class":229},"s2Zo4"," defineNuxtConfig",[216,232,234],{"class":233},"sTEyZ","(",[216,236,238],{"class":237},"sMK4o","{\n",[216,240,242,246,249,252,255,259,261,264],{"class":218,"line":241},2,[216,243,245],{"class":244},"swJcz","  modules",[216,247,248],{"class":237},":",[216,250,251],{"class":233}," [",[216,253,254],{"class":237},"'",[216,256,258],{"class":257},"sfazB","better-convex-nuxt",[216,260,254],{"class":237},[216,262,263],{"class":233},"]",[216,265,266],{"class":237},",\n",[216,268,270,273,275],{"class":218,"line":269},3,[216,271,272],{"class":244},"  convex",[216,274,248],{"class":237},[216,276,277],{"class":237}," {\n",[216,279,281,284,286,289,292,295,297,300],{"class":218,"line":280},4,[216,282,283],{"class":244},"    url",[216,285,248],{"class":237},[216,287,288],{"class":233}," process",[216,290,291],{"class":237},".",[216,293,294],{"class":233},"env",[216,296,291],{"class":237},[216,298,299],{"class":233},"CONVEX_URL",[216,301,266],{"class":237},[216,303,305,308,310],{"class":218,"line":304},5,[216,306,307],{"class":244},"    auth",[216,309,248],{"class":237},[216,311,277],{"class":237},[216,313,315,318,320,324],{"class":218,"line":314},6,[216,316,317],{"class":244},"      enabled",[216,319,248],{"class":237},[216,321,323],{"class":322},"sfNiH"," true",[216,325,266],{"class":237},[216,327,329,332,334],{"class":218,"line":328},7,[216,330,331],{"class":244},"      routeProtection",[216,333,248],{"class":237},[216,335,277],{"class":237},[216,337,339,342,344,347,350,352],{"class":218,"line":338},8,[216,340,341],{"class":244},"        redirectTo",[216,343,248],{"class":237},[216,345,346],{"class":237}," '",[216,348,349],{"class":257},"/auth/signin",[216,351,254],{"class":237},[216,353,266],{"class":237},[216,355,357,360,362,364],{"class":218,"line":356},9,[216,358,359],{"class":244},"        preserveReturnTo",[216,361,248],{"class":237},[216,363,323],{"class":322},[216,365,266],{"class":237},[216,367,369],{"class":218,"line":368},10,[216,370,371],{"class":237},"      },\n",[216,373,375,378,380],{"class":218,"line":374},11,[216,376,377],{"class":244},"      unauthorized",[216,379,248],{"class":237},[216,381,277],{"class":237},[216,383,385,388,390,392],{"class":218,"line":384},12,[216,386,387],{"class":244},"        enabled",[216,389,248],{"class":237},[216,391,323],{"class":322},[216,393,266],{"class":237},[216,395,397,399,401,403,405,407],{"class":218,"line":396},13,[216,398,341],{"class":244},[216,400,248],{"class":237},[216,402,346],{"class":237},[216,404,349],{"class":257},[216,406,254],{"class":237},[216,408,266],{"class":237},[216,410,412,415,417,420,423],{"class":218,"line":411},14,[216,413,414],{"class":244},"        includeQueries",[216,416,248],{"class":237},[216,418,419],{"class":322}," false",[216,421,422],{"class":237},",",[216,424,426],{"class":425},"sHwdD"," // start conservative\n",[216,428,430],{"class":218,"line":429},15,[216,431,371],{"class":237},[216,433,435],{"class":218,"line":434},16,[216,436,437],{"class":237},"    },\n",[216,439,441,444,446,448],{"class":218,"line":440},17,[216,442,443],{"class":244},"    permissions",[216,445,248],{"class":237},[216,447,323],{"class":322},[216,449,266],{"class":237},[216,451,453],{"class":218,"line":452},18,[216,454,455],{"class":237},"  },\n",[216,457,459,462],{"class":218,"line":458},19,[216,460,461],{"class":237},"}",[216,463,464],{"class":233},")\n",[192,466,468],{"id":467},"protect-the-page","Protect the Page",[205,470,472],{"className":207,"code":471,"language":210,"meta":211,"style":211},"definePageMeta({\n  convexAuth: true,\n})\n",[213,473,474,483,494],{"__ignoreMap":211},[216,475,476,479,481],{"class":218,"line":219},[216,477,478],{"class":229},"definePageMeta",[216,480,234],{"class":233},[216,482,238],{"class":237},[216,484,485,488,490,492],{"class":218,"line":241},[216,486,487],{"class":244},"  convexAuth",[216,489,248],{"class":237},[216,491,323],{"class":322},[216,493,266],{"class":237},[216,495,496,498],{"class":218,"line":269},[216,497,461],{"class":237},[216,499,464],{"class":233},[192,501,503],{"id":502},"gate-ui-by-permission","Gate UI by Permission",[205,505,509],{"className":506,"code":507,"language":508,"meta":211,"style":211},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\nconst { can, pending } = usePermissions()\nconst canEdit = can('post.update')\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cbutton v-if=\"!pending && canEdit\">Edit Post\u003C/button>\n\u003C/template>\n","vue",[213,510,511,539,566,588,597,603,612,644],{"__ignoreMap":211},[216,512,513,516,519,523,526,529,532,534,536],{"class":218,"line":219},[216,514,515],{"class":237},"\u003C",[216,517,518],{"class":244},"script",[216,520,522],{"class":521},"spNyl"," setup",[216,524,525],{"class":521}," lang",[216,527,528],{"class":237},"=",[216,530,531],{"class":237},"\"",[216,533,210],{"class":257},[216,535,531],{"class":237},[216,537,538],{"class":237},">\n",[216,540,541,544,547,550,552,555,557,560,563],{"class":218,"line":241},[216,542,543],{"class":521},"const",[216,545,546],{"class":237}," {",[216,548,549],{"class":233}," can",[216,551,422],{"class":237},[216,553,554],{"class":233}," pending ",[216,556,461],{"class":237},[216,558,559],{"class":237}," =",[216,561,562],{"class":229}," usePermissions",[216,564,565],{"class":233},"()\n",[216,567,568,570,573,575,577,579,581,584,586],{"class":218,"line":269},[216,569,543],{"class":521},[216,571,572],{"class":233}," canEdit ",[216,574,528],{"class":237},[216,576,549],{"class":229},[216,578,234],{"class":233},[216,580,254],{"class":237},[216,582,583],{"class":257},"post.update",[216,585,254],{"class":237},[216,587,464],{"class":233},[216,589,590,593,595],{"class":218,"line":280},[216,591,592],{"class":237},"\u003C/",[216,594,518],{"class":244},[216,596,538],{"class":237},[216,598,599],{"class":218,"line":304},[216,600,602],{"emptyLinePlaceholder":601},true,"\n",[216,604,605,607,610],{"class":218,"line":314},[216,606,515],{"class":237},[216,608,609],{"class":244},"template",[216,611,538],{"class":237},[216,613,614,617,620,623,625,627,630,632,635,638,640,642],{"class":218,"line":328},[216,615,616],{"class":237},"  \u003C",[216,618,619],{"class":244},"button",[216,621,622],{"class":521}," v-if",[216,624,528],{"class":237},[216,626,531],{"class":237},[216,628,629],{"class":257},"!pending && canEdit",[216,631,531],{"class":237},[216,633,634],{"class":237},">",[216,636,637],{"class":233},"Edit Post",[216,639,592],{"class":237},[216,641,619],{"class":244},[216,643,538],{"class":237},[216,645,646,648,650],{"class":218,"line":338},[216,647,592],{"class":237},[216,649,609],{"class":244},[216,651,538],{"class":237},[192,653,655],{"id":654},"what-happens-on-expired-session","What Happens on Expired Session?",[657,658,659,663,666,669,676],"ul",{},[660,661,662],"li",{},"Mutations/actions that fail with an unauthorized error can trigger a single deduped recovery flow.",[660,664,665],{},"Local auth state is cleared.",[660,667,668],{},"The user is redirected to your configured auth route.",[660,670,671,672,675],{},"Query/paginated query-triggered redirects are off by default (",[213,673,674],{},"includeQueries: false",") to avoid noisy background redirects.",[660,677,678,679,682],{},"Set ",[213,680,681],{},"includeQueries: true"," if you want the same deduped unauthorized recovery flow for queries.",[684,685,686],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"title":211,"searchDepth":219,"depth":241,"links":688},[689,690,691,692,693],{"id":194,"depth":241,"text":195},{"id":202,"depth":241,"text":203},{"id":467,"depth":241,"text":468},{"id":502,"depth":241,"text":503},{"id":654,"depth":241,"text":655},"Combine route protection, permissions, and expired-session redirects.","md",null,{},{"icon":28},{"title":179,"description":694},{"loc":180},"1zMUr8aR85KShVESZAW5C1YIgZKN-1HUr3nzcG_HPRI",[703,705],{"title":174,"path":175,"stem":176,"description":704,"icon":177,"children":-1},"Add custom claims typing to useConvexAuth().user with module augmentation.",{"title":183,"path":184,"stem":185,"description":706,"icon":73,"children":-1},"Reuse list query cache on a slug page for immediate title/description rendering.",1772891787497]