[{"data":1,"prerenderedAt":1504},["ShallowReactive",2],{"navigation_docs":3,"-modules-interface-ui-page-components":587,"-modules-interface-ui-page-components-surround":1499},[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":332,"body":589,"description":1492,"extension":1493,"links":1494,"meta":1495,"navigation":1496,"path":333,"seo":1497,"stem":334,"__hash__":1498},"docs\u002F3.modules\u002F4.interface\u002F1.ui\u002F2.page-components.md",{"type":590,"value":591,"toc":1481},"minimark",[592,600,606,611,614,627,638,642,647,769,781,801,813,817,820,1020,1038,1050,1054,1057,1187,1209,1223,1237,1241,1246,1364,1386,1408,1421,1425,1428,1449,1454,1458],[593,594,595,596,599],"p",{},"This page lists the components every admin and account page is made of, with their props and slots. It is for app\ndevelopers and module authors who build those pages. Set up the module first: ",[597,598,173],"a",{"href":327},".",[593,601,602,603,605],{},"The components add structure and spacing only. Colours and radius come from Nuxt UI. When to use which one is\nexplained in the ",[597,604,91],{"href":102},"; this page does not repeat those rules.",[607,608,610],"h2",{"id":609},"how-they-are-registered","How they are registered",[593,612,613],{},"The components are auto-imported by name, with no prefix. None is a global component, so each page only loads the\nones it uses.",[615,616,617,618,622,623,626],"tip",{},"To pick a component at runtime, call ",[619,620,621],"code",{},"resolveComponent('PageHeading')"," with a literal name. Nuxt resolves it at build\ntime. Do not register the component with ",[619,624,625],{},"global: true",": a global component is bundled into the app entry and\nslows the first render of every page.",[593,628,629,630,599],{},"Every built-in string is a prop, and its default is translated. See\n",[597,631,633,634,637],{"href":632},"\u002Fmodules\u002Finterface\u002Fui\u002Freference#the-patterns-strings","the ",[619,635,636],{},"patterns"," strings",[607,639,641],{"id":640},"page-frame","Page frame",[593,643,644,645,599],{},"The heading, tabs and toolbar at the top of a page. The admin area's shell is on\n",[597,646,336],{"href":337},[648,649,650,669],"table",{},[651,652,653],"thead",{},[654,655,656,660,663,666],"tr",{},[657,658,659],"th",{},"Component",[657,661,662],{},"Props",[657,664,665],{},"Slots",[657,667,668],{},"Use",[670,671,672,710,731,751],"tbody",{},[654,673,674,680,692,707],{},[675,676,677],"td",{},[619,678,679],{},"PageHeading",[675,681,682,685,686,685,689],{},[619,683,684],{},"title?",", ",[619,687,688],{},"description?",[619,690,691],{},"breadcrumb?: string | BreadcrumbItem[]",[675,693,694,685,697,685,700,703,704],{},[619,695,696],{},"title",[619,698,699],{},"badge",[619,701,702],{},"description",", default (meta row), ",[619,705,706],{},"actions",[675,708,709],{},"The title block of an app page.",[654,711,712,717,725,728],{},[675,713,714],{},[619,715,716],{},"PageTabs",[675,718,719,685,722],{},[619,720,721],{},"items: (NavigationMenuItem & { value? })[]",[619,723,724],{},"v-model?",[675,726,727],{},"none",[675,729,730],{},"Tabs under a heading, for sections the page owns.",[654,732,733,738,746,748],{},[675,734,735],{},[619,736,737],{},"PageSectionSwitcher",[675,739,740,685,743],{},[619,741,742],{},"items: NavigationMenuItem[]",[619,744,745],{},"label?",[675,747,727],{},[675,749,750],{},"A button that opens a menu of every section, for narrow screens. The account area uses it.",[654,752,753,758,760,766],{},[675,754,755],{},[619,756,757],{},"PageToolbar",[675,759,727],{},[675,761,762,763],{},"default (search and filters), ",[619,764,765],{},"right",[675,767,768],{},"The row of search and filter controls above a table.",[593,770,771,777,778,599],{},[772,773,774,599],"strong",{},[619,775,776],{},"breadcrumb"," A string is a plain label above the title. An array renders breadcrumbs, such as\n",[619,779,780],{},"[{ label: 'Users', to: '\u002Fadmin\u002Fusers' }, { label: 'Ada' }]",[593,782,783,788,789,792,793,796,797,800],{},[772,784,785,787],{},[619,786,716],{}," modes."," When the items have ",[619,790,791],{},"to",", each tab is a route (link mode). With ",[619,794,795],{},"v-model",", the tab whose ",[619,798,799],{},"value","\nmatches is active (state mode). On narrow screens the strip scrolls sideways and hides icons.",[593,802,803,808,809,812],{},[772,804,805,807],{},[619,806,737],{}," label."," ",[619,810,811],{},"label"," names the button for screen readers. The current section is appended to it.",[607,814,816],{"id":815},"cards","Cards",[593,818,819],{},"The framed blocks a page is made of.",[648,821,822,834],{},[651,823,824],{},[654,825,826,828,830,832],{},[657,827,659],{},[657,829,662],{},[657,831,665],{},[657,833,668],{},[670,835,836,876,916,955,992],{},[654,837,838,843,858,869],{},[675,839,840],{},[619,841,842],{},"SectionCard",[675,844,845,685,847,685,849,685,852,685,855],{},[619,846,684],{},[619,848,688],{},[619,850,851],{},"icon?",[619,853,854],{},"loading?",[619,856,857],{},"flush?",[675,859,860,685,863,865,866],{},[619,861,862],{},"header",[619,864,706],{},", default, ",[619,867,868],{},"footer",[675,870,871,872,875],{},"A framed block of a page. ",[619,873,874],{},"flush"," removes the body padding.",[654,877,878,883,894,907],{},[675,879,880],{},[619,881,882],{},"TableCard",[675,884,885,685,887,685,889,685,891],{},[619,886,684],{},[619,888,688],{},[619,890,854],{},[619,892,893],{},"refreshing?",[675,895,896,897,900,901,685,903,685,905],{},"default (the ",[619,898,899],{},"UTable","), ",[619,902,862],{},[619,904,706],{},[619,906,868],{},[675,908,909,910,912,913,599],{},"The frame a table sits in. ",[619,911,868],{}," holds ",[619,914,915],{},"TablePagination",[654,917,918,923,943,949],{},[675,919,920],{},[619,921,922],{},"StatCard",[675,924,925,685,927,685,930,685,933,685,935,685,938,685,940],{},[619,926,811],{},[619,928,929],{},"value?",[619,931,932],{},"hint?",[619,934,851],{},[619,936,937],{},"to?",[619,939,854],{},[619,941,942],{},"empty?",[675,944,945,946,948],{},"default (replaces ",[619,947,799],{},")",[675,950,951,952,954],{},"A number with a label. ",[619,953,791],{}," links the card to the list it counts.",[654,956,957,962,980,989],{},[675,958,959],{},[619,960,961],{},"ListCard",[675,963,964,685,966,685,968,685,970,685,973,685,975,685,977],{},[619,965,696],{},[619,967,688],{},[619,969,854],{},[619,971,972],{},"isEmpty?",[619,974,942],{},[619,976,937],{},[619,978,979],{},"toLabel?",[675,981,982,983,986,987],{},"default (",[619,984,985],{},"\u003Cli>"," rows), ",[619,988,706],{},[675,990,991],{},"A short divided list with a \"View all\" link.",[654,993,994,999,1011,1017],{},[675,995,996],{},[619,997,998],{},"DescriptionList",[675,1000,1001,685,1004,685,1006,685,1008],{},[619,1002,1003],{},"items: { key?, label, value? }[]",[619,1005,942],{},[619,1007,854],{},[619,1009,1010],{},"align?",[675,1012,1013,1014],{},"one slot per ",[619,1015,1016],{},"key",[675,1018,1019],{},"Label and value rows. A missing value shows \"Not set\".",[593,1021,1022,808,1027,1030,1031,1034,1035,599],{},[772,1023,1024,1026],{},[619,1025,882],{}," loading.",[619,1028,1029],{},"loading"," shows skeleton rows. ",[619,1032,1033],{},"refreshing"," keeps the rows on screen and dims them while new\nones load. When to pass which is on ",[597,1036,101],{"href":1037},"\u002Fguide\u002Fux-patterns\u002Fpages#loading",[593,1039,1040,1043,1044,1047,1048,599],{},[772,1041,1042],{},"No table wrapper."," Write ",[619,1045,1046],{},"\u003CTableCard>\u003CUTable :ui=\"tableUi()\" \u002F>\u003C\u002FTableCard>"," yourself. A wrapper component would\nlose the slot types of ",[619,1049,899],{},[607,1051,1053],{"id":1052},"table-rows","Table rows",[593,1055,1056],{},"The cells and controls inside a list.",[648,1058,1059,1071],{},[651,1060,1061],{},[654,1062,1063,1065,1067,1069],{},[657,1064,659],{},[657,1066,662],{},[657,1068,665],{},[657,1070,668],{},[670,1072,1073,1097,1127,1158],{},[654,1074,1075,1080,1089,1094],{},[675,1076,1077],{},[619,1078,1079],{},"TableIdentity",[675,1081,1082,685,1084,685,1086],{},[619,1083,696],{},[619,1085,688],{},[619,1087,1088],{},"avatar?: AvatarProps",[675,1090,1091],{},[619,1092,1093],{},"badges",[675,1095,1096],{},"The first cell of a row: a name, a muted second line and an optional avatar.",[654,1098,1099,1104,1119,1121],{},[675,1100,1101],{},[619,1102,1103],{},"StatusBadge",[675,1105,1106,685,1109,685,1111,685,1114,685,1117],{},[619,1107,1108],{},"status",[619,1110,745],{},[619,1112,1113],{},"colors?: Record\u003Cstring, StatusColor>",[619,1115,1116],{},"size?",[619,1118,851],{},[675,1120,727],{},[675,1122,1123,1124,599],{},"A status as a subtle badge, coloured by ",[619,1125,1126],{},"statusColor",[654,1128,1129,1134,1149,1151],{},[675,1130,1131],{},[619,1132,1133],{},"RowMenu",[675,1135,1136,685,1139,685,1142,685,1145,685,1147],{},[619,1137,1138],{},"items: DropdownMenuItem[] | DropdownMenuItem[][]",[619,1140,1141],{},"subject?",[619,1143,1144],{},"variant?: 'ghost' | 'outline'",[619,1146,1116],{},[619,1148,745],{},[675,1150,727],{},[675,1152,1153,1154,1157],{},"The ",[619,1155,1156],{},"⋯"," menu of a row or heading.",[654,1159,1160,1164,1178,1184],{},[675,1161,1162],{},[619,1163,915],{},[675,1165,1166,685,1169,685,1172,685,1175],{},[619,1167,1168],{},"total",[619,1170,1171],{},"v-model:page",[619,1173,1174],{},"v-model:page-size",[619,1176,1177],{},"pageSizes?",[675,1179,982,1180,1183],{},[619,1181,1182],{},"{ range }",", replaces the range text)",[675,1185,1186],{},"The footer of a paginated list: \"21–40 of 132\", rows per page and pages.",[593,1188,1189,808,1193,1196,1197,1200,1201,1203,1204,599],{},[772,1190,1191,599],{},[619,1192,1103],{},[619,1194,1195],{},"colors"," recolours single statuses, such as ",[619,1198,1199],{},"{ archived: 'warning' }",". ",[619,1202,811],{}," defaults to the\nstatus, so pass a translated one. Without a status or label it renders nothing. The colours are listed under\n",[597,1205,1207],{"href":1206},"\u002Fmodules\u002Finterface\u002Fui\u002Fcomposables#status-and-styling",[619,1208,1126],{},[593,1210,1211,1215,1216,1218,1219,1222],{},[772,1212,1213,599],{},[619,1214,1133],{}," A click on the menu does not reach the row. Its accessible name is \"Actions for {subject}\", or ",[619,1217,811],{},".\nUse ",[619,1220,1221],{},"variant=\"outline\""," in a heading.",[593,1224,1225,808,1229,1232,1233,1236],{},[772,1226,1227,599],{},[619,1228,915],{},[619,1230,1231],{},"pageSizes"," defaults to ",[619,1234,1235],{},"[20, 50, 100]",". The pages hide while everything fits on one page. A\nnew page size goes back to page 1.",[607,1238,1240],{"id":1239},"forms-and-dialogs","Forms and dialogs",[593,1242,1243,1244,599],{},"The pieces of create, edit and confirm flows. How they fit together is on\n",[597,1245,106],{"href":107},[648,1247,1248,1260],{},[651,1249,1250],{},[654,1251,1252,1254,1256,1258],{},[657,1253,659],{},[657,1255,662],{},[657,1257,665],{},[657,1259,668],{},[670,1261,1262,1288,1327],{},[654,1263,1264,1269,1280,1285],{},[675,1265,1266],{},[619,1267,1268],{},"FormRow",[675,1270,1271,1272,1275,1276,1279],{},"every ",[619,1273,1274],{},"UFormField"," prop (a ",[619,1277,1278],{},"ui"," is merged)",[675,1281,1271,1282,1284],{},[619,1283,1274],{}," slot",[675,1286,1287],{},"One horizontal row of an inline settings form: label and hint left, control right.",[654,1289,1290,1295,1315,1321],{},[675,1291,1292],{},[619,1293,1294],{},"FormSlideover",[675,1296,1297,685,1299,685,1301,685,1304,685,1307,685,1310,685,1312],{},[619,1298,696],{},[619,1300,688],{},[619,1302,1303],{},"formId",[619,1305,1306],{},"submitLabel",[619,1308,1309],{},"cancelLabel?",[619,1311,854],{},[619,1313,1314],{},"disabled?",[675,1316,1317,1318],{},"default (the form), ",[619,1319,1320],{},"footer({ cancel })",[675,1322,1323,1324,599],{},"A slideover for create and edit forms. Emits ",[619,1325,1326],{},"close",[654,1328,1329,1334,1352,1354],{},[675,1330,1331],{},[619,1332,1333],{},"ConfirmDialog",[675,1335,1336,685,1338,685,1340,685,1343,685,1346,685,1349],{},[619,1337,684],{},[619,1339,688],{},[619,1341,1342],{},"confirmText?",[619,1344,1345],{},"cancelText?",[619,1347,1348],{},"destructive?",[619,1350,1351],{},"dismissible?",[675,1353,727],{},[675,1355,1356,1357,1360,1361,599],{},"The modal behind ",[619,1358,1359],{},"useConfirmDialog",". Emits ",[619,1362,1363],{},"close(boolean)",[593,1365,1366,1370,1371,1374,1375,1378,1379,1382,1383,599],{},[772,1367,1368,599],{},[619,1369,1268],{}," The label column takes a third of the row, at most ",[619,1372,1373],{},"16rem",". Rows stack below the ",[619,1376,1377],{},"sm"," breakpoint. Each\nrow holds one control, which gets the row's ",[619,1380,1381],{},"id",". Sizing rules are on ",[597,1384,101],{"href":1385},"\u002Fguide\u002Fux-patterns\u002Fpages#detail-pages",[593,1387,1388,1393,1394,1397,1398,1400,1401,1404,1405,599],{},[772,1389,1390,1392],{},[619,1391,1294],{}," footer."," By default it shows Cancel and a submit button wired to ",[619,1395,1396],{},"form=\"\u003CformId>\"",". The ",[619,1399,868],{}," slot\nreplaces both. It receives ",[619,1402,1403],{},"cancel",", which closes the slideover with ",[619,1406,1407],{},"false",[593,1409,1410,1414,1415,1420],{},[772,1411,1412,599],{},[619,1413,1333],{}," Open it through ",[597,1416,1418],{"href":1417},"\u002Fmodules\u002Finterface\u002Fui\u002Fcomposables#confirmations",[619,1419,1359],{}," rather than\ndirectly.",[607,1422,1424],{"id":1423},"empty-states-and-the-page-root","Empty states and the page root",[593,1426,1427],{},"UI has no empty-state component and no page wrapper:",[1429,1430,1431,1443],"ul",{},[1432,1433,1434,1435,1438,1439,1442],"li",{},"An empty state is Nuxt UI's ",[619,1436,1437],{},"UEmpty",", with ",[619,1440,1441],{},"variant=\"naked\""," inside a card.",[1432,1444,1445,1446,599],{},"A page root is ",[619,1447,1448],{},"\u003Cdiv class=\"flex flex-col gap-4\">",[593,1450,1451,1452,599],{},"A complete detail page built from these components is on ",[597,1453,101],{"href":1385},[607,1455,1457],{"id":1456},"next-steps","Next steps",[1429,1459,1460,1465,1470],{},[1432,1461,1462,1464],{},[597,1463,101],{"href":102}," – combine these components into a list or a detail page.",[1432,1466,1467,1469],{},[597,1468,106],{"href":107}," – build the create, edit and delete flows.",[1432,1471,1472,1474,1475,1477,1478,599],{},[597,1473,344],{"href":345}," – look up ",[619,1476,1359],{}," and ",[619,1479,1480],{},"tableUi",{"title":1482,"searchDepth":1483,"depth":1483,"links":1484},"",2,[1485,1486,1487,1488,1489,1490,1491],{"id":609,"depth":1483,"text":610},{"id":640,"depth":1483,"text":641},{"id":815,"depth":1483,"text":816},{"id":1052,"depth":1483,"text":1053},{"id":1239,"depth":1483,"text":1240},{"id":1423,"depth":1483,"text":1424},{"id":1456,"depth":1483,"text":1457},"Look up the props and slots of the headings, cards, tables, row menus and forms every app page uses.","md",null,{},{"title":332},{"title":332,"description":1492},"ijBbguTxT_z6wdim-GcjRBbVgP6PETyC8tDFnGcp8Rg",[1500,1502],{"title":173,"path":327,"stem":328,"description":1501,"children":-1},"Gives every module's screens the same headings, cards, tables, forms and toasts, on top of Nuxt UI.",{"title":336,"path":337,"stem":338,"description":1503,"children":-1},"Wrap an area of your app in the same sidebar dashboard layout the admin area uses.",1794503156874]