[{"data":1,"prerenderedAt":1913},["ShallowReactive",2],{"navigation_docs":3,"-guide-concepts-glossary":587,"-guide-concepts-glossary-surround":1908},[4,50,155,441,504],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":49},"Get Started","i-lucide-rocket","\u002Fget-started","1.get-started",[10,15,20,25,30,35,40,45],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fget-started\u002Fintroduction","1.get-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fget-started\u002Finstallation","1.get-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Project structure","\u002Fget-started\u002Fproject-structure","1.get-started\u002F3.project-structure","i-lucide-folder-tree",{"title":26,"path":27,"stem":28,"icon":29},"Configuration","\u002Fget-started\u002Fconfiguration","1.get-started\u002F4.configuration","i-lucide-settings",{"title":31,"path":32,"stem":33,"icon":34},"Authentication","\u002Fget-started\u002Fauthentication","1.get-started\u002F5.authentication","i-lucide-lock",{"title":36,"path":37,"stem":38,"icon":39},"Adding modules","\u002Fget-started\u002Fadding-modules","1.get-started\u002F6.adding-modules","i-lucide-puzzle",{"title":41,"path":42,"stem":43,"icon":44},"Database","\u002Fget-started\u002Fdatabase","1.get-started\u002F7.database","i-lucide-database",{"title":46,"path":47,"stem":48,"icon":6},"Deployment","\u002Fget-started\u002Fdeployment","1.get-started\u002F8.deployment",false,{"title":51,"icon":52,"path":53,"stem":54,"children":55,"page":49},"Guide","i-lucide-book-open","\u002Fguide","2.guide",[56,90,115,125],{"title":57,"icon":49,"path":58,"stem":59,"children":60,"page":49},"Concepts","\u002Fguide\u002Fconcepts","2.guide\u002F1.concepts",[61,66,71,76,80,85],{"title":62,"path":63,"stem":64,"icon":65},"Architecture","\u002Fguide\u002Fconcepts\u002Farchitecture","2.guide\u002F1.concepts\u002F1.architecture","i-lucide-blocks",{"title":67,"path":68,"stem":69,"icon":70},"Access control","\u002Fguide\u002Fconcepts\u002Fauth-and-scopes","2.guide\u002F1.concepts\u002F2.auth-and-scopes","i-lucide-shield-check",{"title":72,"path":73,"stem":74,"icon":75},"Extension points","\u002Fguide\u002Fconcepts\u002Fextension-points","2.guide\u002F1.concepts\u002F3.extension-points","i-lucide-plug",{"title":77,"path":78,"stem":79,"icon":44},"Database extensions","\u002Fguide\u002Fconcepts\u002Fdatabase-extensions","2.guide\u002F1.concepts\u002F4.database-extensions",{"title":81,"path":82,"stem":83,"icon":84},"Identity","\u002Fguide\u002Fconcepts\u002Fidentity","2.guide\u002F1.concepts\u002F5.identity","i-lucide-fingerprint",{"title":86,"path":87,"stem":88,"icon":89},"Glossary","\u002Fguide\u002Fconcepts\u002Fglossary","2.guide\u002F1.concepts\u002F6.glossary","i-lucide-book-a",{"title":91,"icon":49,"path":92,"stem":93,"children":94,"page":49},"UX patterns","\u002Fguide\u002Fux-patterns","2.guide\u002F2.ux-patterns",[95,100,105,110],{"title":96,"path":97,"stem":98,"icon":99},"Layouts and navigation","\u002Fguide\u002Fux-patterns\u002Flayouts-and-navigation","2.guide\u002F2.ux-patterns\u002F1.layouts-and-navigation","i-lucide-layout-template",{"title":101,"path":102,"stem":103,"icon":104},"Pages","\u002Fguide\u002Fux-patterns\u002Fpages","2.guide\u002F2.ux-patterns\u002F2.pages","i-lucide-table",{"title":106,"path":107,"stem":108,"icon":109},"Forms and actions","\u002Fguide\u002Fux-patterns\u002Fforms-and-actions","2.guide\u002F2.ux-patterns\u002F3.forms-and-actions","i-lucide-square-pen",{"title":111,"path":112,"stem":113,"icon":114},"Text and formatting","\u002Fguide\u002Fux-patterns\u002Ftext-and-formatting","2.guide\u002F2.ux-patterns\u002F4.text-and-formatting","i-lucide-type",{"title":116,"icon":49,"path":117,"stem":118,"children":119,"page":49},"Best practices","\u002Fguide\u002Fbest-practices","2.guide\u002F3.best-practices",[120],{"title":121,"path":122,"stem":123,"icon":124},"HTTP routes","\u002Fguide\u002Fbest-practices\u002Fhttp-routes","2.guide\u002F3.best-practices\u002F1.http-routes","i-lucide-route",{"title":126,"icon":49,"path":127,"stem":128,"children":129,"page":49},"Going further","\u002Fguide\u002Fgoing-further","2.guide\u002F4.going-further",[130,135,140,145,150],{"title":131,"path":132,"stem":133,"icon":134},"Use your own OAuth server","\u002Fguide\u002Fgoing-further\u002Fown-oauth-server","2.guide\u002F4.going-further\u002F1.own-oauth-server","i-lucide-key-round",{"title":136,"path":137,"stem":138,"icon":139},"Create an OAuth application","\u002Fguide\u002Fgoing-further\u002Foauth-application","2.guide\u002F4.going-further\u002F2.oauth-application","i-lucide-app-window",{"title":141,"path":142,"stem":143,"icon":144},"Signing keys","\u002Fguide\u002Fgoing-further\u002Fsigning-keys","2.guide\u002F4.going-further\u002F3.signing-keys","i-lucide-key-square",{"title":146,"path":147,"stem":148,"icon":149},"Stripe setup","\u002Fguide\u002Fgoing-further\u002Fstripe-setup","2.guide\u002F4.going-further\u002F4.stripe-setup","i-lucide-credit-card",{"title":151,"path":152,"stem":153,"icon":154},"Migrate to the permission model","\u002Fguide\u002Fgoing-further\u002Fmigrate-access-control","2.guide\u002F4.going-further\u002F5.migrate-access-control","i-lucide-arrow-right-left",{"title":156,"icon":157,"path":158,"stem":159,"children":160},"Modules","i-lucide-boxes","\u002Fmodules","3.modules",[161,163,244,273,320,375],{"title":156,"path":158,"stem":162},"3.modules\u002Findex",{"title":81,"icon":49,"path":164,"stem":165,"children":166,"page":49},"\u002Fmodules\u002Fidentity","3.modules\u002F1.identity",[167,190,194,198,220,224,240],{"title":168,"path":169,"stem":170,"children":171},"Auth","\u002Fmodules\u002Fidentity\u002Fauth","3.modules\u002F1.identity\u002F1.auth\u002Findex",[172,174,178,182,186],{"title":173,"path":169,"stem":170},"Overview",{"title":175,"path":176,"stem":177},"Server API","\u002Fmodules\u002Fidentity\u002Fauth\u002Fserver","3.modules\u002F1.identity\u002F1.auth\u002F2.server",{"title":179,"path":180,"stem":181},"Reference","\u002Fmodules\u002Fidentity\u002Fauth\u002Freference","3.modules\u002F1.identity\u002F1.auth\u002F3.reference",{"title":183,"path":184,"stem":185},"Client mode","\u002Fmodules\u002Fidentity\u002Fauth\u002Fclient-mode","3.modules\u002F1.identity\u002F1.auth\u002F4.client-mode",{"title":187,"path":188,"stem":189},"OAuth providers","\u002Fmodules\u002Fidentity\u002Fauth\u002Foauth-providers","3.modules\u002F1.identity\u002F1.auth\u002F5.oauth-providers",{"title":191,"path":192,"stem":193},"Users","\u002Fmodules\u002Fidentity\u002Fusers","3.modules\u002F1.identity\u002F2.users",{"title":195,"path":196,"stem":197},"Account","\u002Fmodules\u002Fidentity\u002Faccount","3.modules\u002F1.identity\u002F3.account",{"title":199,"path":200,"stem":201,"children":202},"Authorization","\u002Fmodules\u002Fidentity\u002Fauthorization","3.modules\u002F1.identity\u002F4.authorization\u002Findex",[203,204,208,212,216],{"title":173,"path":200,"stem":201},{"title":205,"path":206,"stem":207},"Roles and requirements","\u002Fmodules\u002Fidentity\u002Fauthorization\u002Froles-and-requirements","3.modules\u002F1.identity\u002F4.authorization\u002F2.roles-and-requirements",{"title":209,"path":210,"stem":211},"Policies","\u002Fmodules\u002Fidentity\u002Fauthorization\u002Fpolicies","3.modules\u002F1.identity\u002F4.authorization\u002F3.policies",{"title":213,"path":214,"stem":215},"Client","\u002Fmodules\u002Fidentity\u002Fauthorization\u002Fclient","3.modules\u002F1.identity\u002F4.authorization\u002F4.client",{"title":217,"path":218,"stem":219},"Admin","\u002Fmodules\u002Fidentity\u002Fauthorization\u002Fadmin","3.modules\u002F1.identity\u002F4.authorization\u002F5.admin",{"title":221,"path":222,"stem":223},"Preferences","\u002Fmodules\u002Fidentity\u002Fpreferences","3.modules\u002F1.identity\u002F5.preferences",{"title":225,"path":226,"stem":227,"children":228},"OAuth Server","\u002Fmodules\u002Fidentity\u002Foauth-server","3.modules\u002F1.identity\u002F6.oauth-server\u002Findex",[229,230,233,237],{"title":173,"path":226,"stem":227},{"title":175,"path":231,"stem":232},"\u002Fmodules\u002Fidentity\u002Foauth-server\u002Fserver","3.modules\u002F1.identity\u002F6.oauth-server\u002F2.server",{"title":234,"path":235,"stem":236},"Hooks","\u002Fmodules\u002Fidentity\u002Foauth-server\u002Fhooks","3.modules\u002F1.identity\u002F6.oauth-server\u002F3.hooks",{"title":179,"path":238,"stem":239},"\u002Fmodules\u002Fidentity\u002Foauth-server\u002Froutes-and-clients","3.modules\u002F1.identity\u002F6.oauth-server\u002F4.routes-and-clients",{"title":241,"path":242,"stem":243},"OAuth Resource","\u002Fmodules\u002Fidentity\u002Foauth-resource","3.modules\u002F1.identity\u002F8.oauth-resource",{"title":245,"icon":49,"path":246,"stem":247,"children":248,"page":49},"Commerce","\u002Fmodules\u002Fcommerce","3.modules\u002F2.commerce",[249,253,257],{"title":250,"path":251,"stem":252},"Stripe","\u002Fmodules\u002Fcommerce\u002Fstripe","3.modules\u002F2.commerce\u002F1.stripe",{"title":254,"path":255,"stem":256},"Payments","\u002Fmodules\u002Fcommerce\u002Fpayments","3.modules\u002F2.commerce\u002F2.payments",{"title":258,"path":259,"stem":260,"children":261},"Subscriptions","\u002Fmodules\u002Fcommerce\u002Fsubscriptions","3.modules\u002F2.commerce\u002F3.subscriptions\u002Findex",[262,263,266,270],{"title":173,"path":259,"stem":260},{"title":175,"path":264,"stem":265},"\u002Fmodules\u002Fcommerce\u002Fsubscriptions\u002Fserver","3.modules\u002F2.commerce\u002F3.subscriptions\u002F2.server",{"title":267,"path":268,"stem":269},"App","\u002Fmodules\u002Fcommerce\u002Fsubscriptions\u002Fapp","3.modules\u002F2.commerce\u002F3.subscriptions\u002F3.app",{"title":179,"path":271,"stem":272},"\u002Fmodules\u002Fcommerce\u002Fsubscriptions\u002Freference","3.modules\u002F2.commerce\u002F3.subscriptions\u002F4.reference",{"title":274,"icon":49,"path":275,"stem":276,"children":277,"page":49},"Features","\u002Fmodules\u002Ffeatures","3.modules\u002F3.features",[278,293,312,316],{"title":279,"path":280,"stem":281,"children":282},"Events","\u002Fmodules\u002Ffeatures\u002Fevents","3.modules\u002F3.features\u002F1.events\u002Findex",[283,284,287,290],{"title":173,"path":280,"stem":281},{"title":175,"path":285,"stem":286},"\u002Fmodules\u002Ffeatures\u002Fevents\u002Fserver","3.modules\u002F3.features\u002F1.events\u002F2.server",{"title":267,"path":288,"stem":289},"\u002Fmodules\u002Ffeatures\u002Fevents\u002Fapp","3.modules\u002F3.features\u002F1.events\u002F3.app",{"title":179,"path":291,"stem":292},"\u002Fmodules\u002Ffeatures\u002Fevents\u002Freference","3.modules\u002F3.features\u002F1.events\u002F4.reference",{"title":294,"path":295,"stem":296,"children":297},"Forms","\u002Fmodules\u002Ffeatures\u002Fforms","3.modules\u002F3.features\u002F2.forms\u002Findex",[298,299,303,306,309],{"title":173,"path":295,"stem":296},{"title":300,"path":301,"stem":302},"Definition","\u002Fmodules\u002Ffeatures\u002Fforms\u002Fdefinition","3.modules\u002F3.features\u002F2.forms\u002F2.definition",{"title":175,"path":304,"stem":305},"\u002Fmodules\u002Ffeatures\u002Fforms\u002Fserver","3.modules\u002F3.features\u002F2.forms\u002F3.server",{"title":267,"path":307,"stem":308},"\u002Fmodules\u002Ffeatures\u002Fforms\u002Fapp","3.modules\u002F3.features\u002F2.forms\u002F4.app",{"title":179,"path":310,"stem":311},"\u002Fmodules\u002Ffeatures\u002Fforms\u002Freference","3.modules\u002F3.features\u002F2.forms\u002F5.reference",{"title":313,"path":314,"stem":315},"Cookie Consent","\u002Fmodules\u002Ffeatures\u002Fcookie-consent","3.modules\u002F3.features\u002F3.cookie-consent",{"title":317,"path":318,"stem":319},"MCP","\u002Fmodules\u002Ffeatures\u002Fmcp","3.modules\u002F3.features\u002F4.mcp",{"title":321,"icon":49,"path":322,"stem":323,"children":324,"page":49},"Interface","\u002Fmodules\u002Finterface","3.modules\u002F4.interface",[325,350,353,357,361],{"title":326,"path":327,"stem":328,"children":329},"UI","\u002Fmodules\u002Finterface\u002Fui","3.modules\u002F4.interface\u002F1.ui\u002Findex",[330,331,335,339,343,347],{"title":173,"path":327,"stem":328},{"title":332,"path":333,"stem":334},"Page components","\u002Fmodules\u002Finterface\u002Fui\u002Fpage-components","3.modules\u002F4.interface\u002F1.ui\u002F2.page-components",{"title":336,"path":337,"stem":338},"App shell","\u002Fmodules\u002Finterface\u002Fui\u002Fapp-shell","3.modules\u002F4.interface\u002F1.ui\u002F3.app-shell",{"title":340,"path":341,"stem":342},"Form inputs","\u002Fmodules\u002Finterface\u002Fui\u002Fform-inputs","3.modules\u002F4.interface\u002F1.ui\u002F4.form-inputs",{"title":344,"path":345,"stem":346},"Composables and helpers","\u002Fmodules\u002Finterface\u002Fui\u002Fcomposables","3.modules\u002F4.interface\u002F1.ui\u002F5.composables",{"title":179,"path":348,"stem":349},"\u002Fmodules\u002Finterface\u002Fui\u002Freference","3.modules\u002F4.interface\u002F1.ui\u002F6.reference",{"title":217,"path":351,"stem":352},"\u002Fmodules\u002Finterface\u002Fadmin","3.modules\u002F4.interface\u002F2.admin",{"title":354,"path":355,"stem":356},"Menu","\u002Fmodules\u002Finterface\u002Fmenu","3.modules\u002F4.interface\u002F3.menu",{"title":358,"path":359,"stem":360},"Widget","\u002Fmodules\u002Finterface\u002Fwidget","3.modules\u002F4.interface\u002F4.widget",{"title":362,"path":363,"stem":364,"children":365},"Mobile","\u002Fmodules\u002Finterface\u002Fmobile","3.modules\u002F4.interface\u002F5.mobile\u002Findex",[366,367,371],{"title":173,"path":363,"stem":364},{"title":368,"path":369,"stem":370},"CLI and devices","\u002Fmodules\u002Finterface\u002Fmobile\u002Fcli-and-devices","3.modules\u002F4.interface\u002F5.mobile\u002F2.cli-and-devices",{"title":372,"path":373,"stem":374},"Splash screen","\u002Fmodules\u002Finterface\u002Fmobile\u002Fsplash-screen","3.modules\u002F4.interface\u002F5.mobile\u002F3.splash-screen",{"title":376,"icon":49,"path":377,"stem":378,"children":379,"page":49},"Platform","\u002Fmodules\u002Fplatform","3.modules\u002F5.platform",[380,402,406,423],{"title":381,"path":382,"stem":383,"children":384},"Module Kit","\u002Fmodules\u002Fplatform\u002Fmodule-kit","3.modules\u002F5.platform\u002F1.module-kit\u002Findex",[385,386,390,394,398],{"title":173,"path":382,"stem":383},{"title":387,"path":388,"stem":389},"Server toolkit","\u002Fmodules\u002Fplatform\u002Fmodule-kit\u002Fserver-toolkit","3.modules\u002F5.platform\u002F1.module-kit\u002F2.server-toolkit",{"title":391,"path":392,"stem":393},"Registries and menus","\u002Fmodules\u002Fplatform\u002Fmodule-kit\u002Fregistries-and-menus","3.modules\u002F5.platform\u002F1.module-kit\u002F3.registries-and-menus",{"title":395,"path":396,"stem":397},"Translations","\u002Fmodules\u002Fplatform\u002Fmodule-kit\u002Fi18n","3.modules\u002F5.platform\u002F1.module-kit\u002F4.i18n",{"title":399,"path":400,"stem":401},"Database helpers","\u002Fmodules\u002Fplatform\u002Fmodule-kit\u002Fdatabase","3.modules\u002F5.platform\u002F1.module-kit\u002F5.database",{"title":403,"path":404,"stem":405},"Notify","\u002Fmodules\u002Fplatform\u002Fnotify","3.modules\u002F5.platform\u002F2.notify",{"title":407,"path":408,"stem":409,"children":410},"Email Templates","\u002Fmodules\u002Fplatform\u002Femail-templates","3.modules\u002F5.platform\u002F3.email-templates\u002Findex",[411,412,416,419],{"title":173,"path":408,"stem":409},{"title":413,"path":414,"stem":415},"Email components","\u002Fmodules\u002Fplatform\u002Femail-templates\u002Fcomponents","3.modules\u002F5.platform\u002F3.email-templates\u002F2.components",{"title":175,"path":417,"stem":418},"\u002Fmodules\u002Fplatform\u002Femail-templates\u002Fserver","3.modules\u002F5.platform\u002F3.email-templates\u002F3.server",{"title":420,"path":421,"stem":422},"Module emails","\u002Fmodules\u002Fplatform\u002Femail-templates\u002Fmodule-emails","3.modules\u002F5.platform\u002F3.email-templates\u002F4.module-emails",{"title":424,"path":425,"stem":426,"children":427},"Base Layer","\u002Fmodules\u002Fplatform\u002Fbase-layer","3.modules\u002F5.platform\u002F4.base-layer\u002Findex",[428,429,433,437],{"title":173,"path":425,"stem":426},{"title":430,"path":431,"stem":432},"Content collections","\u002Fmodules\u002Fplatform\u002Fbase-layer\u002Fcontent-collections","3.modules\u002F5.platform\u002F4.base-layer\u002F2.content-collections",{"title":434,"path":435,"stem":436},"Layouts and routing","\u002Fmodules\u002Fplatform\u002Fbase-layer\u002Flayouts-and-routing","3.modules\u002F5.platform\u002F4.base-layer\u002F3.layouts-and-routing",{"title":438,"path":439,"stem":440},"Composables and utils","\u002Fmodules\u002Fplatform\u002Fbase-layer\u002Fcomposables-and-utils","3.modules\u002F5.platform\u002F4.base-layer\u002F4.composables-and-utils",{"title":442,"icon":443,"path":444,"stem":445,"children":446,"page":49},"Examples","i-lucide-code-xml","\u002Fexamples","4.examples",[447,466,476],{"title":448,"icon":49,"path":449,"stem":450,"children":451,"page":49},"Starters","\u002Fexamples\u002Fstarters","4.examples\u002F1.starters",[452,456,461],{"title":453,"path":454,"stem":455,"icon":6},"Workspace starter","\u002Fexamples\u002Fstarters\u002Fworkspace","4.examples\u002F1.starters\u002F1.workspace",{"title":457,"path":458,"stem":459,"icon":460},"Mobile starter","\u002Fexamples\u002Fstarters\u002Fmobile","4.examples\u002F1.starters\u002F2.mobile","i-lucide-smartphone",{"title":462,"path":463,"stem":464,"icon":465},"Standalone mobile starter","\u002Fexamples\u002Fstarters\u002Fmobile-standalone","4.examples\u002F1.starters\u002F3.mobile-standalone","i-lucide-tablet-smartphone",{"title":467,"icon":49,"path":468,"stem":469,"children":470,"page":49},"Apps","\u002Fexamples\u002Fapps","4.examples\u002F2.apps",[471],{"title":472,"path":473,"stem":474,"icon":475},"Frigear website app","\u002Fexamples\u002Fapps\u002Ffrigear-nu-website","4.examples\u002F2.apps\u002F1.frigear-nu-website","i-lucide-layout-dashboard",{"title":477,"icon":49,"path":478,"stem":479,"children":480,"page":49},"Tasks","\u002Fexamples\u002Ftasks","4.examples\u002F3.tasks",[481,485,489,494,499],{"title":482,"path":483,"stem":484,"icon":70},"Protect a route","\u002Fexamples\u002Ftasks\u002Fprotect-a-route","4.examples\u002F3.tasks\u002F1.protect-a-route",{"title":486,"path":487,"stem":488,"icon":475},"Add an admin page","\u002Fexamples\u002Ftasks\u002Fadd-an-admin-page","4.examples\u002F3.tasks\u002F2.add-an-admin-page",{"title":490,"path":491,"stem":492,"icon":493},"Sell event tickets","\u002Fexamples\u002Ftasks\u002Fsell-event-tickets","4.examples\u002F3.tasks\u002F3.sell-event-tickets","i-lucide-ticket",{"title":495,"path":496,"stem":497,"icon":498},"Build a form","\u002Fexamples\u002Ftasks\u002Fbuild-a-form","4.examples\u002F3.tasks\u002F4.build-a-form","i-lucide-clipboard-list",{"title":500,"path":501,"stem":502,"icon":503},"Send an email","\u002Fexamples\u002Ftasks\u002Fsend-an-email","4.examples\u002F3.tasks\u002F5.send-an-email","i-lucide-mail",{"title":505,"icon":506,"path":507,"stem":508,"children":509,"page":49},"Contribute","i-lucide-git-pull-request","\u002Fcontribute","5.contribute",[510,513,518,544,549,552,556,571],{"title":173,"path":511,"stem":512,"icon":506},"\u002Fcontribute\u002Foverview","5.contribute\u002F1.overview",{"title":514,"path":515,"stem":516,"icon":517},"Local development","\u002Fcontribute\u002Flocal-development","5.contribute\u002F2.local-development","i-lucide-terminal",{"title":519,"icon":49,"path":520,"stem":521,"children":522,"page":49},"Writing a module","\u002Fcontribute\u002Fwriting-a-module","5.contribute\u002F3.writing-a-module",[523,527,532,536,541],{"title":524,"path":525,"stem":526,"icon":39},"Scaffold a module","\u002Fcontribute\u002Fwriting-a-module\u002Fscaffold","5.contribute\u002F3.writing-a-module\u002F1.scaffold",{"title":528,"path":529,"stem":530,"icon":531},"Setup checklist","\u002Fcontribute\u002Fwriting-a-module\u002Fsetup-checklist","5.contribute\u002F3.writing-a-module\u002F2.setup-checklist","i-lucide-list-checks",{"title":533,"path":534,"stem":535,"icon":44},"Database tables","\u002Fcontribute\u002Fwriting-a-module\u002Fdatabase-tables","5.contribute\u002F3.writing-a-module\u002F3.database-tables",{"title":537,"path":538,"stem":539,"icon":540},"Testing","\u002Fcontribute\u002Fwriting-a-module\u002Ftesting","5.contribute\u002F3.writing-a-module\u002F4.testing","i-lucide-flask-conical",{"title":67,"path":542,"stem":543,"icon":70},"\u002Fcontribute\u002Fwriting-a-module\u002Faccess-control","5.contribute\u002F3.writing-a-module\u002F5.access-control",{"title":545,"path":546,"stem":547,"icon":548},"Publishing","\u002Fcontribute\u002Fpublishing","5.contribute\u002F4.publishing","i-lucide-package-check",{"title":448,"path":550,"stem":551,"icon":6},"\u002Fcontribute\u002Fstarters","5.contribute\u002F5.starters",{"title":553,"path":554,"stem":555,"icon":52},"Documentation","\u002Fcontribute\u002Fdocumentation","5.contribute\u002F6.documentation",{"title":557,"icon":49,"path":558,"stem":559,"children":560,"page":49},"Tooling","\u002Fcontribute\u002Ftooling","5.contribute\u002F7.tooling",[561,566],{"title":562,"path":563,"stem":564,"icon":565},"CLI","\u002Fcontribute\u002Ftooling\u002Fcli","5.contribute\u002F7.tooling\u002F1.cli","i-lucide-square-terminal",{"title":567,"path":568,"stem":569,"icon":570},"ESLint config","\u002Fcontribute\u002Ftooling\u002Feslint-config","5.contribute\u002F7.tooling\u002F2.eslint-config","i-lucide-spell-check",{"title":572,"icon":49,"path":573,"stem":574,"children":575},"Decisions","\u002Fcontribute\u002Fdecisions","5.contribute\u002F8.decisions\u002Findex",[576,578,583],{"title":572,"path":573,"stem":574,"icon":577},"i-lucide-scale",{"title":579,"path":580,"stem":581,"icon":582},"Session lifetimes per OAuth client","\u002Fcontribute\u002Fdecisions\u002Foauth-token-lifetimes","5.contribute\u002F8.decisions\u002F1.oauth-token-lifetimes","i-lucide-timer",{"title":584,"path":585,"stem":586,"icon":70},"One permission model","\u002Fcontribute\u002Fdecisions\u002Fpermission-model","5.contribute\u002F8.decisions\u002F2.permission-model",{"id":588,"title":86,"body":589,"description":1901,"extension":1902,"links":1903,"meta":1904,"navigation":1905,"path":87,"seo":1906,"stem":88,"__hash__":1907},"docs\u002F2.guide\u002F1.concepts\u002F6.glossary.md",{"type":590,"value":591,"toc":1888},"minimark",[592,596,599,604,882,886,1213,1220,1224,1445,1456,1460,1546,1549,1633,1636,1723,1727,1854,1858,1865,1869],[593,594,595],"p",{},"These docs use one word for each concept. This page lists those words, and every other page links here the first time\nit uses one.",[593,597,598],{},"Each row gives the term, its meaning and the page that explains it in full. The last column lists the words the docs\nused before. Avoid them in new text. A dash means there is no old word to avoid.",[600,601,603],"h2",{"id":602},"apps-and-modules","Apps and modules",[605,606,607,626],"table",{},[608,609,610],"thead",{},[611,612,613,617,620,623],"tr",{},[614,615,616],"th",{},"Term",[614,618,619],{},"Meaning",[614,621,622],{},"Where it is explained",[614,624,625],{},"Instead of",[627,628,629,649,666,688,705,726,747,766,787,803,820,840,861],"tbody",{},[611,630,631,638,641,646],{},[632,633,634],"td",{},[635,636,637],"strong",{},"host app",[632,639,640],{},"The Nuxt app that installs Frigear modules and configures them. Pages for app developers may say \"your app\".",[632,642,643],{},[644,645,62],"a",{"href":63},[632,647,648],{},"host application, consuming app, consuming application",[611,650,651,656,659,663],{},[632,652,653],{},[635,654,655],{},"hosting platform",[632,657,658],{},"Where you deploy the host app, such as Cloudflare, Vercel or a Node server.",[632,660,661],{},[644,662,46],{"href":47},[632,664,665],{},"the host's environment",[611,667,668,673,681,685],{},[632,669,670],{},[635,671,672],{},"module",[632,674,675,676,680],{},"A Nuxt module published as ",[677,678,679],"code",{},"@frigear-nu\u002F\u003Cname>"," that adds one feature to a host app.",[632,682,683],{},[644,684,156],{"href":158},[632,686,687],{},"building block",[611,689,690,695,698,702],{},[632,691,692],{},[635,693,694],{},"package",[632,696,697],{},"Any npm package in the repository, named in install and publish steps and for tooling that is not a module.",[632,699,700],{},[644,701,62],{"href":63},[632,703,704],{},"—",[611,706,707,712,719,724],{},[632,708,709],{},[635,710,711],{},"base layer",[632,713,714,715,718],{},"The shared Nuxt layer a host app extends for config, interface defaults and content pages. Its package is ",[677,716,717],{},"@frigear-nu\u002Fbase",".",[632,720,721],{},[644,722,723],{"href":425},"Base layer",[632,725,704],{},[611,727,728,733,740,745],{},[632,729,730],{},[635,731,732],{},"options",[632,734,735,736,739],{},"Module options sit under the module's config key in ",[677,737,738],{},"nuxt.config.ts",". Option tables show the full path from that key.",[632,741,742],{},[644,743,553],{"href":744},"\u002Fcontribute\u002Fdocumentation#writing",[632,746,704],{},[611,748,749,754,760,764],{},[632,750,751],{},[635,752,753],{},"Frigear repository",[632,755,756,757,718],{},"This monorepo, ",[677,758,759],{},"Frigear-nu\u002Ffrigear-nu",[632,761,762],{},[644,763,173],{"href":511},[632,765,704],{},[611,767,768,773,780,784],{},[632,769,770],{},[635,771,772],{},"starter",[632,774,775,776,779],{},"A ready-made project in ",[677,777,778],{},".starters\u002F"," that you copy to start a new host app, such as the workspace starter.",[632,781,782],{},[644,783,16],{"href":17},[632,785,786],{},"boilerplate",[611,788,789,794,797,801],{},[632,790,791],{},[635,792,793],{},"your workspace",[632,795,796],{},"The pnpm workspace a starter creates for you.",[632,798,799],{},[644,800,21],{"href":22},[632,802,704],{},[611,804,805,810,813,817],{},[632,806,807],{},[635,808,809],{},"frigear.nu",[632,811,812],{},"The live Frigear service, which is also the default issuer.",[632,814,815],{},[644,816,472],{"href":473},[632,818,819],{},"Frigear SSO",[611,821,822,826,833,837],{},[632,823,824],{},[635,825,472],{},[632,827,828,829,832],{},"The reference host app in ",[677,830,831],{},"apps\u002Fwebsite"," that runs frigear.nu.",[632,834,835],{},[644,836,472],{"href":473},[632,838,839],{},"frigear.nu website",[611,841,842,847,854,858],{},[632,843,844],{},[635,845,846],{},"test fixture",[632,848,849,850,853],{},"A minimal Nuxt app under ",[677,851,852],{},"test\u002Ffixtures\u002F"," that installs a module from source so tests can boot it.",[632,855,856],{},[644,857,537],{"href":538},[632,859,860],{},"fixture app, test app",[611,862,863,868,875,880],{},[632,864,865],{},[635,866,867],{},"playground",[632,869,870,871,874],{},"A dev app under ",[677,872,873],{},"packages\u002F\u003Cname>\u002Fplayground"," for working on one package. It is not a test fixture.",[632,876,877],{},[644,878,879],{"href":525},"Scaffold",[632,881,704],{},[600,883,885],{"id":884},"people-and-permissions","People and permissions",[605,887,888,900],{},[608,889,890],{},[611,891,892,894,896,898],{},[614,893,616],{},[614,895,619],{},[614,897,622],{},[614,899,625],{},[627,901,902,928,964,989,1020,1042,1059,1080,1107,1129,1159,1180,1197],{},[611,903,904,909,920,925],{},[632,905,906],{},[635,907,908],{},"permission",[632,910,911,912,915,916,919],{},"A ",[677,913,914],{},"resource:action"," string such as ",[677,917,918],{},"events:manage",", registered by a module or the host app. The only thing code checks.",[632,921,922],{},[644,923,67],{"href":924},"\u002Fguide\u002Fconcepts\u002Fauth-and-scopes#terms",[632,926,927],{},"ability, privilege, right",[611,929,930,935,956,961],{},[632,931,932],{},[635,933,934],{},"role",[632,936,937,938,941,942,945,946,945,949,945,952,955],{},"A named bundle of permissions in ",[677,939,940],{},"authorization.roles"," (",[677,943,944],{},"grant",", ",[677,947,948],{},"inherit",[677,950,951],{},"requirements",[677,953,954],{},"auto","). A user holds several.",[632,957,958],{},[644,959,67],{"href":960},"\u002Fguide\u002Fconcepts\u002Fauth-and-scopes#roles",[632,962,963],{},"role column, user role",[611,965,966,971,981,986],{},[632,967,968],{},[635,969,970],{},"policy",[632,972,973,974,945,977,980],{},"Code that refines one permission against a record (",[677,975,976],{},"definePolicy",[677,978,979],{},"defineSharedPolicy","). It can deny, never grant.",[632,982,983],{},[644,984,67],{"href":985},"\u002Fguide\u002Fconcepts\u002Fauth-and-scopes#policies",[632,987,988],{},"ability, policy gate, policy hook",[611,990,991,996,1009,1014],{},[632,992,993],{},[635,994,995],{},"before hook",[632,997,998,1001,1002,1005,1006,718],{},[677,999,1000],{},"authorization:before",": the single hook the host app answers to allow or deny any check. Listeners call ",[677,1003,1004],{},"allow()"," or ",[677,1007,1008],{},"deny()",[632,1010,1011],{},[644,1012,67],{"href":1013},"\u002Fguide\u002Fconcepts\u002Fauth-and-scopes#the-before-hook",[632,1015,1016,1017],{},"policy hook, ",[677,1018,1019],{},"\u003Cmodule>:authorize",[611,1021,1022,1027,1034,1039],{},[632,1023,1024],{},[635,1025,1026],{},"sensitive permission",[632,1028,1029,1030,1033],{},"A permission that a wildcard never covers, such as ",[677,1031,1032],{},"forms:pii",". It is granted by name.",[632,1035,1036],{},[644,1037,67],{"href":1038},"\u002Fguide\u002Fconcepts\u002Fauth-and-scopes#permissions-and-sensitive-ones",[632,1040,1041],{},"PII scope",[611,1043,1044,1049,1052,1057],{},[632,1045,1046],{},[635,1047,1048],{},"sessionOnly",[632,1050,1051],{},"A permission setting: only a cookie session may use it, never a token.",[632,1053,1054],{},[644,1055,67],{"href":1056},"\u002Fguide\u002Fconcepts\u002Fauth-and-scopes#sessiononly",[632,1058,704],{},[611,1060,1061,1066,1073,1077],{},[632,1062,1063],{},[635,1064,1065],{},"staff",[632,1067,1068,1069,1072],{},"People your host app lets into management screens and APIs. They are the people whose roles hold the module's permissions, such as ",[677,1070,1071],{},"events:update","; there is no separate staff check.",[632,1074,1075],{},[644,1076,67],{"href":68},[632,1078,1079],{},"back office users, privileged users",[611,1081,1082,1087,1100,1104],{},[632,1083,1084],{},[635,1085,1086],{},"admin area",[632,1088,1089,1090,1093,1094,1096,1097,718],{},"The screens under ",[677,1091,1092],{},"\u002Fadmin",", drawn by the ",[644,1095,217],{"href":351}," module and gated by ",[677,1098,1099],{},"admin:access",[632,1101,1102],{},[644,1103,217],{"href":351},[632,1105,1106],{},"back office, back-office, admin UI, user admin",[611,1108,1109,1117,1123,1127],{},[632,1110,1111,1114,1115],{},[677,1112,1113],{},"admin"," ",[635,1116,934],{},[632,1118,1119,1120,1122],{},"A role name in ",[677,1121,940],{},". It is a name, not a synonym for staff.",[632,1124,1125],{},[644,1126,199],{"href":200},[632,1128,704],{},[611,1130,1131,1136,1151,1156],{},[632,1132,1133],{},[635,1134,1135],{},"route rule",[632,1137,911,1138,1141,1142,945,1144,1005,1147,1150],{},[677,1139,1140],{},"routeRules"," entry with ",[677,1143,908],{},[677,1145,1146],{},"authenticated",[677,1148,1149],{},"guest",". Auth enforces it on the server. In client mode it only shapes the interface.",[632,1152,1153],{},[644,1154,67],{"href":1155},"\u002Fguide\u002Fconcepts\u002Fauth-and-scopes#where-the-browser-gets-its-answer",[632,1157,1158],{},"page guard, role guard",[611,1160,1161,1166,1172,1177],{},[632,1162,1163],{},[635,1164,1165],{},"principal",[632,1167,1168,1169,718],{},"Who made a request: the signed-in user, how they proved it and the permissions that proof carries. In code it is ",[677,1170,1171],{},"AuthPrincipal",[632,1173,1174],{},[644,1175,67],{"href":1176},"\u002Fguide\u002Fconcepts\u002Fauth-and-scopes#the-principal",[632,1178,1179],{},"authenticated user",[611,1181,1182,1187,1190,1194],{},[632,1183,1184],{},[635,1185,1186],{},"signed-in user",[632,1188,1189],{},"The person behind a principal, when only the person matters.",[632,1191,1192],{},[644,1193,67],{"href":68},[632,1195,1196],{},"logged-in user",[611,1198,1199,1204,1207,1211],{},[632,1200,1201],{},[635,1202,1203],{},"visitor",[632,1205,1206],{},"Someone with no valid credential.",[632,1208,1209],{},[644,1210,67],{"href":68},[632,1212,1149],{},[593,1214,1215,1216,1219],{},"The old words ability, staff guard, policy gate and ceiling are gone from the API. The\n",[644,1217,1218],{"href":152},"migration guide"," maps each to its replacement.",[600,1221,1223],{"id":1222},"signing-in","Signing in",[605,1225,1226,1238],{},[608,1227,1228],{},[611,1229,1230,1232,1234,1236],{},[614,1231,616],{},[614,1233,619],{},[614,1235,622],{},[614,1237,625],{},[627,1239,1240,1261,1282,1299,1316,1332,1350,1365,1381,1402,1423],{},[611,1241,1242,1251,1254,1258],{},[632,1243,1244,1247,1248],{},[635,1245,1246],{},"sign in"," \u002F ",[635,1249,1250],{},"sign-in",[632,1252,1253],{},"\"Sign in\" is the verb and \"sign-in\" the noun or adjective. Sign up and sign out follow the same pattern.",[632,1255,1256],{},[644,1257,31],{"href":32},[632,1259,1260],{},"log in, log out, Log in with frigear.nu",[611,1262,1263,1268,1274,1279],{},[632,1264,1265],{},[635,1266,1267],{},"Sign in with frigear.nu",[632,1269,1270,1271,718],{},"Auth's built-in sign-in against frigear.nu for previews and local development. Its option is ",[677,1272,1273],{},"oauth.frigear",[632,1275,1276],{},[644,1277,187],{"href":1278},"\u002Fmodules\u002Fidentity\u002Fauth\u002Foauth-providers#sign-in-with-frigearnu",[632,1280,1281],{},"Log in with frigear.nu, frigear SSO",[611,1283,1284,1289,1292,1296],{},[632,1285,1286],{},[635,1287,1288],{},"server mode",[632,1290,1291],{},"Auth signs users in on the host app's own server and keeps them in a cookie session. This is the default.",[632,1293,1294],{},[644,1295,168],{"href":169},[632,1297,1298],{},"server-rendered mode, confidential mode",[611,1300,1301,1306,1309,1313],{},[632,1302,1303],{},[635,1304,1305],{},"client mode",[632,1307,1308],{},"Auth for an app without its own server, such as a single-page application (SPA) or a Capacitor app. It signs in at an issuer and keeps the tokens.",[632,1310,1311],{},[644,1312,183],{"href":184},[632,1314,1315],{},"SPA mode, public client mode",[611,1317,1318,1323,1326,1330],{},[632,1319,1320],{},[635,1321,1322],{},"session",[632,1324,1325],{},"A sealed cookie that keeps a person signed in to one host app in server mode. It may do whatever the user's roles allow.",[632,1327,1328],{},[644,1329,67],{"href":1176},[632,1331,704],{},[611,1333,1334,1339,1342,1347],{},[632,1335,1336],{},[635,1337,1338],{},"issuer",[632,1340,1341],{},"The server where users sign in and which issues tokens to other apps. Frigear's issuer is the OAuth Server module.",[632,1343,1344],{},[644,1345,81],{"href":1346},"\u002Fguide\u002Fconcepts\u002Fidentity#the-roles",[632,1348,1349],{},"identity provider, Frigear OAuth server",[611,1351,1352,1356,1359,1363],{},[632,1353,1354],{},[635,1355,225],{},[632,1357,1358],{},"The module that turns a host app into an issuer, always capitalised and linked.",[632,1360,1361],{},[644,1362,225],{"href":226},[632,1364,704],{},[611,1366,1367,1372,1375,1379],{},[632,1368,1369],{},[635,1370,1371],{},"OAuth provider",[632,1373,1374],{},"A third-party sign-in service that Auth supports through nuxt-auth-utils, such as GitHub, Google or a generic OpenID Connect server.",[632,1376,1377],{},[644,1378,187],{"href":188},[632,1380,704],{},[611,1382,1383,1388,1394,1399],{},[632,1384,1385],{},[635,1386,1387],{},"OAuth application",[632,1389,1390,1391,718],{},"An app registered at an issuer so its users can sign in through it. It is stored in ",[677,1392,1393],{},"oauth_applications",[632,1395,1396],{},[644,1397,1398],{"href":238},"Routes and clients",[632,1400,1401],{},"OAuth client",[611,1403,1404,1412,1415,1420],{},[632,1405,1406,1247,1409],{},[635,1407,1408],{},"public",[635,1410,1411],{},"confidential",[632,1413,1414],{},"The two OAuth application types, fixed at creation. A confidential one is a server that keeps a client secret, and a public one has no secret.",[632,1416,1417],{},[644,1418,81],{"href":1419},"\u002Fguide\u002Fconcepts\u002Fidentity#public-and-confidential-applications",[632,1421,1422],{},"public client, confidential client",[611,1424,1425,1430,1437,1442],{},[632,1426,1427],{},[635,1428,1429],{},"configured client",[632,1431,1432,1433,1436],{},"A public OAuth application defined in the ",[677,1434,1435],{},"clients"," option of OAuth Server instead of in the admin area.",[632,1438,1439],{},[644,1440,1398],{"href":1441},"\u002Fmodules\u002Fidentity\u002Foauth-server\u002Froutes-and-clients#configured-clients",[632,1443,1444],{},"config client, static client",[593,1446,1447,1448,1451,1452,1455],{},"The routes ",[677,1449,1450],{},"\u002Flogin"," and ",[677,1453,1454],{},"\u002Fregister"," keep their names as code. Quote \"Create account\" only when you quote the\ninterface.",[600,1457,1459],{"id":1458},"tokens-and-scopes","Tokens and scopes",[605,1461,1462,1474],{},[608,1463,1464],{},[611,1465,1466,1468,1470,1472],{},[614,1467,616],{},[614,1469,619],{},[614,1471,622],{},[614,1473,625],{},[627,1475,1476,1499,1520],{},[611,1477,1478,1483,1490,1496],{},[632,1479,1480],{},[635,1481,1482],{},"API token",[632,1484,1485,1486,1489],{},"A long-lived token a user creates on their account page for scripts and agents. It starts with ",[677,1487,1488],{},"fnu_"," by default.",[632,1491,1492],{},[644,1493,1495],{"href":1494},"\u002Fmodules\u002Fidentity\u002Fauth\u002Fserver#user-api-tokens","Auth server API",[632,1497,1498],{},"user API token, personal token",[611,1500,1501,1506,1513,1517],{},[632,1502,1503],{},[635,1504,1505],{},"access token",[632,1507,1508,1509,1512],{},"A short-lived signed JSON Web Token (JWT) that an issuer gives an OAuth application for a signed-in user. Not a form access token (",[677,1510,1511],{},"ffk_","), which Forms owns.",[632,1514,1515],{},[644,1516,67],{"href":1176},[632,1518,1519],{},"OAuth token, bearer JWT",[611,1521,1522,1527,1538,1543],{},[632,1523,1524],{},[635,1525,1526],{},"scope",[632,1528,1529,1530,1533,1534,1537],{},"What an API token or an access token may do: a permission, a wildcard, or a named scope that expands to permissions (",[677,1531,1532],{},"tickets",") or to none (",[677,1535,1536],{},"openid",").",[632,1539,1540],{},[644,1541,67],{"href":1542},"\u002Fguide\u002Fconcepts\u002Fauth-and-scopes#scopes",[632,1544,1545],{},"permission (for a token's limit)",[600,1547,72],{"id":1548},"extension-points",[605,1550,1551,1563],{},[608,1552,1553],{},[611,1554,1555,1557,1559,1561],{},[614,1556,616],{},[614,1558,619],{},[614,1560,622],{},[614,1562,625],{},[627,1564,1565,1582,1599,1617],{},[611,1566,1567,1572,1575,1579],{},[632,1568,1569],{},[635,1570,1571],{},"extension point",[632,1573,1574],{},"A place where one module adds things to another without importing it, either a registry or a hook.",[632,1576,1577],{},[644,1578,72],{"href":73},[632,1580,1581],{},"plug-in point, contribution point",[611,1583,1584,1589,1592,1596],{},[632,1585,1586],{},[635,1587,1588],{},"registry",[632,1590,1591],{},"A build-time list that modules add entries to, such as menus, widgets, tabs, permissions, roles, scopes and Model Context Protocol (MCP) tools.",[632,1593,1594],{},[644,1595,72],{"href":73},[632,1597,1598],{},"virtual registry",[611,1600,1601,1606,1611,1615],{},[632,1602,1603],{},[635,1604,1605],{},"hook",[632,1607,1608,1609,718],{},"A runtime hook (Nitro or app) that a module calls and that listeners in the host app or other modules answer, such as ",[677,1610,1000],{},[632,1612,1613],{},[644,1614,72],{"href":73},[632,1616,704],{},[611,1618,1619,1624,1627,1631],{},[632,1620,1621],{},[635,1622,1623],{},"widget area",[632,1625,1626],{},"A named slot where the Widget module renders the components modules add.",[632,1628,1629],{},[644,1630,358],{"href":359},[632,1632,704],{},[600,1634,41],{"id":1635},"database",[605,1637,1638,1650],{},[608,1639,1640],{},[611,1641,1642,1644,1646,1648],{},[614,1643,616],{},[614,1645,619],{},[614,1647,622],{},[614,1649,625],{},[627,1651,1652,1670,1687,1706],{},[611,1653,1654,1659,1662,1667],{},[632,1655,1656],{},[635,1657,1658],{},"migration",[632,1660,1661],{},"A generated SQL (Structured Query Language) file that changes the database schema. You commit one whenever a module adds or changes tables.",[632,1663,1664],{},[644,1665,41],{"href":1666},"\u002Fget-started\u002Fdatabase#migrations",[632,1668,1669],{},"schema change file",[611,1671,1672,1677,1680,1685],{},[632,1673,1674],{},[635,1675,1676],{},"dialect",[632,1678,1679],{},"The database type a schema is written for: SQLite or PostgreSQL.",[632,1681,1682],{},[644,1683,41],{"href":1684},"\u002Fget-started\u002Fdatabase#sqlite-and-postgresql",[632,1686,704],{},[611,1688,1689,1694,1700,1704],{},[632,1690,1691],{},[635,1692,1693],{},"NuxtHub",[632,1695,1696,1697,718],{},"The module that gives the host app its database and blob storage. Its package is ",[677,1698,1699],{},"@nuxthub\u002Fcore",[632,1701,1702],{},[644,1703,41],{"href":42},[632,1705,704],{},[611,1707,1708,1713,1716,1721],{},[632,1709,1710],{},[635,1711,1712],{},"Drizzle",[632,1714,1715],{},"The TypeScript object-relational mapper (ORM) that modules use to define tables and generate migrations.",[632,1717,1718],{},[644,1719,1720],{"href":400},"Module Kit database",[632,1722,704],{},[600,1724,1726],{"id":1725},"tools-and-acronyms","Tools and acronyms",[605,1728,1729,1741],{},[608,1730,1731],{},[611,1732,1733,1735,1737,1739],{},[614,1734,616],{},[614,1736,619],{},[614,1738,622],{},[614,1740,625],{},[627,1742,1743,1760,1776,1792,1812,1833],{},[611,1744,1745,1750,1753,1757],{},[632,1746,1747],{},[635,1748,1749],{},"Nitro",[632,1751,1752],{},"Nuxt's server engine, where server routes, server plugins and hooks run.",[632,1754,1755],{},[644,1756,86],{"href":87},[632,1758,1759],{},"server runtime",[611,1761,1762,1767,1770,1774],{},[632,1763,1764],{},[635,1765,1766],{},"PKCE",[632,1768,1769],{},"Proof Key for Code Exchange: a one-time secret that proves the app finishing a sign-in is the app that started it.",[632,1771,1772],{},[644,1773,81],{"href":82},[632,1775,704],{},[611,1777,1778,1783,1786,1790],{},[632,1779,1780],{},[635,1781,1782],{},"SPA",[632,1784,1785],{},"Single-page application: a browser app with no server of its own.",[632,1787,1788],{},[644,1789,81],{"href":82},[632,1791,704],{},[611,1793,1794,1799,1806,1810],{},[632,1795,1796],{},[635,1797,1798],{},"JWKS",[632,1800,1801,1802,1805],{},"JSON Web Key Set: the public keys an issuer publishes at ",[677,1803,1804],{},"\u002F.well-known\u002Fjwks.json"," so others can verify its tokens.",[632,1807,1808],{},[644,1809,141],{"href":142},[632,1811,704],{},[611,1813,1814,1819,1826,1830],{},[632,1815,1816],{},[635,1817,1818],{},"PII",[632,1820,1821,1822,1825],{},"Personally identifiable information (personal data). Permissions such as ",[677,1823,1824],{},"events:pii"," guard it. They are sensitive, so wildcards never include them.",[632,1827,1828],{},[644,1829,67],{"href":1038},[632,1831,1832],{},"personal data scope, personal-data scope",[611,1834,1835,1840,1847,1852],{},[632,1836,1837],{},[635,1838,1839],{},"ACL",[632,1841,1842,1843,1846],{},"Access control list. In the starter, ",[677,1844,1845],{},"NUXT_ACL_ADMINS"," lists the emails that always get the admin role.",[632,1848,1849],{},[644,1850,31],{"href":1851},"\u002Fget-started\u002Fauthentication#_4-roles-and-the-first-admin",[632,1853,704],{},[600,1855,1857],{"id":1856},"how-to-use-a-term","How to use a term",[593,1859,1860,1861,1864],{},"Link a term to this page the first time a page uses it, then write it plainly. Put the plain word first and the code\nname once after it, as the ",[644,1862,1863],{"href":744},"writing rules"," explain.",[600,1866,1868],{"id":1867},"next-steps","Next steps",[1870,1871,1872,1878,1883],"ul",{},[1873,1874,1875,1877],"li",{},[644,1876,553],{"href":744}," – the writing rules these terms belong to.",[1873,1879,1880,1882],{},[644,1881,67],{"href":68}," – the permission, role, scope and policy terms in context.",[1873,1884,1885,1887],{},[644,1886,81],{"href":82}," – the signing-in terms across apps.",{"title":1889,"searchDepth":1890,"depth":1890,"links":1891},"",2,[1892,1893,1894,1895,1896,1897,1898,1899,1900],{"id":602,"depth":1890,"text":603},{"id":884,"depth":1890,"text":885},{"id":1222,"depth":1890,"text":1223},{"id":1458,"depth":1890,"text":1459},{"id":1548,"depth":1890,"text":72},{"id":1635,"depth":1890,"text":41},{"id":1725,"depth":1890,"text":1726},{"id":1856,"depth":1890,"text":1857},{"id":1867,"depth":1890,"text":1868},"The one word these docs use for each concept, what it means and which page explains it.","md",null,{},{"icon":89},{"title":86,"description":1901},"wJf_KPNfXdBBbHmzAEM6dIL_jmk-lRr7OCuAND1wQ_I",[1909,1911],{"title":81,"path":82,"stem":83,"description":1910,"icon":84,"children":-1},"Which module each of your apps needs to sign people in across a web app, a mobile app and the services they call.",{"title":96,"path":97,"stem":98,"description":1912,"icon":99,"children":-1},"Which of the three areas a new screen belongs in, the layout it gets and where its navigation entry goes.",1794503140360]