[{"data":1,"prerenderedAt":2233},["ShallowReactive",2],{"navigation":3,"\u002Fdeployment\u002Ftroubleshooting":553,"\u002Fdeployment\u002Ftroubleshooting-surround":2230},[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":550,"badge":555,"body":556,"description":2224,"extension":2225,"links":555,"meta":2226,"navigation":2227,"path":551,"seo":2228,"stem":552,"__hash__":2229},"docs\u002F6.deployment\u002F7.troubleshooting.md",null,{"type":557,"value":558,"toc":2158},"minimark",[559,563,572,577,587,632,660,667,671,683,728,743,772,783,826,851,861,869,884,917,925,943,985,1007,1011,1030,1114,1128,1132,1143,1147,1191,1198,1206,1237,1263,1270,1291,1326,1330,1359,1370,1374,1421,1428,1489,1493,1503,1516,1527,1531,1538,1542,1564,1613,1619,1625,1657,1661,1717,1727,1731,1738,1757,1761,1765,1772,1776,1783,1790,1794,1797,1883,1887,1894,1921,1932,1939,1961,1968,1983,1989,1999,2003,2022,2025,2033,2044,2048,2056,2060,2068,2076,2086,2090,2097,2105,2112,2115,2154],[560,561,562],"p",{},"Each problem below has its own heading, named after what you see: the symptom or the error text. Search the page for your error message. Each entry links back to the reference section that explains the part involved.",[560,564,565,566,571],{},"Troubleshooting for other parts of CWA is listed at the end, in ",[567,568,570],"a",{"href":569},"#elsewhere-in-the-docs","Elsewhere in the docs",".",[573,574,576],"h2",{"id":575},"local-development","Local development",[578,579,581,582,586],"h3",{"id":580},"every-page-returns-502-or-503-after-you-run-pnpm-install-on-the-host","Every page returns 502 or 503 after you run ",[583,584,585],"code",{},"pnpm install"," on the host",[560,588,589,590,593,594,597,598,601,602,605,606,608,609,612,613,615,616,619,620,623,624,627,628,631],{},"In development, ",[583,591,592],{},"compose.override.yaml"," bind-mounts ",[583,595,596],{},"app\u002F"," and ",[583,599,600],{},"app\u002Fnode_modules"," into the ",[583,603,604],{},"app"," container, and that container runs ",[583,607,585],{}," and then ",[583,610,611],{},"pnpm dev",". A ",[583,614,585],{}," on your machine, such as for a dependency bump, rewrites the shared ",[583,617,618],{},"node_modules"," while the container's dev server is still running from it. The dev server then crash-loops with errors like ",[583,621,622],{},"Cannot find module 'typescript'",", a missing ",[583,625,626],{},"@nuxt\u002Fcli\u002Fdist\u002Fdev\u002Findex.mjs"," or ",[583,629,630],{},"Cannot resolve module \"@nuxt\u002Fkit\"",", and Caddy returns 502 or 503 for every page. Restart the container so it reinstalls from inside:",[633,634,639],"pre",{"className":635,"code":636,"language":637,"meta":638,"style":638},"language-bash shiki shiki-themes github-light github-dark material-theme-palenight","docker compose restart app\n","bash","",[583,640,641],{"__ignoreMap":638},[642,643,646,650,654,657],"span",{"class":644,"line":645},"line",1,[642,647,649],{"class":648},"sRCss","docker",[642,651,653],{"class":652},"sLL54"," compose",[642,655,656],{"class":652}," restart",[642,658,659],{"class":652}," app\n",[560,661,662,663,571],{},"When you check its logs afterwards, only look at lines after the restart. The crash from before it is still in the log and looks like a new failure. See ",[567,664,666],{"href":665},"\u002Fdeployment\u002Fdocker#development-workflow","Docker → Development Workflow",[578,668,670],{"id":669},"every-dev-page-takes-about-30-seconds","Every dev page takes about 30 seconds",[560,672,673,674,678,679,682],{},"This is almost always ",[675,676,677],"strong",{},"missing PostgreSQL statistics",", not slow I\u002FO. CWA's components use Doctrine ",[583,680,681],{},"JOINED"," inheritance, so loading a page emits a wide multi-table join. The component subclass tables hold only a handful of rows each — permanently below the threshold that triggers PostgreSQL's autoanalyze — so those tables are never analysed, the planner has no statistics, and it wildly over-estimates the join and throws parallel workers at a query that returns almost nothing. Fix it by analysing the database once:",[633,684,686],{"className":635,"code":685,"language":637,"meta":638,"style":638},"docker compose exec database psql -U app -d app -c 'ANALYZE;'\n",[583,687,688],{"__ignoreMap":638},[642,689,690,692,694,697,700,703,707,710,713,715,718,722,725],{"class":644,"line":645},[642,691,649],{"class":648},[642,693,653],{"class":652},[642,695,696],{"class":652}," exec",[642,698,699],{"class":652}," database",[642,701,702],{"class":652}," psql",[642,704,706],{"class":705},"szhYu"," -U",[642,708,709],{"class":652}," app",[642,711,712],{"class":705}," -d",[642,714,709],{"class":652},[642,716,717],{"class":705}," -c",[642,719,721],{"class":720},"seSrl"," '",[642,723,724],{"class":652},"ANALYZE;",[642,726,727],{"class":720},"'\n",[560,729,730,731,734,735,738,739,571],{},"The current template does this automatically in the ",[583,732,733],{},"php"," entrypoint on every ",[583,736,737],{},"compose up",", so fresh projects don't hit it — but a project scaffolded before that change, or a new small fixture table, can still trigger it. See ",[567,740,742],{"href":741},"\u002Fdeployment\u002Fdocker#starting-the-stack","Docker → Starting the Stack",[744,745,748],"callout",{"color":746,"icon":747},"warning","i-heroicons-exclamation-triangle",[560,749,750,751,754,755,759,760,763,764,767,768,771],{},"This is easy to misdiagnose because it's a pure query-planner problem with ",[675,752,753],{},"no I\u002FO",". A near-idle database, tiny tables, and a 99% cache-hit ratio are all true ",[756,757,758],"em",{},"and completely consistent with it"," — none of them rule the database out. If dev is mysteriously slow, go straight to ",[583,761,762],{},"EXPLAIN (ANALYZE, BUFFERS)"," and check ",[583,765,766],{},"SELECT relname, reltuples FROM pg_class"," for tables reporting ",[583,769,770],{},"-1"," (never analysed).",[578,773,775,778,779,782],{"id":774},"composer-update-fails-with-a-rawgithubusercontentcom-404",[583,776,777],{},"composer update"," fails with a ",[583,780,781],{},"raw.githubusercontent.com"," 404",[560,784,785,786,789,790,793,794,797,798,800,801,804,805,808,809,812,813,817,818,821,822,825],{},"If Composer dies downloading a Symfony Flex recipes index with an HTTP 404, the cause is usually a ",[675,787,788],{},"stale GitHub token"," in the container's ",[583,791,792],{},"\u002Fconfig\u002Fcomposer\u002Fauth.json",", not a network or GitHub outage. GitHub returns ",[675,795,796],{},"404, not 401",", for a bad token on ",[583,799,781],{}," — and a plain ",[583,802,803],{},"curl"," of the same URL returns 200 because it sends no token, which misleadingly \"proves\" the network is fine. The ",[583,806,807],{},"\u002Fconfig"," volume (",[583,810,811],{},"caddy_config",", see ",[567,814,816],{"href":815},"\u002Fdeployment\u002Fdocker#volumes","Docker → Volumes",") persists across ",[583,819,820],{},"compose down","\u002F",[583,823,824],{},"up",", so the bad token survives restarts. Clear it:",[633,827,829],{"className":635,"code":828,"language":637,"meta":638,"style":638},"docker compose exec php rm -f \u002Fconfig\u002Fcomposer\u002Fauth.json\n",[583,830,831],{"__ignoreMap":638},[642,832,833,835,837,839,842,845,848],{"class":644,"line":645},[642,834,649],{"class":648},[642,836,653],{"class":652},[642,838,696],{"class":652},[642,840,841],{"class":652}," php",[642,843,844],{"class":652}," rm",[642,846,847],{"class":705}," -f",[642,849,850],{"class":652}," \u002Fconfig\u002Fcomposer\u002Fauth.json\n",[560,852,853,854,856,857,860],{},"Then re-run ",[583,855,777],{}," (or set a valid ",[583,858,859],{},"GITHUB_TOKEN",").",[578,862,864,865,868],{"id":863},"composer-or-php-reports-a-missing-ffi-extension","Composer or php reports a missing ",[583,866,867],{},"ffi"," extension",[560,870,871,872,875,876,880,881,883],{},"The project's Composer dependencies require ",[583,873,874],{},"ext-ffi"," for the ",[567,877,879],{"href":878},"\u002Fdeployment\u002Fdocker#image-processing","libvips imagine driver",". An image built before you took that change has no libvips or ",[583,882,867],{},". Rebuild the dev php image:",[633,885,887],{"className":635,"code":886,"language":637,"meta":638,"style":638},"docker compose build php && docker compose up -d php\n",[583,888,889],{"__ignoreMap":638},[642,890,891,893,895,898,900,904,907,909,912,914],{"class":644,"line":645},[642,892,649],{"class":648},[642,894,653],{"class":652},[642,896,897],{"class":652}," build",[642,899,841],{"class":652},[642,901,903],{"class":902},"sOvfz"," &&",[642,905,906],{"class":648}," docker",[642,908,653],{"class":652},[642,910,911],{"class":652}," up",[642,913,712],{"class":705},[642,915,916],{"class":652}," php\n",[578,918,920,921,924],{"id":919},"caddy-reports-unexpected-eof-after-you-edit-the-caddyfile","Caddy reports ",[583,922,923],{},"unexpected EOF"," after you edit the Caddyfile",[560,926,927,928,930,931,934,935,938,939,942],{},"If Caddy fails with ",[583,929,923],{}," while ",[583,932,933],{},"api\u002Ffrankenphp\u002FCaddyfile"," looks valid on disk, it's a stale-config issue, not a syntax error. On macOS\u002FWindows (Docker Desktop), a ",[675,936,937],{},"single-file"," bind mount caches the file's size, so an edit that makes the file ",[756,940,941],{},"longer"," — what most editors' atomic save does — is served to the container truncated. Edits that shrink or keep the length work, which makes it look random. Confirm by comparing byte counts:",[633,944,946],{"className":635,"code":945,"language":637,"meta":638,"style":638},"wc -c \u003C api\u002Ffrankenphp\u002FCaddyfile\ndocker compose exec php sh -c 'wc -c \u003C \u002Fapp\u002Ffrankenphp\u002FCaddyfile'\n",[583,947,948,962],{"__ignoreMap":638},[642,949,950,953,955,959],{"class":644,"line":645},[642,951,952],{"class":648},"wc",[642,954,717],{"class":705},[642,956,958],{"class":957},"sVlFx"," \u003C",[642,960,961],{"class":652}," api\u002Ffrankenphp\u002FCaddyfile\n",[642,963,965,967,969,971,973,976,978,980,983],{"class":644,"line":964},2,[642,966,649],{"class":648},[642,968,653],{"class":652},[642,970,696],{"class":652},[642,972,841],{"class":652},[642,974,975],{"class":652}," sh",[642,977,717],{"class":705},[642,979,721],{"class":720},[642,981,982],{"class":652},"wc -c \u003C \u002Fapp\u002Ffrankenphp\u002FCaddyfile",[642,984,727],{"class":720},[560,986,987,988,991,992,995,996,999,1000,1003,1004,1006],{},"If they differ, recreate the container (",[583,989,990],{},"restart"," isn't enough): ",[583,993,994],{},"docker compose up -d --force-recreate php",". The CWA template avoids this by reading dev config through the ",[583,997,998],{},".\u002Fapi"," ",[675,1001,1002],{},"directory"," mount rather than mounting single files — you'll only hit it if you reintroduce a single-file mount in ",[583,1005,592],{},". Production is unaffected: the image bakes the Caddyfile in.",[578,1008,1010],{"id":1009},"the-dev-server-loads-but-nothing-on-the-page-responds","The dev server loads, but nothing on the page responds",[560,1012,1013,1014,1017,1018,1021,1022,1025,1026,1029],{},"On Nuxt 4.5, if pages render but never hydrate, so buttons do nothing and the login form reloads the page, check the browser console for a ",[583,1015,1016],{},"SyntaxError"," about ",[583,1019,1020],{},"__unhead_devtoolsPlugin"," being declared twice. ",[583,1023,1024],{},"@unhead\u002Fbundler"," 3.4.1 registers its DevTools runtime import once for each of Nuxt's client and server Vite servers. Turn off unhead's own DevTools panel in ",[583,1027,1028],{},"nuxt.config.ts",":",[633,1031,1035],{"className":1032,"code":1033,"language":1034,"meta":638,"style":638},"language-ts shiki shiki-themes github-light github-dark material-theme-palenight","export default defineNuxtConfig({\n  unhead: {\n    vite: {\n      devtools: false,\n    },\n  },\n})\n","ts",[583,1036,1037,1057,1068,1078,1093,1099,1105],{"__ignoreMap":638},[642,1038,1039,1043,1046,1050,1054],{"class":644,"line":645},[642,1040,1042],{"class":1041},"sm4w6","export",[642,1044,1045],{"class":1041}," default",[642,1047,1049],{"class":1048},"sKpYG"," defineNuxtConfig",[642,1051,1053],{"class":1052},"sPB8G","(",[642,1055,1056],{"class":902},"{\n",[642,1058,1059,1063,1065],{"class":644,"line":964},[642,1060,1062],{"class":1061},"sDHlG","  unhead",[642,1064,1029],{"class":902},[642,1066,1067],{"class":902}," {\n",[642,1069,1071,1074,1076],{"class":644,"line":1070},3,[642,1072,1073],{"class":1061},"    vite",[642,1075,1029],{"class":902},[642,1077,1067],{"class":902},[642,1079,1081,1084,1086,1090],{"class":644,"line":1080},4,[642,1082,1083],{"class":1061},"      devtools",[642,1085,1029],{"class":902},[642,1087,1089],{"class":1088},"swWMF"," false",[642,1091,1092],{"class":902},",\n",[642,1094,1096],{"class":644,"line":1095},5,[642,1097,1098],{"class":902},"    },\n",[642,1100,1102],{"class":644,"line":1101},6,[642,1103,1104],{"class":902},"  },\n",[642,1106,1108,1111],{"class":644,"line":1107},7,[642,1109,1110],{"class":902},"}",[642,1112,1113],{"class":1052},")\n",[560,1115,1116,1117,1120,1121,1127],{},"This only affects development. Nuxt DevTools and ",[583,1118,1119],{},"useSeoMeta"," still work, and the production build is unchanged. The template sets this (",[567,1122,1126],{"href":1123,"rel":1124},"https:\u002F\u002Fgithub.com\u002Fcomponents-web-app\u002Fcomponents-web-app\u002Fissues\u002F95",[1125],"nofollow","#95","). Remove it once an unhead release fixes the duplicate.",[578,1129,1131],{"id":1130},"the-rate-limit-never-triggers-on-the-dev-stack","The rate limit never triggers on the dev stack",[560,1133,1134,1135,1138,1139,571],{},"The rate limit never applies to private addresses, so your own browser may never trigger it locally. To try it, send an ",[583,1136,1137],{},"X-Forwarded-For"," header with a public address: the request comes from a trusted private address, so Caddy believes the header. See ",[567,1140,1142],{"href":1141},"\u002Fdeployment\u002Fdocker#origin-protection-settings","Docker → Origin protection settings",[573,1144,1146],{"id":1145},"caddy-and-souin","Caddy and Souin",[560,1148,1149,999,1155,1158,1159,1162,1163,1166,1167,1170,1171,1174,1175,1178,1179,1182,1183,1190],{},[675,1150,1151,1152,571],{},"Check every Caddyfile change with ",[583,1153,1154],{},"bin\u002Ftest\u002Fcaddy-validate.sh",[583,1156,1157],{},"frankenphp adapt"," only parses the Caddyfile, so errors raised while Caddy loads its modules, like several below, pass it. The script runs ",[583,1160,1161],{},"frankenphp validate",", which loads every module, for both ",[583,1164,1165],{},"SERVER_NAME"," shapes the template uses: Helm's ",[583,1168,1169],{},":80"," and compose's several ports. Run it locally with ",[583,1172,1173],{},"docker compose exec -T php sh -s \u003C bin\u002Ftest\u002Fcaddy-validate.sh",". It checks the Caddyfile at ",[583,1176,1177],{},"\u002Fetc\u002Fcaddy\u002FCaddyfile",", which is the copy built into the image, so rebuild php after editing. CI runs it too: from template ",[583,1180,1181],{},"2.0.0-alpha.6"," (",[567,1184,1187],{"href":1185,"rel":1186},"https:\u002F\u002Fgithub.com\u002Fcomponents-web-app\u002Fcomponents-web-app\u002Fcommit\u002F843082a54c663a44bc6267314f491647ec94275e",[1125],[583,1188,1189],{},"843082a","), the unit-tests job does.",[560,1192,1193,1194,571],{},"How the template's Caddyfile caches is in ",[567,1195,1197],{"href":1196},"\u002Fdeployment\u002Fdocker#the-http-cache-in-caddy","Docker → The HTTP Cache in Caddy",[578,1199,1201,1202,1205],{"id":1200},"php-wont-start-with-unrecognized-directive-after-you-copy-the-templates-caddyfile","php won't start with ",[583,1203,1204],{},"unrecognized directive"," after you copy the template's Caddyfile",[560,1207,1208,1209,1182,1212,1215,1216,1219,1220,1224,1225,1228,1229,1232,1233,1236],{},"From template ",[583,1210,1211],{},"2.0.0-alpha.4",[583,1213,1214],{},"4cbe05a","), the Caddyfile uses two Caddy modules that older php images don't have: ",[583,1217,1218],{},"query_allowlist",", the template's own handler for the ",[567,1221,1223],{"href":1222},"\u002Fdeployment\u002Forigin-protection#query-parameters-on-pages","query allowlist",", and ",[583,1226,1227],{},"rate_limit",", from ",[583,1230,1231],{},"mholt\u002Fcaddy-ratelimit",". An old image refuses the file. In dev, the ",[583,1234,1235],{},"--watch"," reload keeps the old config running, and the next restart crash-loops. Rebuild the image, or let CI build it:",[633,1238,1239],{"className":635,"code":886,"language":637,"meta":638,"style":638},[583,1240,1241],{"__ignoreMap":638},[642,1242,1243,1245,1247,1249,1251,1253,1255,1257,1259,1261],{"class":644,"line":645},[642,1244,649],{"class":648},[642,1246,653],{"class":652},[642,1248,897],{"class":652},[642,1250,841],{"class":652},[642,1252,903],{"class":902},[642,1254,906],{"class":648},[642,1256,653],{"class":652},[642,1258,911],{"class":652},[642,1260,712],{"class":705},[642,1262,916],{"class":652},[578,1264,1266,1267],{"id":1265},"php-keeps-restarting-with-token-recognition-error-at","php keeps restarting with ",[583,1268,1269],{},"token recognition error at: '#'",[560,1271,1272,1273,1276,1277,1279,1280,1283,1284,1286,1287,1290],{},"Comments inside the ",[583,1274,1275],{},"@use_cache"," expression break Caddy, and ",[583,1278,1157],{}," does not warn you. The text between the backticks is a CEL expression, not Caddyfile syntax. CEL has no comments. A ",[583,1281,1282],{},"#"," line inside the backticks is a parse error, but ",[583,1285,1157],{}," does not check the text inside the backticks, so it reports no problem. The error only appears at runtime, and the php container keeps restarting. Put comments above the block. After changing it, run ",[583,1288,1289],{},"adapt",", then recreate the container and check that it becomes healthy:",[633,1292,1294],{"className":635,"code":1293,"language":637,"meta":638,"style":638},"docker compose up -d --force-recreate php\ndocker compose ps php      # should reach \"healthy\", not \"Restarting\"\n",[583,1295,1296,1311],{"__ignoreMap":638},[642,1297,1298,1300,1302,1304,1306,1309],{"class":644,"line":645},[642,1299,649],{"class":648},[642,1301,653],{"class":652},[642,1303,911],{"class":652},[642,1305,712],{"class":705},[642,1307,1308],{"class":705}," --force-recreate",[642,1310,916],{"class":652},[642,1312,1313,1315,1317,1320,1322],{"class":644,"line":964},[642,1314,649],{"class":648},[642,1316,653],{"class":652},[642,1318,1319],{"class":652}," ps",[642,1321,841],{"class":652},[642,1323,1325],{"class":1324},"sTBSN","      # should reach \"healthy\", not \"Restarting\"\n",[578,1327,1329],{"id":1328},"a-cache-matcher-never-matches-when-a-cookie-is-absent","A cache matcher never matches when a cookie is absent",[560,1331,1332,1333,1335,1336,1342,1343,1346,1347,1350,1351,1354,1355,1358],{},"If you edit the Souin ",[583,1334,1275],{}," expression in the Caddyfile, note that an ",[675,1337,1338,1339],{},"absent cookie does not equal ",[583,1340,1341],{},"\"\""," in Caddy matchers — unlike a missing ",[756,1344,1345],{},"header",", which does. A clause like ",[583,1348,1349],{},"{http.request.cookie.api_component} == \"\""," only matches when the cookie is ",[756,1352,1353],{},"present but empty",", so requests with no cookie at all (SSR, curl, health checks) silently miss the cache. Match on the ",[583,1356,1357],{},"Cookie"," header instead, so an absent or empty cookie both count as \"not authenticated\":",[633,1360,1364],{"className":1361,"code":1362,"language":1363,"meta":638,"style":638},"language-caddyfile shiki shiki-themes github-light github-dark material-theme-palenight","!{http.request.header.Cookie}.matches(\"api_component=[^;]+\")\n","caddyfile",[583,1365,1366],{"__ignoreMap":638},[642,1367,1368],{"class":644,"line":645},[642,1369,1362],{},[578,1371,1373],{"id":1372},"nothing-is-cached-after-a-full-flush","Nothing is cached after a full flush",[560,1375,1376,1377,627,1380,1383,1384,1387,1388,1391,1392,1395,1396,1399,1400,1403,1404,1387,1409,1416,1417,1420],{},"The php log shows ",[583,1378,1379],{},"BADGER-INSERTION-ERROR",[583,1381,1382],{},"DB Closed",". Unpatched Souin v1.7.9 closes the badger and nuts storages on a full flush, and they stay closed until php restarts. A full flush is ",[675,1385,1386],{},"Purge all cached data",", ",[583,1389,1390],{},"purge-http-cache",", every fixture load, and every deploy with ",[583,1393,1394],{},"provider cloudflare",". The default in-memory otter storage is not affected. Template ",[583,1397,1398],{},"2.0.0-alpha.7"," adds ",[583,1401,1402],{},"v1.7.9-flush-no-close.patch",", which empties the store and leaves it open (",[567,1405,1408],{"href":1406,"rel":1407},"https:\u002F\u002Fgithub.com\u002Fcomponents-web-app\u002Fcomponents-web-app\u002Fissues\u002F114",[1125],"#114",[567,1410,1413],{"href":1411,"rel":1412},"https:\u002F\u002Fgithub.com\u002Fcomponents-web-app\u002Fcomponents-web-app\u002Fcommit\u002F8ebf5e994687014d0496da33a209eafd2137cd93",[1125],[583,1414,1415],{},"8ebf5e9","). If you use badger or nuts, take the patch and the matching lines in ",[583,1418,1419],{},"api\u002FDockerfile",", then rebuild the API image. Until then, restart php after each full flush.",[578,1422,1424,1425],{"id":1423},"requests-that-waited-on-a-failed-render-get-an-empty-200","Requests that waited on a failed render get an empty ",[583,1426,1427],{},"200",[560,1429,1430,1431,1387,1434,1387,1437,627,1440,1443,1444,1446,1447,1450,1451,1399,1454,1457,1458,1387,1463,1470,1471,1474,1475,1478,1479,597,1482,1485,1486,1488],{},"Souin sends only one request upstream for a URL that isn't cached, and the others for that URL wait for its response. In unpatched Souin v1.7.9, when that response was a ",[583,1432,1433],{},"500",[583,1435,1436],{},"502",[583,1438,1439],{},"503",[583,1441,1442],{},"504",", the waiting requests got a ",[583,1445,1427],{}," with an empty body and no ",[583,1448,1449],{},"Cache-Status"," header, and an SSR render could cache a broken page. Template ",[583,1452,1453],{},"2.0.0-alpha.20",[583,1455,1456],{},"v1.7.9-singleflight-5xx.patch",", so they get the same error (",[567,1459,1462],{"href":1460,"rel":1461},"https:\u002F\u002Fgithub.com\u002Fcomponents-web-app\u002Fcomponents-web-app\u002Fissues\u002F137",[1125],"#137",[567,1464,1467],{"href":1465,"rel":1466},"https:\u002F\u002Fgithub.com\u002Fcomponents-web-app\u002Fcomponents-web-app\u002Fcommit\u002F6df1b15050970bbc45e8348d10d0a9787477365c",[1125],[583,1468,1469],{},"6df1b15","). A ",[583,1472,1473],{},"5xx"," that is private or sets a cookie isn't shared: each waiting request goes upstream itself. ",[583,1476,1477],{},"bin\u002Ftest\u002Fsouin-coalesced-5xx.sh",", in the unit-tests job, fails on an unpatched binary. To take it, copy the patch, add its ",[583,1480,1481],{},"COPY",[583,1483,1484],{},"patch"," lines to ",[583,1487,1419],{}," straight after the singleflight fix's, and rebuild the API image.",[578,1490,1492],{"id":1491},"php-is-oomkilled-while-serving-a-large-file","php is OOMKilled while serving a large file",[560,1494,1495,1496,1498,1499,571],{},"Souin reads the whole body of a cacheable response into memory before it decides anything, so a large file served through the cache can take php past its memory limit. Keep large files out of ",[583,1497,1275],{},": see ",[567,1500,1502],{"href":1501},"\u002Fdeployment\u002Fdocker#what-the-page-cache-stores","Docker → What the page cache stores",[578,1504,1506,627,1509,1512,1513],{"id":1505},"purge-or-ban-sent-to-the-site-returns-405",[583,1507,1508],{},"PURGE",[583,1510,1511],{},"BAN"," sent to the site returns ",[583,1514,1515],{},"405",[560,1517,1518,1519,571],{},"That's intended: they never purged anything. See ",[567,1520,1522,1523,597,1525],{"href":1521},"\u002Fdeployment\u002Fdocker#purge-and-ban-sent-to-the-site-return-405","Docker → ",[583,1524,1508],{},[583,1526,1511],{},[573,1528,1530],{"id":1529},"mercure","Mercure",[560,1532,1533,1534,571],{},"The module's own checks for live updates are in ",[567,1535,1537],{"href":1536},"\u002Fnuxt-module\u002Fcomponent-helpers\u002Freal-time-updates#troubleshooting","Real-time Updates → Troubleshooting",[578,1539,1541],{"id":1540},"php-wont-start-after-rebuilding-with-mercure-10","php won't start after rebuilding with Mercure 1.0",[560,1543,1544,1545,597,1548,1551,1552,1555,1556,1559,1560,1563],{},"FrankenPHP 1.13 ships Mercure 1.0, which treats unknown directives as errors and has removed ",[583,1546,1547],{},"demo",[583,1549,1550],{},"ui",". If ",[583,1553,1554],{},"MERCURE_EXTRA_DIRECTIVES"," sets either, use ",[583,1557,1558],{},"debugger"," instead, in development only. The template's Caddyfile uses an ",[583,1561,1562],{},"issuer"," block, which a 0.x Mercure doesn't know, so rebuild the API image before you restart php with the new Caddyfile. Two errors mean the Caddyfile and the binary don't match:",[1565,1566,1567,1588],"ul",{},[1568,1569,1570,1573,1574,597,1577,1580,1581,1583,1584,571],"li",{},[583,1571,1572],{},"the \"publisher_jwt\", \"subscriber_jwt\", … directives work only in compatibility mode",": the old top-level ",[583,1575,1576],{},"publisher_jwt",[583,1578,1579],{},"subscriber_jwt"," directives are still there. Move the keys into an ",[583,1582,1562],{}," block, as described in ",[567,1585,1587],{"href":1586},"\u002Fapi\u002Freal-time#hub-caddyfile","Hub Caddyfile",[1568,1589,1590,1593,1594,1597,1598,597,1600,1602,1603,597,1606,1609,1610,1612],{},[583,1591,1592],{},"an issuer identifier is required in modern mode",": the Caddyfile is still set up for compatibility mode (",[583,1595,1596],{},"protocol_version_compatibility"," with top-level ",[583,1599,1576],{},[583,1601,1579],{},"), but the binary was built without the ",[583,1604,1605],{},"deprecated_topic",[583,1607,1608],{},"deprecated_claim"," tags, so the hub runs in modern mode anyway. Remove the directive and move the keys into an ",[583,1611,1562],{}," block.",[560,1614,1615,1618],{},[583,1616,1617],{},"caddy adapt"," reports neither error. Only a running hub does, so check php's logs after it starts.",[578,1620,1201,1622],{"id":1621},"php-wont-start-with-only-one-unnamed-mercure-hub-is-allowed-per-configuration",[583,1623,1624],{},"only one unnamed Mercure hub is allowed per configuration",[560,1626,1627,1628,1630,1631,1634,1635,1637,1638,1641,1642,1644,1645,1648,1649,1654,1655,571],{},"An API image built with Mercure 1.0.3 or later refuses the compose stack's Caddyfile unless the ",[583,1629,1529],{}," block has a ",[583,1632,1633],{},"name",". Compose's ",[583,1636,1165],{}," has several ports, so Caddy runs one server per port, each with its own hub. The healthcheck never passes, and the error only shows in the php container's log. Add ",[583,1639,1640],{},"name cwa"," to the ",[583,1643,1529],{}," block, as template ",[583,1646,1647],{},"2.0.0-alpha.5"," does (",[567,1650,1653],{"href":1651,"rel":1652},"https:\u002F\u002Fgithub.com\u002Fcomponents-web-app\u002Fcomponents-web-app\u002Fissues\u002F113",[1125],"#113","), then recreate php. See ",[567,1656,1587],{"href":1586},[578,1658,1660],{"id":1659},"admins-get-no-private-updates-locally","Admins get no private updates locally",[560,1662,1663,1664,1667,1668,1671,1672,1675,1676,1679,1680,1683,1684,1687,1688,1387,1691,1698,1699,1702,1703,1706,1707,1709,1710,1712,1713,860],{},"With a Mercure 1.0 hub, the cookie is ",[583,1665,1666],{},"__Secure-mercure_access_token",", and browsers only accept it over HTTPS. The template's dev stack serves the hub at ",[583,1669,1670],{},"https:\u002F\u002Flocalhost\u002F.well-known\u002Fmercure",", so this works out of the box. ",[583,1673,1674],{},"mercure.yaml"," pins the name as ",[583,1677,1678],{},"cookie_name",", because mercure-bundle 0.6 drops the ",[583,1681,1682],{},"__Secure-"," prefix when ",[583,1685,1686],{},"kernel.debug"," is on, as it is in dev, and the hub then wouldn't read the cookie (template ",[583,1689,1690],{},"2.0.0-alpha.18",[567,1692,1695],{"href":1693,"rel":1694},"https:\u002F\u002Fgithub.com\u002Fcomponents-web-app\u002Fcomponents-web-app\u002Fcommit\u002Fb71fd4d1f6193ab6c80fd05c07a9cb3e576414fe",[1125],[583,1696,1697],{},"b71fd4d","). If you change ",[583,1700,1701],{},"CADDY_MERCURE_PUBLIC_URL"," to a plain ",[583,1704,1705],{},"http:\u002F\u002F"," URL, change that ",[583,1708,1678],{}," to a prefix-less name, and set the same name in the Caddyfile's ",[583,1711,1529],{}," block (see ",[567,1714,1716],{"href":1715},"\u002Fapi\u002Freal-time#the-subscriber-cookie","The subscriber cookie",[560,1718,1719,1720,1498,1723,571],{},"If the API and the front end are on different subdomains, also check the cookie's ",[583,1721,1722],{},"SameSite",[567,1724,1726],{"href":1725},"\u002Fdeployment\u002Fdocker#environment-variables","Docker → Environment Variables",[573,1728,1730],{"id":1729},"nuxt","Nuxt",[578,1732,1734,1735],{"id":1733},"the-sitemap-is-empty-or-the-nuxt-log-shows-und_err_headers_overflow","The sitemap is empty, or the Nuxt log shows ",[583,1736,1737],{},"UND_ERR_HEADERS_OVERFLOW",[560,1739,1740,1741,1744,1745,1748,1749,1752,1753,571],{},"Node refuses a response whose headers pass 16 KB by default, and a large collection's ",[583,1742,1743],{},"Surrogate-Key"," can pass that. The app image raises Node's limit with ",[583,1746,1747],{},"NODE_OPTIONS=--max-http-header-size=65536","; a deploy that sets its own ",[583,1750,1751],{},"NODE_OPTIONS"," replaces that. See ",[567,1754,1756],{"href":1755},"\u002Fdeployment\u002Fcloudflare#purges-must-reach-cloudflare","Cloudflare → Purges must reach Cloudflare",[573,1758,1760],{"id":1759},"database","Database",[578,1762,1764],{"id":1763},"the-in-cluster-postgresql-restarts-empty-or-the-api-cant-connect-after-a-credentials-change","The in-cluster PostgreSQL restarts empty, or the API can't connect after a credentials change",[560,1766,1767,1768,571],{},"Without persistence, changing the user or database name on a live site restarts the PostgreSQL pod empty, and a new password alone leaves the API unable to connect. See ",[567,1769,1771],{"href":1770},"\u002Fdeployment\u002Fvariables#database","CI\u002FCD Variables → Database",[573,1773,1775],{"id":1774},"kubernetes-deploys","Kubernetes deploys",[578,1777,1779,1780],{"id":1778},"the-review-job-is-orange-and-says-no-namespace-name","The review job is orange and says ",[583,1781,1782],{},"No namespace '\u003Cname>'",[560,1784,1785,1786,571],{},"The branch has no Kubernetes namespace, so it has no review app. Create the namespace and its role bindings, then run the job again. See ",[567,1787,1789],{"href":1788},"\u002Fdeployment\u002Fci-cd#review-apps","CI\u002FCD → Review Apps",[578,1791,1793],{"id":1792},"the-deploy-fails-before-helm-runs","The deploy fails before Helm runs",[560,1795,1796],{},"The deploy checks several things before it changes anything in the cluster, and its log says which one failed and what to change:",[1565,1798,1799,1821,1831,1842,1853,1862,1873],{},[1568,1800,1801,1808,1809,1812,1813,1816,1817,571],{},[675,1802,1803,1804,1807],{},"No ",[583,1805,1806],{},"DOMAIN",", or one that starts or ends with a dot:"," the environment url or ",[583,1810,1811],{},"KUBE_INGRESS_BASE_DOMAIN"," is empty. See ",[583,1814,1815],{},"check_kube_domain"," in ",[567,1818,1820],{"href":1819},"\u002Fdeployment\u002Fci-cd#the-devops-scripts","The Devops Scripts",[1568,1822,1823,1826,1827,571],{},[675,1824,1825],{},"The php memory budget doesn't fit:"," see ",[567,1828,1830],{"href":1829},"\u002Fdeployment\u002Fvariables#php-memory-budget","CI\u002FCD Variables → php memory budget",[1568,1832,1833,1826,1838,571],{},[675,1834,1835,1029],{},[583,1836,1837],{},"Site environment variables (NUXT_*, CWA_API_*) that can't be passed through",[567,1839,1841],{"href":1840},"\u002Fdeployment\u002Fvariables#reserved-names","Reserved names",[1568,1843,1844,1826,1849,571],{},[675,1845,1846,1029],{},[583,1847,1848],{},"CWA_ENVIRONMENT must be letters, digits, '.', '_' or '-'",[567,1850,1852],{"href":1851},"\u002Fdeployment\u002Fvariables#the-environment-name","The environment name",[1568,1854,1855,1826,1858,571],{},[675,1856,1857],{},"The PostgreSQL persistence settings differ from the live database:",[567,1859,1861],{"href":1860},"\u002Fdeployment\u002Fvariables#in-cluster-postgresql-persistence","In-cluster PostgreSQL persistence",[1568,1863,1864,1826,1869,571],{},[675,1865,1866,1029],{},[583,1867,1868],{},"CADDY_CACHE_CDN_CONFIG is incomplete, so php would not start",[567,1870,1872],{"href":1871},"\u002Fdeployment\u002Fcloudflare#secrets","Cloudflare → Secrets",[1568,1874,1875,1878,1879,571],{},[675,1876,1877],{},"A new hostname's certificate wasn't issued:"," point its DNS at the ingress first. See ",[567,1880,1882],{"href":1881},"\u002Fdeployment\u002Fci-cd#changing-a-live-sites-hostnames","Changing a live site's hostnames",[578,1884,1886],{"id":1885},"the-api-pod-stays-unready-and-every-probe-times-out","The API pod stays unready, and every probe times out",[560,1888,1889,1890,1893],{},"The php probes request ",[583,1891,1892],{},"\u002F_api\u002F_\u002Fsite_config_parameters.jsonld",", a path that would pass through the Souin cache. Souin combines concurrent requests for the same cache key into one request to php. In unpatched Souin 1.7.9, a request that is given up while php is still working keeps hold of that key, so every later probe waits for the 10-second backend timeout and fails, and the pod stays unready for good. The template prevents this three ways:",[1565,1895,1896,1908,1918],{},[1568,1897,1898,1899,1182,1904,1907],{},"The template's Souin build applies the fix from ",[567,1900,1903],{"href":1901,"rel":1902},"https:\u002F\u002Fgithub.com\u002Fdarkweak\u002Fsouin\u002Fpull\u002F850",[1125],"darkweak\u002Fsouin#850",[583,1905,1906],{},"api\u002Ffrankenphp\u002Fsouin\u002Fv1.7.9-singleflight-fix.patch","), so a request that times out releases the key. The patch can be removed once a Souin release includes it.",[1568,1909,1910,1911,1913,1914,1917],{},"The Caddyfile's ",[583,1912,1275],{}," skips the probe path for the kubelet's ",[583,1915,1916],{},"kube-probe\u002F"," user agent, so probes always reach php.",[1568,1919,1920],{},"Liveness uses the same request as readiness, so a pod whose php has stopped answering is restarted.",[560,1922,1923,1924,1927,1928,571],{},"Also keep ",[583,1925,1926],{},"timeoutSeconds: 5"," on both probes. See ",[567,1929,1931],{"href":1930},"\u002Fdeployment\u002Fkubernetes#health-checks","Kubernetes → Health Checks",[578,1933,1935,1936,1938],{"id":1934},"visitors-get-502-while-a-deploy-rolls-out","Visitors get ",[583,1937,1436],{}," while a deploy rolls out",[560,1940,1941,1942,1945,1946,1949,1950,597,1953,1956,1957,571],{},"A pod that closes its listener as soon as it's told to stop still gets requests for a few seconds, until the ingress and php's proxy drop its endpoint. The chart's ",[583,1943,1944],{},"preStop"," hooks hold both pods open for 5 seconds first. If your chart has no ",[583,1947,1948],{},"lifecycle.preStop"," blocks, copy them from the template's ",[583,1951,1952],{},"deployment.yaml",[583,1954,1955],{},"pwa-deployment.yaml",". The first deploy with them still rolls the old pods without the hook. See ",[567,1958,1960],{"href":1959},"\u002Fdeployment\u002Fkubernetes#stopping-a-pod-without-502s","Kubernetes → Stopping a pod without 502s",[578,1962,1964,1965],{"id":1963},"the-image-variants-job-ends-with-ran-out-of-memory-exit-137","The image variants job ends with ",[583,1966,1967],{},"ran out of memory (exit 137)",[560,1969,1970,1971,1974,1975,1978,1979,571],{},"The Job generating variants went over its own memory limit. The site isn't affected, because the Job doesn't serve requests. Raise ",[583,1972,1973],{},"CWA_CI_IMAGE_VARIANTS_MEMORY",", or lower ",[583,1976,1977],{},"CWA_CI_IMAGE_VARIANTS_MAX_MEMORY"," so each Job stops sooner and the next one carries on. See ",[567,1980,1982],{"href":1981},"\u002Fdeployment\u002Fci-cd#generating-image-variants-after-a-deploy","CI\u002FCD → Generating image variants after a deploy",[578,1984,1935,1986,1988],{"id":1985},"visitors-get-503-under-load",[583,1987,1439],{}," under load",[560,1990,1991,1992,1994,1995,571],{},"php gives up on a request that waits too long for a free worker, rather than letting it queue into a ",[583,1993,1442],{},". See ",[567,1996,1998],{"href":1997},"\u002Fdeployment\u002Forigin-protection#load-shedding","Origin Protection → Load shedding",[578,2000,2002],{"id":2001},"the-per-visitor-rate-limit-never-applies","The per-visitor rate limit never applies",[560,2004,2005,2006,2009,2010,2013,2014,2017,2018,571],{},"Every visitor looks internal when the ingress controller's Service uses ",[583,2007,2008],{},"externalTrafficPolicy: Cluster",". Set it to ",[583,2011,2012],{},"Local",", and check ",[583,2015,2016],{},"visitor_ip"," in php's access log. See ",[567,2019,2021],{"href":2020},"\u002Fdeployment\u002Forigin-protection#ingress-rate-limits","Origin Protection → Ingress rate limits",[573,2023,526],{"id":2024},"cloudflare",[578,2026,2028,2029,2032],{"id":2027},"cloudflare-returns-526-for-a-new-hostname-or-after-a-staging-deploy","Cloudflare returns ",[583,2030,2031],{},"526"," for a new hostname or after a staging deploy",[560,2034,2035,2036,597,2040,571],{},"The origin's certificate isn't valid yet. See ",[567,2037,2039],{"href":2038},"\u002Fdeployment\u002Fcloudflare#dns-and-tls","Cloudflare → DNS and TLS",[567,2041,2043],{"href":2042},"\u002Fdeployment\u002Fcloudflare#each-deploy-track","Each deploy track",[578,2045,2047],{"id":2046},"a-certificate-can-never-be-issued-or-renewed-behind-cloudflare","A certificate can never be issued or renewed behind Cloudflare",[560,2049,2050,2053,2054,571],{},[675,2051,2052],{},"Always Use HTTPS"," redirects the HTTP-01 challenge. Turn it off. See ",[567,2055,2043],{"href":2042},[578,2057,2059],{"id":2058},"an-edit-doesnt-show-at-the-edge","An edit doesn't show at the edge",[560,2061,2062,2063,2067],{},"See ",[567,2064,2066],{"href":2065},"\u002Fdeployment\u002Fcloudflare#checking-purges","Cloudflare → Checking purges"," for the log messages and how to check that purges arrive.",[578,2069,2071,2072,2075],{"id":2070},"pages-stay-dynamic-under-the-cache-rule","Pages stay ",[583,2073,2074],{},"DYNAMIC"," under the Cache Rule",[560,2077,2078,2079,1994,2082,571],{},"Cloudflare doesn't cache a response that carries ",[583,2080,2081],{},"Set-Cookie",[567,2083,2085],{"href":2084},"\u002Fdeployment\u002Fcloudflare#the-cache-rules-must-match-the-templates-exclusions","The cache rules must match the template's exclusions",[578,2087,2089],{"id":2088},"pages-built-from-page-data-all-show-one-pages-content-after-client-side-navigation","Pages built from page data all show one page's content after client-side navigation",[560,2091,2092,2093,571],{},"The API rule is missing the component positions exclusion. See ",[567,2094,2096],{"href":2095},"\u002Fdeployment\u002Fcloudflare#api-responses-optional","Cloudflare → API responses",[578,2098,2100,2101,2104],{"id":2099},"browsing-quickly-gets-a-429-from-cloudflare","Browsing quickly gets a ",[583,2102,2103],{},"429"," from Cloudflare",[560,2106,2107,2108,571],{},"A rate limiting rule is set too low. See ",[567,2109,2111],{"href":2110},"\u002Fdeployment\u002Fcloudflare#free-protection-worth-turning-on","Free protection worth turning on",[573,2113,570],{"id":2114},"elsewhere-in-the-docs",[1565,2116,2117,2122,2129,2136,2142,2149],{},[1568,2118,2119,2121],{},[567,2120,1537],{"href":1536},": live updates don't arrive.",[1568,2123,2124,2128],{},[567,2125,2127],{"href":2126},"\u002Fapi\u002Fdebugging#error-status-codes","Debugging & Profiler → Error Status Codes",": what each API error status means.",[1568,2130,2131,2135],{},[567,2132,2134],{"href":2133},"\u002Fnuxt-module\u002Fcwa-layer\u002Fdate-pickers#troubleshooting-the-picker-shows-no-time","Date Pickers → Troubleshooting",": the picker shows no time.",[1568,2137,2138,2141],{},[567,2139,2140],{"href":485},"Styling & CSS Isolation",": your global styles leak into the admin UI.",[1568,2143,2144,2148],{},[567,2145,2147],{"href":2146},"\u002Fdeployment\u002Fload-testing#traps","Load Testing → Traps",": a load test reports failures against a healthy server.",[1568,2150,2151,2153],{},[567,2152,19],{"href":20},": many errors above come from copying one part of a release without the rest, so follow each release's upgrade notes in full.",[2155,2156,2157],"style",{},"html pre.shiki code .sRCss, html code.shiki .sRCss{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#FFCB6B}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);}html pre.shiki code .szhYu, html code.shiki .szhYu{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#C3E88D}html pre.shiki code .seSrl, html code.shiki .seSrl{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#89DDFF}html pre.shiki code .sOvfz, html code.shiki .sOvfz{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#89DDFF}html pre.shiki code .sVlFx, html code.shiki .sVlFx{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#89DDFF}html pre.shiki code .sm4w6, html code.shiki .sm4w6{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}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 .sDHlG, html code.shiki .sDHlG{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#F07178}html pre.shiki code .swWMF, html code.shiki .swWMF{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":638,"searchDepth":964,"depth":964,"links":2159},[2160,2173,2186,2192,2196,2199,2212,2223],{"id":575,"depth":964,"text":576,"children":2161},[2162,2164,2165,2167,2169,2171,2172],{"id":580,"depth":1070,"text":2163},"Every page returns 502 or 503 after you run pnpm install on the host",{"id":669,"depth":1070,"text":670},{"id":774,"depth":1070,"text":2166},"composer update fails with a raw.githubusercontent.com 404",{"id":863,"depth":1070,"text":2168},"Composer or php reports a missing ffi extension",{"id":919,"depth":1070,"text":2170},"Caddy reports unexpected EOF after you edit the Caddyfile",{"id":1009,"depth":1070,"text":1010},{"id":1130,"depth":1070,"text":1131},{"id":1145,"depth":964,"text":1146,"children":2174},[2175,2177,2179,2180,2181,2183,2184],{"id":1200,"depth":1070,"text":2176},"php won't start with unrecognized directive after you copy the template's Caddyfile",{"id":1265,"depth":1070,"text":2178},"php keeps restarting with token recognition error at: '#'",{"id":1328,"depth":1070,"text":1329},{"id":1372,"depth":1070,"text":1373},{"id":1423,"depth":1070,"text":2182},"Requests that waited on a failed render get an empty 200",{"id":1491,"depth":1070,"text":1492},{"id":1505,"depth":1070,"text":2185},"PURGE or BAN sent to the site returns 405",{"id":1529,"depth":964,"text":1530,"children":2187},[2188,2189,2191],{"id":1540,"depth":1070,"text":1541},{"id":1621,"depth":1070,"text":2190},"php won't start with only one unnamed Mercure hub is allowed per configuration",{"id":1659,"depth":1070,"text":1660},{"id":1729,"depth":964,"text":1730,"children":2193},[2194],{"id":1733,"depth":1070,"text":2195},"The sitemap is empty, or the Nuxt log shows UND_ERR_HEADERS_OVERFLOW",{"id":1759,"depth":964,"text":1760,"children":2197},[2198],{"id":1763,"depth":1070,"text":1764},{"id":1774,"depth":964,"text":1775,"children":2200},[2201,2203,2204,2205,2207,2209,2211],{"id":1778,"depth":1070,"text":2202},"The review job is orange and says No namespace '\u003Cname>'",{"id":1792,"depth":1070,"text":1793},{"id":1885,"depth":1070,"text":1886},{"id":1934,"depth":1070,"text":2206},"Visitors get 502 while a deploy rolls out",{"id":1963,"depth":1070,"text":2208},"The image variants job ends with ran out of memory (exit 137)",{"id":1985,"depth":1070,"text":2210},"Visitors get 503 under load",{"id":2001,"depth":1070,"text":2002},{"id":2024,"depth":964,"text":526,"children":2213},[2214,2216,2217,2218,2220,2221],{"id":2027,"depth":1070,"text":2215},"Cloudflare returns 526 for a new hostname or after a staging deploy",{"id":2046,"depth":1070,"text":2047},{"id":2058,"depth":1070,"text":2059},{"id":2070,"depth":1070,"text":2219},"Pages stay DYNAMIC under the Cache Rule",{"id":2088,"depth":1070,"text":2089},{"id":2099,"depth":1070,"text":2222},"Browsing quickly gets a 429 from Cloudflare",{"id":2114,"depth":964,"text":570},"Find a problem by its symptom or error message — local dev, Caddy and Souin, Mercure, Nuxt, the database, Kubernetes deploys and Cloudflare — with a fix for each and a link to the full explanation.","md",{},true,{"title":550,"description":2224},"MhZkDc6OXubA0MXWEZ9DzvJMoC_Nb0KcHK7RaA5F5WM",[2231,555],{"title":546,"path":547,"stem":548,"description":2232,"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.",1791855273524]