[{"data":1,"prerenderedAt":1182},["ShallowReactive",2],{"navigation":3,"\u002Fdeployment\u002Freading-lighthouse-scores":553,"\u002Fdeployment\u002Freading-lighthouse-scores-surround":1177},[4,22,64,89,215,503],{"title":5,"path":6,"stem":7,"children":8},"Introduction","\u002Fgetting-started","1.getting-started\u002F1.index",[9,10,14,18],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation",{"title":15,"path":16,"stem":17},"Key Ideas","\u002Fgetting-started\u002Fkey-ideas","1.getting-started\u002F3.key-ideas",{"title":19,"path":20,"stem":21},"Releases","\u002Fgetting-started\u002Freleases","1.getting-started\u002F4.releases",{"title":23,"path":24,"stem":25,"children":26},"Overview","\u002Fcore-concepts","2.core-concepts\u002F0.index",[27,28,32,36,40,44,48,52,56,60],{"title":23,"path":24,"stem":25},{"title":29,"path":30,"stem":31},"How It All Works","\u002Fcore-concepts\u002Farchitecture","2.core-concepts\u002F1.architecture",{"title":33,"path":34,"stem":35},"The Data Model","\u002Fcore-concepts\u002Fthe-data-model","2.core-concepts\u002F2.the-data-model",{"title":37,"path":38,"stem":39},"Layouts & Pages","\u002Fcore-concepts\u002Flayouts-and-pages","2.core-concepts\u002F3.layouts-and-pages",{"title":41,"path":42,"stem":43},"Dynamic Pages","\u002Fcore-concepts\u002Fdynamic-pages","2.core-concepts\u002F4.dynamic-pages",{"title":45,"path":46,"stem":47},"Components","\u002Fcore-concepts\u002Fcomponents","2.core-concepts\u002F5.components",{"title":49,"path":50,"stem":51},"Draft & Publish Workflow","\u002Fcore-concepts\u002Fdraft-and-publish","2.core-concepts\u002F6.draft-and-publish",{"title":53,"path":54,"stem":55},"The Admin Panel","\u002Fcore-concepts\u002Fadmin-panel","2.core-concepts\u002F7.admin-panel",{"title":57,"path":58,"stem":59},"Caching","\u002Fcore-concepts\u002Fcaching","2.core-concepts\u002F8.caching",{"title":61,"path":62,"stem":63},"Glossary","\u002Fcore-concepts\u002Fglossary","2.core-concepts\u002F9.glossary",{"title":23,"path":65,"stem":66,"children":67},"\u002Fguides","3.guides\u002F0.index",[68,69,73,77,81,85],{"title":23,"path":65,"stem":66},{"title":70,"path":71,"stem":72},"Your First Layout","\u002Fguides\u002Fyour-first-layout","3.guides\u002F1.your-first-layout",{"title":74,"path":75,"stem":76},"Your First Page Template","\u002Fguides\u002Fyour-first-page-template","3.guides\u002F2.your-first-page-template",{"title":78,"path":79,"stem":80},"Your First Component","\u002Fguides\u002Fyour-first-component","3.guides\u002F3.your-first-component",{"title":82,"path":83,"stem":84},"Alternative UI Variants","\u002Fguides\u002Falternative-ui-variants","3.guides\u002F4.alternative-ui-variants",{"title":86,"path":87,"stem":88},"Your First Dynamic Page","\u002Fguides\u002Fyour-first-dynamic-page","3.guides\u002F5.your-first-dynamic-page",{"title":23,"path":90,"stem":91,"children":92},"\u002Fapi","4.api\u002F0.index",[93,94,98,102,120,162,166,170,195,199,203,207,211],{"title":23,"path":90,"stem":91},{"title":95,"path":96,"stem":97},"Bundle Setup","\u002Fapi\u002Fbundle-setup","4.api\u002F02.bundle-setup",{"title":99,"path":100,"stem":101},"Configuration Reference","\u002Fapi\u002Fconfiguration","4.api\u002F03.configuration",{"title":103,"path":104,"stem":105,"children":106,"page":119},"Users","\u002Fapi\u002Fusers","4.api\u002F04.users",[107,111,115],{"title":108,"path":109,"stem":110},"Authentication","\u002Fapi\u002Fusers\u002Fauthentication","4.api\u002F04.users\u002F1.authentication",{"title":112,"path":113,"stem":114},"User Emails","\u002Fapi\u002Fusers\u002Fuser-emails","4.api\u002F04.users\u002F2.user-emails",{"title":116,"path":117,"stem":118},"Access Control","\u002Fapi\u002Fusers\u002Faccess-control","4.api\u002F04.users\u002F3.access-control",false,{"title":45,"path":121,"stem":122,"children":123,"page":119},"\u002Fapi\u002Fcomponents","4.api\u002F05.components",[124,128,149],{"title":125,"path":126,"stem":127},"Creating Components","\u002Fapi\u002Fcomponents\u002Fcreating-components","4.api\u002F05.components\u002F1.creating-components",{"title":129,"path":130,"stem":131,"children":132,"page":119},"Annotations","\u002Fapi\u002Fcomponents\u002Fannotations","4.api\u002F05.components\u002F2.annotations",[133,137,141,145],{"title":134,"path":135,"stem":136},"Publishable","\u002Fapi\u002Fcomponents\u002Fannotations\u002Fpublishable","4.api\u002F05.components\u002F2.annotations\u002F1.publishable",{"title":138,"path":139,"stem":140},"Uploadable","\u002Fapi\u002Fcomponents\u002Fannotations\u002Fuploadable","4.api\u002F05.components\u002F2.annotations\u002F2.uploadable",{"title":142,"path":143,"stem":144},"Timestamped","\u002Fapi\u002Fcomponents\u002Fannotations\u002Ftimestamped","4.api\u002F05.components\u002F2.annotations\u002F3.timestamped",{"title":146,"path":147,"stem":148},"Explicit Allow Only","\u002Fapi\u002Fcomponents\u002Fannotations\u002Fexplicit-allow-only","4.api\u002F05.components\u002F2.annotations\u002F4.explicit-allow-only",{"title":150,"path":151,"stem":152,"children":153,"page":119},"Built Ins","\u002Fapi\u002Fcomponents\u002Fbuilt-ins","4.api\u002F05.components\u002F3.built-ins",[154,158],{"title":155,"path":156,"stem":157},"Collection Component","\u002Fapi\u002Fcomponents\u002Fbuilt-ins\u002Fcollection-component","4.api\u002F05.components\u002F3.built-ins\u002F1.collection-component",{"title":159,"path":160,"stem":161},"Form Component","\u002Fapi\u002Fcomponents\u002Fbuilt-ins\u002Fform-component","4.api\u002F05.components\u002F3.built-ins\u002F2.form-component",{"title":163,"path":164,"stem":165},"Page Data & Nested Pages","\u002Fapi\u002Fdynamic-pages","4.api\u002F06.dynamic-pages",{"title":167,"path":168,"stem":169},"Routes","\u002Fapi\u002Froutes","4.api\u002F07.routes",{"title":171,"path":172,"stem":173,"children":174,"page":119},"Data Fixtures","\u002Fapi\u002Fdata-fixtures","4.api\u002F08.data-fixtures",[175,179,183,187,191],{"title":176,"path":177,"stem":178},"Getting Started with Fixtures","\u002Fapi\u002Fdata-fixtures\u002Fgetting-started","4.api\u002F08.data-fixtures\u002F1.getting-started",{"title":180,"path":181,"stem":182},"Builder Reference","\u002Fapi\u002Fdata-fixtures\u002Fbuilder-reference","4.api\u002F08.data-fixtures\u002F2.builder-reference",{"title":184,"path":185,"stem":186},"Seeding Content","\u002Fapi\u002Fdata-fixtures\u002Fseeding-content","4.api\u002F08.data-fixtures\u002F3.seeding-content",{"title":188,"path":189,"stem":190},"Appending & Multiple Scaffolds","\u002Fapi\u002Fdata-fixtures\u002Fappending","4.api\u002F08.data-fixtures\u002F4.appending",{"title":192,"path":193,"stem":194},"Generating Fixtures","\u002Fapi\u002Fdata-fixtures\u002Fgenerating-fixtures","4.api\u002F08.data-fixtures\u002F5.generating-fixtures",{"title":196,"path":197,"stem":198},"Real-Time (Mercure)","\u002Fapi\u002Freal-time","4.api\u002F09.real-time",{"title":200,"path":201,"stem":202},"HTTP Caching","\u002Fapi\u002Fhttp-caching","4.api\u002F10.http-caching",{"title":204,"path":205,"stem":206},"Orphaned Data","\u002Fapi\u002Forphaned-data","4.api\u002F11.orphaned-data",{"title":208,"path":209,"stem":210},"Console Commands","\u002Fapi\u002Fconsole-commands","4.api\u002F12.console-commands",{"title":212,"path":213,"stem":214},"Debugging & Errors","\u002Fapi\u002Fdebugging","4.api\u002F13.debugging",{"title":23,"path":216,"stem":217,"children":218},"\u002Fnuxt-module","5.nuxt-module\u002F0.index",[219,220,224,237,257,286,307,430,464,467,495,499],{"title":23,"path":216,"stem":217},{"title":221,"path":222,"stem":223},"Module Setup","\u002Fnuxt-module\u002Fmodule-setup","5.nuxt-module\u002F01.module-setup",{"title":225,"path":226,"stem":227,"children":228,"page":119},"Configuration","\u002Fnuxt-module\u002Fconfiguration","5.nuxt-module\u002F02.configuration",[229,233],{"title":230,"path":231,"stem":232},"Nuxt Config","\u002Fnuxt-module\u002Fconfiguration\u002Fnuxt-config","5.nuxt-module\u002F02.configuration\u002F1.nuxt-config",{"title":234,"path":235,"stem":236},"Site Config & SEO","\u002Fnuxt-module\u002Fconfiguration\u002Fsite-config-and-seo","5.nuxt-module\u002F02.configuration\u002F2.site-config-and-seo",{"title":238,"path":239,"stem":240,"children":241,"page":119},"Building Your Ui","\u002Fnuxt-module\u002Fbuilding-your-ui","5.nuxt-module\u002F03.building-your-ui",[242,246,250,253],{"title":243,"path":244,"stem":245},"Layouts","\u002Fnuxt-module\u002Fbuilding-your-ui\u002Fcreating-layouts","5.nuxt-module\u002F03.building-your-ui\u002F1.creating-layouts",{"title":247,"path":248,"stem":249},"Page Templates","\u002Fnuxt-module\u002Fbuilding-your-ui\u002Fcreating-page-templates","5.nuxt-module\u002F03.building-your-ui\u002F2.creating-page-templates",{"title":45,"path":251,"stem":252},"\u002Fnuxt-module\u002Fbuilding-your-ui\u002Fcreating-components","5.nuxt-module\u002F03.building-your-ui\u002F3.creating-components",{"title":254,"path":255,"stem":256},"CLI Generator","\u002Fnuxt-module\u002Fbuilding-your-ui\u002Fcwa-cli","5.nuxt-module\u002F03.building-your-ui\u002F4.cwa-cli",{"title":258,"path":259,"stem":260,"children":261,"page":119},"Component Helpers","\u002Fnuxt-module\u002Fcomponent-helpers","5.nuxt-module\u002F04.component-helpers",[262,266,270,274,278,282],{"title":263,"path":264,"stem":265},"Images & Media","\u002Fnuxt-module\u002Fcomponent-helpers\u002Fimages-and-uploads","5.nuxt-module\u002F04.component-helpers\u002F1.images-and-uploads",{"title":267,"path":268,"stem":269},"Collections & Pagination","\u002Fnuxt-module\u002Fcomponent-helpers\u002Fcollections-and-pagination","5.nuxt-module\u002F04.component-helpers\u002F2.collections-and-pagination",{"title":271,"path":272,"stem":273},"HTML Content","\u002Fnuxt-module\u002Fcomponent-helpers\u002Fhtml-content","5.nuxt-module\u002F04.component-helpers\u002F3.html-content",{"title":275,"path":276,"stem":277},"Rich-Text Editor","\u002Fnuxt-module\u002Fcomponent-helpers\u002Frich-text-editor","5.nuxt-module\u002F04.component-helpers\u002F4.rich-text-editor",{"title":279,"path":280,"stem":281},"Real-Time Updates","\u002Fnuxt-module\u002Fcomponent-helpers\u002Freal-time-updates","5.nuxt-module\u002F04.component-helpers\u002F5.real-time-updates",{"title":283,"path":284,"stem":285},"Forms","\u002Fnuxt-module\u002Fcomponent-helpers\u002Fforms","5.nuxt-module\u002F04.component-helpers\u002F6.forms",{"title":287,"path":288,"stem":289,"children":290,"page":119},"Cwa Components","\u002Fnuxt-module\u002Fcwa-components","5.nuxt-module\u002F05.cwa-components",[291,295,299,303],{"title":292,"path":293,"stem":294},"\u003CCwaComponentGroup \u002F>","\u002Fnuxt-module\u002Fcwa-components\u002Fcwa-component-group","5.nuxt-module\u002F05.cwa-components\u002F1.cwa-component-group",{"title":296,"path":297,"stem":298},"\u003CCwaPage \u002F>","\u002Fnuxt-module\u002Fcwa-components\u002Fcwa-page","5.nuxt-module\u002F05.cwa-components\u002F2.cwa-page",{"title":300,"path":301,"stem":302},"\u003CCwaLink \u002F>","\u002Fnuxt-module\u002Fcwa-components\u002Fcwa-link","5.nuxt-module\u002F05.cwa-components\u002F3.cwa-link",{"title":304,"path":305,"stem":306},"\u003CCwaDefaultLayout \u002F>","\u002Fnuxt-module\u002Fcwa-components\u002Fcwa-default-layout","5.nuxt-module\u002F05.cwa-components\u002F5.cwa-default-layout",{"title":308,"path":309,"stem":310,"children":311,"page":119},"Composables","\u002Fnuxt-module\u002Fcomposables","5.nuxt-module\u002F06.composables",[312,315,323,348,368,385,405],{"title":23,"path":313,"stem":314},"\u002Fnuxt-module\u002Fcomposables\u002Foverview","5.nuxt-module\u002F06.composables\u002F0.overview",{"title":316,"path":317,"stem":318,"children":319,"page":119},"Layout","\u002Fnuxt-module\u002Fcomposables\u002Flayout","5.nuxt-module\u002F06.composables\u002F1.layout",[320],{"title":316,"path":321,"stem":322},"\u002Fnuxt-module\u002Fcomposables\u002Flayout\u002Fuse-cwa-layout","5.nuxt-module\u002F06.composables\u002F1.layout\u002F1.use-cwa-layout",{"title":324,"path":325,"stem":326,"children":327,"page":119},"Component","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent","5.nuxt-module\u002F06.composables\u002F2.component",[328,332,336,340,344],{"title":329,"path":330,"stem":331},"Component (recommended)","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-component","5.nuxt-module\u002F06.composables\u002F2.component\u002F1.use-cwa-component",{"title":333,"path":334,"stem":335},"Resource","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-resource","5.nuxt-module\u002F06.composables\u002F2.component\u002F2.use-cwa-resource",{"title":337,"path":338,"stem":339},"File Field","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-file-field","5.nuxt-module\u002F06.composables\u002F2.component\u002F3.use-cwa-file-field",{"title":341,"path":342,"stem":343},"Collection Pagination","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-collection-pagination","5.nuxt-module\u002F06.composables\u002F2.component\u002F4.use-cwa-collection-pagination",{"title":345,"path":346,"stem":347},"Collection Resource (deprecated)","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-collection-resource","5.nuxt-module\u002F06.composables\u002F2.component\u002F9.use-cwa-collection-resource",{"title":349,"path":350,"stem":351,"children":352,"page":119},"Form","\u002Fnuxt-module\u002Fcomposables\u002Fform","5.nuxt-module\u002F06.composables\u002F3.form",[353,356,360,364],{"title":349,"path":354,"stem":355},"\u002Fnuxt-module\u002Fcomposables\u002Fform\u002Fuse-cwa-form","5.nuxt-module\u002F06.composables\u002F3.form\u002F1.use-cwa-form",{"title":357,"path":358,"stem":359},"Form Input","\u002Fnuxt-module\u002Fcomposables\u002Fform\u002Fuse-cwa-form-input","5.nuxt-module\u002F06.composables\u002F3.form\u002F2.use-cwa-form-input",{"title":361,"path":362,"stem":363},"Form Repeated","\u002Fnuxt-module\u002Fcomposables\u002Fform\u002Fuse-cwa-form-repeated","5.nuxt-module\u002F06.composables\u002F3.form\u002F3.use-cwa-form-repeated",{"title":365,"path":366,"stem":367},"Form Collection","\u002Fnuxt-module\u002Fcomposables\u002Fform\u002Fuse-cwa-form-collection","5.nuxt-module\u002F06.composables\u002F3.form\u002F4.use-cwa-form-collection",{"title":369,"path":370,"stem":371,"children":372,"page":119},"Admin Manager","\u002Fnuxt-module\u002Fcomposables\u002Fadmin-manager","5.nuxt-module\u002F06.composables\u002F4.admin-manager",[373,377,381],{"title":374,"path":375,"stem":376},"Manager Tab","\u002Fnuxt-module\u002Fcomposables\u002Fadmin-manager\u002Fuse-cwa-resource-manager-tab","5.nuxt-module\u002F06.composables\u002F4.admin-manager\u002F1.use-cwa-resource-manager-tab",{"title":378,"path":379,"stem":380},"Resource Model","\u002Fnuxt-module\u002Fcomposables\u002Fadmin-manager\u002Fuse-cwa-resource-model","5.nuxt-module\u002F06.composables\u002F4.admin-manager\u002F2.use-cwa-resource-model",{"title":382,"path":383,"stem":384},"Resource Upload","\u002Fnuxt-module\u002Fcomposables\u002Fadmin-manager\u002Fuse-cwa-resource-upload","5.nuxt-module\u002F06.composables\u002F4.admin-manager\u002F3.use-cwa-resource-upload",{"title":386,"path":387,"stem":388,"children":389,"page":119},"Utilities","\u002Fnuxt-module\u002Fcomposables\u002Futilities","5.nuxt-module\u002F06.composables\u002F5.utilities",[390,394,398,402],{"title":391,"path":392,"stem":393},"Resource Endpoint","\u002Fnuxt-module\u002Fcomposables\u002Futilities\u002Fuse-cwa-resource-endpoint","5.nuxt-module\u002F06.composables\u002F5.utilities\u002F1.use-cwa-resource-endpoint",{"title":395,"path":396,"stem":397},"Query Model","\u002Fnuxt-module\u002Fcomposables\u002Futilities\u002Fuse-query-bound-model","5.nuxt-module\u002F06.composables\u002F5.utilities\u002F2.use-query-bound-model",{"title":399,"path":400,"stem":401},"Resource Route","\u002Fnuxt-module\u002Fcomposables\u002Futilities\u002Fuse-cwa-resource-route","5.nuxt-module\u002F06.composables\u002F5.utilities\u002F3.use-cwa-resource-route",{"title":271,"path":403,"stem":404},"\u002Fnuxt-module\u002Fcomposables\u002Futilities\u002Fuse-html-content","5.nuxt-module\u002F06.composables\u002F5.utilities\u002F4.use-html-content",{"title":406,"path":407,"stem":408,"children":409,"page":119},"Auth","\u002Fnuxt-module\u002Fcomposables\u002Fauth","5.nuxt-module\u002F06.composables\u002F6.auth",[410,414,418,422,426],{"title":411,"path":412,"stem":413},"Login","\u002Fnuxt-module\u002Fcomposables\u002Fauth\u002Fuse-login","5.nuxt-module\u002F06.composables\u002F6.auth\u002F1.use-login",{"title":415,"path":416,"stem":417},"Forgot Password","\u002Fnuxt-module\u002Fcomposables\u002Fauth\u002Fuse-forgot-password","5.nuxt-module\u002F06.composables\u002F6.auth\u002F2.use-forgot-password",{"title":419,"path":420,"stem":421},"Reset Password","\u002Fnuxt-module\u002Fcomposables\u002Fauth\u002Fuse-reset-password","5.nuxt-module\u002F06.composables\u002F6.auth\u002F3.use-reset-password",{"title":423,"path":424,"stem":425},"Verify Email","\u002Fnuxt-module\u002Fcomposables\u002Fauth\u002Fuse-verify-email","5.nuxt-module\u002F06.composables\u002F6.auth\u002F4.use-verify-email",{"title":427,"path":428,"stem":429},"Resend Verify Email","\u002Fnuxt-module\u002Fcomposables\u002Fauth\u002Fuse-resend-verify-email","5.nuxt-module\u002F06.composables\u002F6.auth\u002F5.use-resend-verify-email",{"title":431,"path":432,"stem":433,"children":434,"page":119},"Cwa Api","\u002Fnuxt-module\u002Fcwa-api","5.nuxt-module\u002F07.cwa-api",[435,438,442,446,449,452,456,460],{"title":23,"path":436,"stem":437},"\u002Fnuxt-module\u002Fcwa-api\u002Foverview","5.nuxt-module\u002F07.cwa-api\u002F1.overview",{"title":439,"path":440,"stem":441},"Resources","\u002Fnuxt-module\u002Fcwa-api\u002Fresources","5.nuxt-module\u002F07.cwa-api\u002F2.resources",{"title":443,"path":444,"stem":445},"Resources Manager","\u002Fnuxt-module\u002Fcwa-api\u002Fresources-manager","5.nuxt-module\u002F07.cwa-api\u002F3.resources-manager",{"title":406,"path":447,"stem":448},"\u002Fnuxt-module\u002Fcwa-api\u002Fauth","5.nuxt-module\u002F07.cwa-api\u002F4.auth",{"title":283,"path":450,"stem":451},"\u002Fnuxt-module\u002Fcwa-api\u002Fforms","5.nuxt-module\u002F07.cwa-api\u002F5.forms",{"title":453,"path":454,"stem":455},"Admin","\u002Fnuxt-module\u002Fcwa-api\u002Fadmin","5.nuxt-module\u002F07.cwa-api\u002F6.admin",{"title":457,"path":458,"stem":459},"Site Config","\u002Fnuxt-module\u002Fcwa-api\u002Fsite-config","5.nuxt-module\u002F07.cwa-api\u002F7.site-config",{"title":461,"path":462,"stem":463},"Orphaned Resources","\u002Fnuxt-module\u002Fcwa-api\u002Forphaned-resources","5.nuxt-module\u002F07.cwa-api\u002F8.orphaned-resources",{"title":108,"path":465,"stem":466},"\u002Fnuxt-module\u002Fauthentication","5.nuxt-module\u002F08.authentication",{"title":468,"path":469,"stem":470,"children":471,"page":119},"Cwa Layer","\u002Fnuxt-module\u002Fcwa-layer","5.nuxt-module\u002F9.cwa-layer",[472,475,479,483,487,491],{"title":23,"path":473,"stem":474},"\u002Fnuxt-module\u002Fcwa-layer\u002Foverview","5.nuxt-module\u002F9.cwa-layer\u002F1.overview",{"title":476,"path":477,"stem":478},"Auth Pages","\u002Fnuxt-module\u002Fcwa-layer\u002Fauth-pages","5.nuxt-module\u002F9.cwa-layer\u002F2.auth-pages",{"title":480,"path":481,"stem":482},"Admin Panel","\u002Fnuxt-module\u002Fcwa-layer\u002Fadmin-panel","5.nuxt-module\u002F9.cwa-layer\u002F3.admin-panel",{"title":484,"path":485,"stem":486},"Styling","\u002Fnuxt-module\u002Fcwa-layer\u002Fstyling","5.nuxt-module\u002F9.cwa-layer\u002F4.styling",{"title":488,"path":489,"stem":490},"Date Pickers","\u002Fnuxt-module\u002Fcwa-layer\u002Fdate-pickers","5.nuxt-module\u002F9.cwa-layer\u002F5.date-pickers",{"title":492,"path":493,"stem":494},"Maintenance","\u002Fnuxt-module\u002Fcwa-layer\u002Fmaintenance","5.nuxt-module\u002F9.cwa-layer\u002F6.maintenance",{"title":496,"path":497,"stem":498},"PWA & Offline","\u002Fnuxt-module\u002Fpwa","5.nuxt-module\u002F91.pwa",{"title":500,"path":501,"stem":502},"Page Caching","\u002Fnuxt-module\u002Fpage-caching","5.nuxt-module\u002F92.page-caching",{"title":504,"path":505,"stem":506,"children":507},"Deploying a CWA Site","\u002Fdeployment","6.deployment\u002F0.index",[508,509,513,517,521,525,529,533,537,541,545,549],{"title":504,"path":505,"stem":506},{"title":510,"path":511,"stem":512},"Docker","\u002Fdeployment\u002Fdocker","6.deployment\u002F1.docker",{"title":514,"path":515,"stem":516},"Kubernetes & Helm","\u002Fdeployment\u002Fkubernetes","6.deployment\u002F2.kubernetes",{"title":518,"path":519,"stem":520},"CI\u002FCD","\u002Fdeployment\u002Fci-cd","6.deployment\u002F3.ci-cd",{"title":522,"path":523,"stem":524},"CI\u002FCD Variables","\u002Fdeployment\u002Fvariables","6.deployment\u002F4.variables",{"title":526,"path":527,"stem":528},"Cloudflare","\u002Fdeployment\u002Fcloudflare","6.deployment\u002F5.cloudflare",{"title":530,"path":531,"stem":532},"Origin Protection","\u002Fdeployment\u002Forigin-protection","6.deployment\u002F5.origin-protection",{"title":534,"path":535,"stem":536},"Load Testing","\u002Fdeployment\u002Fload-testing","6.deployment\u002F6.load-testing",{"title":538,"path":539,"stem":540},"Performance Audit","\u002Fdeployment\u002Fperformance-audit","6.deployment\u002F6.performance-audit",{"title":542,"path":543,"stem":544},"Reading Lighthouse Scores","\u002Fdeployment\u002Freading-lighthouse-scores","6.deployment\u002F6.reading-lighthouse-scores",{"title":546,"path":547,"stem":548},"Faster Functional Tests","\u002Fdeployment\u002Ffaster-functional-tests","6.deployment\u002F7.faster-functional-tests",{"title":550,"path":551,"stem":552},"Troubleshooting","\u002Fdeployment\u002Ftroubleshooting","6.deployment\u002F7.troubleshooting",{"id":554,"title":542,"badge":555,"body":556,"description":1171,"extension":1172,"links":555,"meta":1173,"navigation":1174,"path":543,"seo":1175,"stem":544,"__hash__":1176},"docs\u002F6.deployment\u002F6.reading-lighthouse-scores.md",null,{"type":557,"value":558,"toc":1161},"minimark",[559,568,585,590,593,629,632,672,685,689,695,728,739,835,852,856,862,895,899,929,944,962,966,969,1041,1045,1090,1117,1121,1128,1134,1138,1157],[560,561,562,563,567],"p",{},"The ",[564,565,566],"a",{"href":539},"performance audit"," runs Lighthouse after a deploy. This page is about reading its score. A fast CWA page can still score badly on mobile, and the cause is usually a choice the project made, not the server.",[560,569,570,571,575,576,580,581,584],{},"One downstream site shows how much this varies. Its page ",[572,573,574],"code",{},"\u002Fgraphs\u002Ftop-line-findings"," is mostly text, paints in 282 ms without throttling, and is served from Cloudflare's edge cache. On mobile Lighthouse it scored ",[577,578,579],"strong",{},"60, 74, 68 and 96"," in four runs. With Google Tag Manager blocked it scored ",[577,582,583],{},"94–96",". These are that site's figures, not a benchmark, but the pattern is common.",[586,587,589],"h2",{"id":588},"mobile-scores-are-estimates","Mobile scores are estimates",[560,591,592],{},"Lighthouse has two ways to slow a page down to a mid-range phone on Slow 4G with a 4× CPU slowdown:",[594,595,596,616],"ul",{},[597,598,599,602,603,606,607,611,612,615],"li",{},[577,600,601],{},"Simulated throttling"," (",[572,604,605],{},"simulate",") loads the page at full speed, then ",[608,609,610],"em",{},"estimates"," the slow-phone timings from the requests it saw. PageSpeed Insights and Lighthouse's own defaults use it. A request that ",[608,613,614],{},"starts"," before the first paint adds to the estimate, even at low priority, and the result can swing between runs.",[597,617,618,602,621,624,625,628],{},[577,619,620],{},"Real throttling",[572,622,623],{},"devtools",") slows the network and CPU while the page loads, and measures what happens. The template's audit uses it by default (",[572,626,627],{},"CWA_CI_PERFORMANCE_AUDIT_THROTTLING","), because simulated throttling gave very different scores for the same page on shared CI runners.",[560,630,631],{},"So before chasing a number:",[633,634,635,641,666],"ol",{},[597,636,637,640],{},[577,638,639],{},"Judge on the median of several runs."," The audit runs each page 5 times and reports the median. A single PageSpeed Insights run proves little.",[597,642,643,646,647,650,651,654,655,658,659,654,662,665],{},[577,644,645],{},"Compare the observed timings with the estimated ones."," In a simulated report's JSON, ",[572,648,649],{},"audits.metrics.details.items[0]"," has ",[572,652,653],{},"observedFirstContentfulPaint"," and ",[572,656,657],{},"observedLargestContentfulPaint"," (unthrottled) next to ",[572,660,661],{},"firstContentfulPaint",[572,663,664],{},"largestContentfulPaint"," (estimated). A page that paints in a few hundred milliseconds but is estimated at several seconds is being penalised for what it requests early, not for being slow.",[597,667,668,671],{},[577,669,670],{},"Look at what loads before the first paint."," The report's network requests and \"Reduce unused JavaScript\" findings usually point straight at the cause.",[673,674,676],"callout",{"icon":675},"i-heroicons-photo",[560,677,678,681,682,684],{},[577,679,680],{},"Image placeholder:"," a Lighthouse mobile report for a CWA page, with the metrics section expanded and the JSON viewer open on ",[572,683,649],{},", highlighting the observed and estimated FCP side by side.",[586,686,688],{"id":687},"third-party-scripts","Third-party scripts",[560,690,691,694],{},[577,692,693],{},"Don't let analytics download before the first paint."," This was by far the biggest cost on the page above.",[560,696,697,700,701,704,705,708,709,712,713,716,717,719,720,723,724,727],{},[572,698,699],{},"@nuxt\u002Fscripts"," warms up a script's connection for you. Its ",[572,702,703],{},"warmupStrategy"," option defaults to ",[572,706,707],{},"'preload'"," when the script's trigger is ",[572,710,711],{},"'client'"," or ",[572,714,715],{},"'onNuxtReady'",", and a registry script such as Google Tag Manager uses ",[572,718,711],{}," unless you give it another trigger. A preload puts the script, for example ",[572,721,722],{},"gtm.js",", in the page's ",[572,725,726],{},"\u003Chead>",", so GTM and the gtag it loads, about 300 KiB on that site, land in the critical path.",[560,729,730,731,734,735,738],{},"Use ",[572,732,733],{},"'preconnect'"," (or ",[572,736,737],{},"false",") instead:",[740,741,746],"pre",{"className":742,"code":743,"language":744,"meta":745,"style":745},"language-ts shiki shiki-themes github-light github-dark material-theme-palenight has-focused","useScriptGoogleTagManager({\n  id: 'GTM-XXXXXXX',\n  scriptOptions: {\n    warmupStrategy: 'preconnect', \u002F\u002F [!code focus]\n  },\n})\n","ts","",[572,747,748,765,789,800,820,826],{"__ignoreMap":745},[749,750,753,757,761],"span",{"class":751,"line":752},"line",1,[749,754,756],{"class":755},"sKpYG","useScriptGoogleTagManager",[749,758,760],{"class":759},"sPB8G","(",[749,762,764],{"class":763},"sOvfz","{\n",[749,766,768,772,775,779,783,786],{"class":751,"line":767},2,[749,769,771],{"class":770},"sDHlG","  id",[749,773,774],{"class":763},":",[749,776,778],{"class":777},"seSrl"," '",[749,780,782],{"class":781},"sLL54","GTM-XXXXXXX",[749,784,785],{"class":777},"'",[749,787,788],{"class":763},",\n",[749,790,792,795,797],{"class":751,"line":791},3,[749,793,794],{"class":770},"  scriptOptions",[749,796,774],{"class":763},[749,798,799],{"class":763}," {\n",[749,801,805,808,810,812,815,817],{"class":802,"line":804},[751,803],"focused",4,[749,806,807],{"class":770},"    warmupStrategy",[749,809,774],{"class":763},[749,811,778],{"class":777},[749,813,814],{"class":781},"preconnect",[749,816,785],{"class":777},[749,818,819],{"class":763},",",[749,821,823],{"class":751,"line":822},5,[749,824,825],{"class":763},"  },\n",[749,827,829,832],{"class":751,"line":828},6,[749,830,831],{"class":763},"}",[749,833,834],{"class":759},")\n",[560,836,837,838,840,841,840,843,712,845,848,849,851],{},"The trigger and consent handling don't change; only the early download goes. On the page above this was worth about 25 points. The option takes ",[572,839,737],{},", ",[572,842,707],{},[572,844,733],{},[572,846,847],{},"'dns-prefetch'",", and a script with a custom trigger, such as a consent promise, gets no warm-up by default. This was checked against ",[572,850,699],{}," 1.3.12.",[586,853,855],{"id":854},"icons","Icons",[560,857,858,861],{},[577,859,860],{},"Ship small favicons and manifest icons."," The browser fetches the icon on a first visit at high priority, so a large one competes with the page. The downstream site's icons were 2000×2000 PNGs of about 300 KiB each. Resized to 192px and 512px and palette-reduced, they were about 2 KiB and 8 KiB.",[560,863,864,865,654,868,871,872,875,876,602,879,882,883,886,887,890,891,894],{},"The template already does this. Its PWA manifest lists ",[572,866,867],{},"pwa-192x192.png",[572,869,870],{},"pwa-512x512.png",", generated from ",[572,873,874],{},"app\u002Fpublic\u002Ficon.png"," by ",[572,877,878],{},"pnpm generate-assets",[572,880,881],{},"@vite-pwa\u002Fassets-generator","). Replace ",[572,884,885],{},"icon.png"," with your own logo, run the script again, and don't point the manifest or a ",[572,888,889],{},"\u003Clink rel=\"icon\">"," at the source image. See ",[564,892,893],{"href":497},"PWA",".",[586,896,898],{"id":897},"images","Images",[560,900,901,904,905,840,908,654,911,914,915,840,918,921,922,925,926,928],{},[577,902,903],{},"Upload PNG or JPEG; visitors get WebP."," From template 2.0.0-alpha.25, every image variant (",[572,906,907],{},"thumbnail",[572,909,910],{},"general",[572,912,913],{},"large",") is WebP whatever the upload's format (",[572,916,917],{},"format: webp",[572,919,920],{},"quality: 80"," in ",[572,923,924],{},"api\u002Fconfig\u002Fpackages\u002Fliip_imagine.yaml","). Editors don't need to convert logos or screenshots. On the downstream site, a 128 KB ",[572,927,910],{}," PNG logo became 41.5 KB.",[560,930,931,932,934,935,939,940,894],{},"A project with its own filter sets needs ",[572,933,917],{}," on each one. See ",[564,936,938],{"href":937},"\u002Fapi\u002Fcomponents\u002Fannotations\u002Fuploadable#webp-and-other-output-formats","WebP and other output formats",". Production deploys also create variants ahead of time, so a visitor's request doesn't have to; see ",[564,941,943],{"href":942},"\u002Fdeployment\u002Fci-cd#generating-image-variants-after-a-deploy","Generating image variants after a deploy",[560,945,946,947,654,950,953,954,957,958,894],{},"Render images with ",[572,948,949],{},"srcset",[572,951,952],{},"sizes",", as the template's ",[572,955,956],{},"Image.vue"," does, so a phone downloads the small variant. See ",[564,959,961],{"href":960},"\u002Fnuxt-module\u002Fcomponent-helpers\u002Fimages-and-uploads#responsive-images","Images & Uploads → Responsive images",[586,963,965],{"id":964},"what-the-stack-already-does","What the stack already does",[560,967,968],{},"So nobody repeats it:",[594,970,971,995,1008,1014,1024],{},[597,972,973,976,977,980,981,984,985,988,989,992,993,894],{},[577,974,975],{},"Compressed build assets."," ",[572,978,979],{},"\u002F_nuxt"," files are compressed with Brotli and gzip when the app is built, by the ",[572,982,983],{},"precompressBuildAssets"," helper in ",[572,986,987],{},"app\u002Fnuxt.config.ts"," (template 2.0.0-alpha.28; not Nitro's ",[572,990,991],{},"compressPublicAssets","). See ",[564,994,510],{"href":511},[597,996,997,1000,1001,1003,1004,894],{},[577,998,999],{},"Page caching."," Souin caches rendered pages and API responses at the origin (",[564,1002,500],{"href":501},"). Cloudflare can cache them at the edge too, if you choose ",[564,1005,1007],{"href":1006},"\u002Fdeployment\u002Fcloudflare#option-b-proxy-with-edge-caching","Option B",[597,1009,1010,1013],{},[577,1011,1012],{},"The editor loads lazily."," The template's TipTap editor is its own chunk, and its prefetch hint is removed from every page. Do the same for any heavy client library, such as a charting library, so it loads only on pages that use it.",[597,1015,1016,1019,1020,1023],{},[577,1017,1018],{},"Fonts."," Nuxt UI registers ",[572,1021,1022],{},"@nuxt\u002Ffonts",", which self-hosts the fonts your CSS uses.",[597,1025,1026,1029,1030,1033,1034,1040],{},[577,1027,1028],{},"Admin code stays out of visitors' pages."," From ",[572,1031,1032],{},"@cwa\u002Fnuxt"," 2.0.0-alpha.11 (",[564,1035,1039],{"href":1036,"rel":1037},"https:\u002F\u002Fgithub.com\u002Fcomponents-web-app\u002Fcwa-nuxt-module\u002Fissues\u002F382",[1038],"nofollow","cwa-nuxt-module#382","), the Mercure client loads after hydration, and the confirm dialog, the orphan report and the page cache warm reader load on first use. Anonymous visitors' pages no longer preload the admin's component manager or the empty-position placeholder. Live updates for visitors are unchanged.",[586,1042,1044],{"id":1043},"what-is-still-the-frameworks-cost","What is still the framework's cost",[594,1046,1047,1064],{},[597,1048,1049,976,1052,1054,1055,1057,1058,1063],{},[577,1050,1051],{},"The module's core classes are still in the visitor entry.",[572,1053,453],{},", its stack manager and reorders, the resources manager, ",[572,1056,283],{}," and the HTTP cache code are built into every visitor's entry. Loading the stack manager and reorders only for admins would save about 4 KB gzip per visitor, and was ",[564,1059,1062],{"href":1060,"rel":1061},"https:\u002F\u002Fgithub.com\u002Fcomponents-web-app\u002Fcwa-nuxt-module\u002Fissues\u002F383",[1038],"declined"," as not worth a breaking change. The module's build checks the entry and an anonymous page's preloads against a size budget, so it shouldn't grow unnoticed.",[597,1065,1066,1075,1076,1079,1080,1085,1086,1089],{},[577,1067,1068,1071,1072,894],{},[572,1069,1070],{},"\u003CUApp>"," in the template's ",[572,1073,1074],{},"app\u002Fapp\u002Fapp.vue"," Nuxt UI's wrapper costs every page about 162 KB minified, 44 KB brotli, of JavaScript, measured by an A\u002FB production build: its toaster, Reka UI's toast, tooltip and overlay providers, and ",[572,1077,1078],{},"tailwind-variants",". That's about a quarter of what every page loads. The template keeps it on purpose (",[564,1081,1084],{"href":1082,"rel":1083},"https:\u002F\u002Fgithub.com\u002Fcomponents-web-app\u002Fcomponents-web-app\u002Fissues\u002F150",[1038],"components-web-app#150","), because visitor toasts such as form feedback, tooltips and modals need it. ",[572,1087,1088],{},":toaster=\"null\""," or a lazily loaded wrapper saves nothing, because the code is still on the hydration path.",[673,1091,1093],{"icon":1092},"i-heroicons-light-bulb",[560,1094,1095,1100,1101,1103,1104,840,1107,712,1110,1113,1114,1116],{},[577,1096,1097,1098],{},"A site that never shows visitors a toast, tooltip or overlay can remove ",[572,1099,1070],{}," from its own ",[572,1102,1074],{}," and save those 44 KB. In a check without it, visitor pages, Nuxt UI form selects, the admin and edit mode all worked unchanged. If the site later uses ",[572,1105,1106],{},"useToast()",[572,1108,1109],{},"UTooltip",[572,1111,1112],{},"useOverlay",", add ",[572,1115,1070],{}," back.",[586,1118,1120],{"id":1119},"a-target-to-aim-for","A target to aim for",[560,1122,1123,1124,1127],{},"A CWA page with no heavy third-party scripts should score ",[577,1125,1126],{},"90 or more on mobile, as the median of 5 runs",". The downstream page above scored 94–96 once its tag manager stopped downloading early. If yours scores well below that, check the sections above in order: third-party scripts, icons, images, then your own components.",[560,1129,1130,1131,894],{},"The score is about one visitor on a slow phone. For how the server holds up under many visitors, and whether pages are served from the cache, run a ",[564,1132,1133],{"href":535},"load test",[586,1135,1137],{"id":1136},"next-steps","Next steps",[594,1139,1140,1145,1152],{},[597,1141,1142,1144],{},[564,1143,538],{"href":539},": running the audit, its budgets and its reports.",[597,1146,1147,1151],{},[564,1148,1150],{"href":1149},"\u002Fdeployment\u002Fci-cd#auditing-performance-after-a-deploy","CI\u002FCD → Auditing performance after a deploy",": where the job sits in the pipeline.",[597,1153,1154,1156],{},[564,1155,534],{"href":535},": how many visitors the site can serve.",[1158,1159,1160],"style",{},"html pre.shiki code .sKpYG, html code.shiki .sKpYG{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#82AAFF}html pre.shiki code .sPB8G, html code.shiki .sPB8G{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#BABED8}html pre.shiki code .sOvfz, html code.shiki .sOvfz{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#89DDFF}html pre.shiki code .sDHlG, html code.shiki .sDHlG{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#F07178}html pre.shiki code .seSrl, html code.shiki .seSrl{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#89DDFF}html pre.shiki code .sLL54, html code.shiki .sLL54{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#C3E88D}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);}",{"title":745,"searchDepth":767,"depth":767,"links":1162},[1163,1164,1165,1166,1167,1168,1169,1170],{"id":588,"depth":767,"text":589},{"id":687,"depth":767,"text":688},{"id":854,"depth":767,"text":855},{"id":897,"depth":767,"text":898},{"id":964,"depth":767,"text":965},{"id":1043,"depth":767,"text":1044},{"id":1119,"depth":767,"text":1120},{"id":1136,"depth":767,"text":1137},"Why a fast CWA page can score anywhere from 60 to 96 on mobile Lighthouse, how to read the result, and what a project should check first — third-party scripts, icons, images and its own front-end bundle.","md",{},true,{"title":542,"description":1171},"AYWf9u0_Z5YHvVtpUgoiOjp4nZ2Lf3Z9N3mBZ5ZUeZk",[1178,1180],{"title":538,"path":539,"stem":540,"description":1179,"children":-1},"Run Lighthouse CI against a deployed CWA site to see what a visitor experiences — LCP, CLS, TBT and page weight against budgets — without ever failing a deploy.",{"title":546,"path":547,"stem":548,"description":1181,"children":-1},"When a project's functional test suite slows CI down — measure where the time goes, reset the database without rebuilding the schema, and shard the job by test.",1791855275387]