[{"data":1,"prerenderedAt":2976},["ShallowReactive",2],{"navigation_docs":3,"-docs-products-sites-architecture-":984},[4,8,44,50,86,583,625,918],{"title":5,"path":6,"stem":7},"Home","\u002Fdocs","docs\u002Findex",{"title":9,"path":10,"stem":11,"children":12},"API usage","\u002Fdocs\u002Fapi-usage","docs\u002Fapi-usage\u002Findex",[13,14,20,26,32,38],{"title":9,"path":10,"stem":11},{"title":15,"path":16,"stem":17,"children":18},"Errors","\u002Fdocs\u002Fapi-usage\u002Ferrors","docs\u002Fapi-usage\u002Ferrors\u002Findex",[19],{"title":15,"path":16,"stem":17},{"title":21,"path":22,"stem":23,"children":24},"Retries & idempotency","\u002Fdocs\u002Fapi-usage\u002Fidempotency","docs\u002Fapi-usage\u002Fidempotency\u002Findex",[25],{"title":21,"path":22,"stem":23},{"title":27,"path":28,"stem":29,"children":30},"Pagination & filtering","\u002Fdocs\u002Fapi-usage\u002Fpagination","docs\u002Fapi-usage\u002Fpagination\u002Findex",[31],{"title":27,"path":28,"stem":29},{"title":33,"path":34,"stem":35,"children":36},"Rate limits","\u002Fdocs\u002Fapi-usage\u002Frate-limits","docs\u002Fapi-usage\u002Frate-limits\u002Findex",[37],{"title":33,"path":34,"stem":35},{"title":39,"path":40,"stem":41,"children":42},"Versioning & stability","\u002Fdocs\u002Fapi-usage\u002Fversioning","docs\u002Fapi-usage\u002Fversioning\u002Findex",[43],{"title":39,"path":40,"stem":41},{"title":45,"path":46,"stem":47,"children":48},"What's new","\u002Fdocs\u002Fchangelog","docs\u002Fchangelog\u002Findex",[49],{"title":45,"path":46,"stem":47},{"title":51,"path":52,"stem":53,"children":54},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002Fgetting-started\u002Findex",[55,56,62,68,74,80],{"title":51,"path":52,"stem":53},{"title":57,"path":58,"stem":59,"children":60},"Architecture Overview","\u002Fdocs\u002Fgetting-started\u002Farchitecture","docs\u002Fgetting-started\u002Farchitecture\u002Findex",[61],{"title":57,"path":58,"stem":59},{"title":63,"path":64,"stem":65,"children":66},"Glossary","\u002Fdocs\u002Fgetting-started\u002Fglossary","docs\u002Fgetting-started\u002Fglossary\u002Findex",[67],{"title":63,"path":64,"stem":65},{"title":69,"path":70,"stem":71,"children":72},"Platform Overview","\u002Fdocs\u002Fgetting-started\u002Fplatform-overview","docs\u002Fgetting-started\u002Fplatform-overview\u002Findex",[73],{"title":69,"path":70,"stem":71},{"title":75,"path":76,"stem":77,"children":78},"Prerequisites","\u002Fdocs\u002Fgetting-started\u002Fprerequisites","docs\u002Fgetting-started\u002Fprerequisites\u002Findex",[79],{"title":75,"path":76,"stem":77},{"title":81,"path":82,"stem":83,"children":84},"Your First App in 15 Minutes","\u002Fdocs\u002Fgetting-started\u002Fquick-start","docs\u002Fgetting-started\u002Fquick-start\u002Findex",[85],{"title":81,"path":82,"stem":83},{"title":87,"path":88,"stem":89,"children":90},"Products","\u002Fdocs\u002Fproducts","docs\u002Fproducts\u002Findex",[91,92,98,170,200,218,254,320,517,565],{"title":87,"path":88,"stem":89},{"title":93,"path":94,"stem":95,"children":96},"AI Studio","\u002Fdocs\u002Fproducts\u002Fai","docs\u002Fproducts\u002Fai\u002Findex",[97],{"title":93,"path":94,"stem":95},{"title":99,"path":100,"stem":101,"children":102},"App Studio","\u002Fdocs\u002Fproducts\u002Fapps","docs\u002Fproducts\u002Fapps\u002Findex",[103,104,110,116,122,128,134,140,146,152,158,164],{"title":99,"path":100,"stem":101},{"title":105,"path":106,"stem":107,"children":108},"App Model","\u002Fdocs\u002Fproducts\u002Fapps\u002Fapp-model","docs\u002Fproducts\u002Fapps\u002Fapp-model\u002Findex",[109],{"title":105,"path":106,"stem":107},{"title":111,"path":112,"stem":113,"children":114},"Auto-generated data APIs","\u002Fdocs\u002Fproducts\u002Fapps\u002Fauto-generated-data-apis","docs\u002Fproducts\u002Fapps\u002Fauto-generated-data-apis\u002Findex",[115],{"title":111,"path":112,"stem":113},{"title":117,"path":118,"stem":119,"children":120},"Billing & Events","\u002Fdocs\u002Fproducts\u002Fapps\u002Fbilling-events","docs\u002Fproducts\u002Fapps\u002Fbilling-events\u002Findex",[121],{"title":117,"path":118,"stem":119},{"title":123,"path":124,"stem":125,"children":126},"Cockpit Integration","\u002Fdocs\u002Fproducts\u002Fapps\u002Fcockpit-integration","docs\u002Fproducts\u002Fapps\u002Fcockpit-integration\u002Findex",[127],{"title":123,"path":124,"stem":125},{"title":129,"path":130,"stem":131,"children":132},"App Model Concept","\u002Fdocs\u002Fproducts\u002Fapps\u002Fconcept","docs\u002Fproducts\u002Fapps\u002Fconcept\u002Findex",[133],{"title":129,"path":130,"stem":131},{"title":135,"path":136,"stem":137,"children":138},"App Lifecycle","\u002Fdocs\u002Fproducts\u002Fapps\u002Flifecycle","docs\u002Fproducts\u002Fapps\u002Flifecycle\u002Findex",[139],{"title":135,"path":136,"stem":137},{"title":141,"path":142,"stem":143,"children":144},"Manifest Reference","\u002Fdocs\u002Fproducts\u002Fapps\u002Fmanifest-reference","docs\u002Fproducts\u002Fapps\u002Fmanifest-reference\u002Findex",[145],{"title":141,"path":142,"stem":143},{"title":147,"path":148,"stem":149,"children":150},"Market Concept","\u002Fdocs\u002Fproducts\u002Fapps\u002Fmarket-concept","docs\u002Fproducts\u002Fapps\u002Fmarket-concept\u002Findex",[151],{"title":147,"path":148,"stem":149},{"title":153,"path":154,"stem":155,"children":156},"Policies","\u002Fdocs\u002Fproducts\u002Fapps\u002Fpolicies","docs\u002Fproducts\u002Fapps\u002Fpolicies\u002Findex",[157],{"title":153,"path":154,"stem":155},{"title":159,"path":160,"stem":161,"children":162},"Schema migrations","\u002Fdocs\u002Fproducts\u002Fapps\u002Fschema-migrator","docs\u002Fproducts\u002Fapps\u002Fschema-migrator\u002Findex",[163],{"title":159,"path":160,"stem":161},{"title":165,"path":166,"stem":167,"children":168},"Schema Reference","\u002Fdocs\u002Fproducts\u002Fapps\u002Fschema-reference","docs\u002Fproducts\u002Fapps\u002Fschema-reference\u002Findex",[169],{"title":165,"path":166,"stem":167},{"title":171,"path":172,"stem":173,"children":174},"Authentication","\u002Fdocs\u002Fproducts\u002Fauth","docs\u002Fproducts\u002Fauth\u002Findex",[175,176,182,188,194],{"title":171,"path":172,"stem":173},{"title":177,"path":178,"stem":179,"children":180},"API keys","\u002Fdocs\u002Fproducts\u002Fauth\u002Fapi-keys","docs\u002Fproducts\u002Fauth\u002Fapi-keys\u002Findex",[181],{"title":177,"path":178,"stem":179},{"title":183,"path":184,"stem":185,"children":186},"Multi-factor authentication","\u002Fdocs\u002Fproducts\u002Fauth\u002Fmfa","docs\u002Fproducts\u002Fauth\u002Fmfa\u002Findex",[187],{"title":183,"path":184,"stem":185},{"title":189,"path":190,"stem":191,"children":192},"Social sign-in","\u002Fdocs\u002Fproducts\u002Fauth\u002Foauth2","docs\u002Fproducts\u002Fauth\u002Foauth2\u002Findex",[193],{"title":189,"path":190,"stem":191},{"title":195,"path":196,"stem":197,"children":198},"Sessions","\u002Fdocs\u002Fproducts\u002Fauth\u002Fsessions","docs\u002Fproducts\u002Fauth\u002Fsessions\u002Findex",[199],{"title":195,"path":196,"stem":197},{"title":201,"path":202,"stem":203,"children":204},"Events","\u002Fdocs\u002Fproducts\u002Fevents","docs\u002Fproducts\u002Fevents\u002Findex",[205,206,212],{"title":201,"path":202,"stem":203},{"title":207,"path":208,"stem":209,"children":210},"Consuming events","\u002Fdocs\u002Fproducts\u002Fevents\u002Fconsuming-events","docs\u002Fproducts\u002Fevents\u002Fconsuming-events\u002Findex",[211],{"title":207,"path":208,"stem":209},{"title":213,"path":214,"stem":215,"children":216},"Event types","\u002Fdocs\u002Fproducts\u002Fevents\u002Fevent-types","docs\u002Fproducts\u002Fevents\u002Fevent-types\u002Findex",[217],{"title":213,"path":214,"stem":215},{"title":219,"path":220,"stem":221,"children":222},"Integration Studio","\u002Fdocs\u002Fproducts\u002Fintegration-studio","docs\u002Fproducts\u002Fintegration-studio\u002Findex",[223,224,230,236,242,248],{"title":219,"path":220,"stem":221},{"title":225,"path":226,"stem":227,"children":228},"Expression Syntax","\u002Fdocs\u002Fproducts\u002Fintegration-studio\u002Fexpression-syntax","docs\u002Fproducts\u002Fintegration-studio\u002Fexpression-syntax\u002Findex",[229],{"title":225,"path":226,"stem":227},{"title":231,"path":232,"stem":233,"children":234},"Node Types","\u002Fdocs\u002Fproducts\u002Fintegration-studio\u002Fnode-types","docs\u002Fproducts\u002Fintegration-studio\u002Fnode-types\u002Findex",[235],{"title":231,"path":232,"stem":233},{"title":237,"path":238,"stem":239,"children":240},"Dual-engine architecture","\u002Fdocs\u002Fproducts\u002Fintegration-studio\u002Foverview","docs\u002Fproducts\u002Fintegration-studio\u002Foverview\u002Findex",[241],{"title":237,"path":238,"stem":239},{"title":243,"path":244,"stem":245,"children":246},"Triggers","\u002Fdocs\u002Fproducts\u002Fintegration-studio\u002Ftriggers","docs\u002Fproducts\u002Fintegration-studio\u002Ftriggers\u002Findex",[247],{"title":243,"path":244,"stem":245},{"title":249,"path":250,"stem":251,"children":252},"Workflow Builder","\u002Fdocs\u002Fproducts\u002Fintegration-studio\u002Fworkflow-builder","docs\u002Fproducts\u002Fintegration-studio\u002Fworkflow-builder\u002Findex",[253],{"title":249,"path":250,"stem":251},{"title":255,"path":256,"stem":257,"children":258},"Network","\u002Fdocs\u002Fproducts\u002Fnetwork","docs\u002Fproducts\u002Fnetwork\u002Findex",[259,260,266,272,278,284,290,296,302,308,314],{"title":255,"path":256,"stem":257},{"title":261,"path":262,"stem":263,"children":264},"Caching","\u002Fdocs\u002Fproducts\u002Fnetwork\u002Fcaching","docs\u002Fproducts\u002Fnetwork\u002Fcaching\u002Findex",[265],{"title":261,"path":262,"stem":263},{"title":267,"path":268,"stem":269,"children":270},"Content delivery (CDN)","\u002Fdocs\u002Fproducts\u002Fnetwork\u002Fcdn","docs\u002Fproducts\u002Fnetwork\u002Fcdn\u002Findex",[271],{"title":267,"path":268,"stem":269},{"title":273,"path":274,"stem":275,"children":276},"Compression","\u002Fdocs\u002Fproducts\u002Fnetwork\u002Fcompression","docs\u002Fproducts\u002Fnetwork\u002Fcompression\u002Findex",[277],{"title":273,"path":274,"stem":275},{"title":279,"path":280,"stem":281,"children":282},"DDoS mitigation","\u002Fdocs\u002Fproducts\u002Fnetwork\u002Fddos","docs\u002Fproducts\u002Fnetwork\u002Fddos\u002Findex",[283],{"title":279,"path":280,"stem":281},{"title":285,"path":286,"stem":287,"children":288},"revenexx DNS service","\u002Fdocs\u002Fproducts\u002Fnetwork\u002Fdns","docs\u002Fproducts\u002Fnetwork\u002Fdns\u002Findex",[289],{"title":285,"path":286,"stem":287},{"title":291,"path":292,"stem":293,"children":294},"Edges","\u002Fdocs\u002Fproducts\u002Fnetwork\u002Fedges","docs\u002Fproducts\u002Fnetwork\u002Fedges\u002Findex",[295],{"title":291,"path":292,"stem":293},{"title":297,"path":298,"stem":299,"children":300},"Endpoints","\u002Fdocs\u002Fproducts\u002Fnetwork\u002Fendpoints","docs\u002Fproducts\u002Fnetwork\u002Fendpoints\u002Findex",[301],{"title":297,"path":298,"stem":299},{"title":303,"path":304,"stem":305,"children":306},"Regions","\u002Fdocs\u002Fproducts\u002Fnetwork\u002Fregions","docs\u002Fproducts\u002Fnetwork\u002Fregions\u002Findex",[307],{"title":303,"path":304,"stem":305},{"title":309,"path":310,"stem":311,"children":312},"Transport Layer Security (TLS)","\u002Fdocs\u002Fproducts\u002Fnetwork\u002Ftls","docs\u002Fproducts\u002Fnetwork\u002Ftls\u002Findex",[313],{"title":309,"path":310,"stem":311},{"title":315,"path":316,"stem":317,"children":318},"Web application firewall (WAF)","\u002Fdocs\u002Fproducts\u002Fnetwork\u002Fwaf","docs\u002Fproducts\u002Fnetwork\u002Fwaf\u002Findex",[319],{"title":315,"path":316,"stem":317},{"title":321,"path":322,"stem":323,"children":324},"Experience Studio","\u002Fdocs\u002Fproducts\u002Fsites","docs\u002Fproducts\u002Fsites\u002Findex",[325,326,332,337,343,349,355,361,367,373,379,385,391,397,403,409,487,505,511],{"title":321,"path":322,"stem":323},{"title":327,"path":328,"stem":329,"children":330},"Storefront Architecture","\u002Fdocs\u002Fproducts\u002Fsites\u002Farchitecture","docs\u002Fproducts\u002Fsites\u002Farchitecture\u002Findex",[331],{"title":327,"path":328,"stem":329},{"title":171,"path":333,"stem":334,"children":335},"\u002Fdocs\u002Fproducts\u002Fsites\u002Fauthentication","docs\u002Fproducts\u002Fsites\u002Fauthentication\u002Findex",[336],{"title":171,"path":333,"stem":334},{"title":338,"path":339,"stem":340,"children":341},"Blökkli Blocks","\u002Fdocs\u002Fproducts\u002Fsites\u002Fblokki-blocks","docs\u002Fproducts\u002Fsites\u002Fblokki-blocks\u002Findex",[342],{"title":338,"path":339,"stem":340},{"title":344,"path":345,"stem":346,"children":347},"Checkout","\u002Fdocs\u002Fproducts\u002Fsites\u002Fcheckout","docs\u002Fproducts\u002Fsites\u002Fcheckout\u002Findex",[348],{"title":344,"path":345,"stem":346},{"title":350,"path":351,"stem":352,"children":353},"Deploy from CLI","\u002Fdocs\u002Fproducts\u002Fsites\u002Fdeploy-from-cli","docs\u002Fproducts\u002Fsites\u002Fdeploy-from-cli\u002Findex",[354],{"title":350,"path":351,"stem":352},{"title":356,"path":357,"stem":358,"children":359},"Deploy from Git","\u002Fdocs\u002Fproducts\u002Fsites\u002Fdeploy-from-git","docs\u002Fproducts\u002Fsites\u002Fdeploy-from-git\u002Findex",[360],{"title":356,"path":357,"stem":358},{"title":362,"path":363,"stem":364,"children":365},"Deploy manually","\u002Fdocs\u002Fproducts\u002Fsites\u002Fdeploy-manually","docs\u002Fproducts\u002Fsites\u002Fdeploy-manually\u002Findex",[366],{"title":362,"path":363,"stem":364},{"title":368,"path":369,"stem":370,"children":371},"Deployments","\u002Fdocs\u002Fproducts\u002Fsites\u002Fdeployments","docs\u002Fproducts\u002Fsites\u002Fdeployments\u002Findex",[372],{"title":368,"path":369,"stem":370},{"title":374,"path":375,"stem":376,"children":377},"Develop revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fdevelop","docs\u002Fproducts\u002Fsites\u002Fdevelop\u002Findex",[378],{"title":374,"path":375,"stem":376},{"title":380,"path":381,"stem":382,"children":383},"Domains","\u002Fdocs\u002Fproducts\u002Fsites\u002Fdomains","docs\u002Fproducts\u002Fsites\u002Fdomains\u002Findex",[384],{"title":380,"path":381,"stem":382},{"title":386,"path":387,"stem":388,"children":389},"Frameworks","\u002Fdocs\u002Fproducts\u002Fsites\u002Fframeworks","docs\u002Fproducts\u002Fsites\u002Fframeworks\u002Findex",[390],{"title":386,"path":387,"stem":388},{"title":392,"path":393,"stem":394,"children":395},"Instant rollbacks","\u002Fdocs\u002Fproducts\u002Fsites\u002Finstant-rollbacks","docs\u002Fproducts\u002Fsites\u002Finstant-rollbacks\u002Findex",[396],{"title":392,"path":393,"stem":394},{"title":398,"path":399,"stem":400,"children":401},"Logs","\u002Fdocs\u002Fproducts\u002Fsites\u002Flogs","docs\u002Fproducts\u002Fsites\u002Flogs\u002Findex",[402],{"title":398,"path":399,"stem":400},{"title":404,"path":405,"stem":406,"children":407},"Previews","\u002Fdocs\u002Fproducts\u002Fsites\u002Fpreviews","docs\u002Fproducts\u002Fsites\u002Fpreviews\u002Findex",[408],{"title":404,"path":405,"stem":406},{"title":410,"path":411,"stem":412,"children":413},"Start with Sites","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Findex",[414,415,421,427,433,439,445,451,457,463,469,475,481],{"title":410,"path":411,"stem":412},{"title":416,"path":417,"stem":418,"children":419},"Deploy an Angular app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fangular","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fangular\u002Findex",[420],{"title":416,"path":417,"stem":418},{"title":422,"path":423,"stem":424,"children":425},"Deploy a Astro app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fastro","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fastro\u002Findex",[426],{"title":422,"path":423,"stem":424},{"title":428,"path":429,"stem":430,"children":431},"Deploy a Flutter Web app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fflutter","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fflutter\u002Findex",[432],{"title":428,"path":429,"stem":430},{"title":434,"path":435,"stem":436,"children":437},"Deploy a Next.js app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fnextjs","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fnextjs\u002Findex",[438],{"title":434,"path":435,"stem":436},{"title":440,"path":441,"stem":442,"children":443},"Deploy a Nuxt app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fnuxt","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fnuxt\u002Findex",[444],{"title":440,"path":441,"stem":442},{"title":446,"path":447,"stem":448,"children":449},"Deploy a React Native app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Freact-native","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Freact-native\u002Findex",[450],{"title":446,"path":447,"stem":448},{"title":452,"path":453,"stem":454,"children":455},"Deploy a React app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Freact","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Freact\u002Findex",[456],{"title":452,"path":453,"stem":454},{"title":458,"path":459,"stem":460,"children":461},"Deploy a Remix app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fremix","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fremix\u002Findex",[462],{"title":458,"path":459,"stem":460},{"title":464,"path":465,"stem":466,"children":467},"Deploy a SvelteKit app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fsveltekit","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fsveltekit\u002Findex",[468],{"title":464,"path":465,"stem":466},{"title":470,"path":471,"stem":472,"children":473},"Deploy a TanStack Start app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Ftanstack-start","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Ftanstack-start\u002Findex",[474],{"title":470,"path":471,"stem":472},{"title":476,"path":477,"stem":478,"children":479},"Deploy a Vanilla JS app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fvanilla","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fvanilla\u002Findex",[480],{"title":476,"path":477,"stem":478},{"title":482,"path":483,"stem":484,"children":485},"Deploy a Vue.js app to revenexx Storefronts","\u002Fdocs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fvue","docs\u002Fproducts\u002Fsites\u002Fquick-start\u002Fvue\u002Findex",[486],{"title":482,"path":483,"stem":484},{"title":488,"path":489,"stem":490,"children":491},"Rendering","\u002Fdocs\u002Fproducts\u002Fsites\u002Frendering","docs\u002Fproducts\u002Fsites\u002Frendering\u002Findex",[492,493,499],{"title":488,"path":489,"stem":490},{"title":494,"path":495,"stem":496,"children":497},"Server Side Rendering","\u002Fdocs\u002Fproducts\u002Fsites\u002Frendering\u002Fssr","docs\u002Fproducts\u002Fsites\u002Frendering\u002Fssr\u002Findex",[498],{"title":494,"path":495,"stem":496},{"title":500,"path":501,"stem":502,"children":503},"Static","\u002Fdocs\u002Fproducts\u002Fsites\u002Frendering\u002Fstatic","docs\u002Fproducts\u002Fsites\u002Frendering\u002Fstatic\u002Findex",[504],{"title":500,"path":501,"stem":502},{"title":506,"path":507,"stem":508,"children":509},"Templates","\u002Fdocs\u002Fproducts\u002Fsites\u002Ftemplates","docs\u002Fproducts\u002Fsites\u002Ftemplates\u002Findex",[510],{"title":506,"path":507,"stem":508},{"title":512,"path":513,"stem":514,"children":515},"Theming","\u002Fdocs\u002Fproducts\u002Fsites\u002Ftheming","docs\u002Fproducts\u002Fsites\u002Ftheming\u002Findex",[516],{"title":512,"path":513,"stem":514},{"title":518,"path":519,"stem":520,"children":521},"Storage","\u002Fdocs\u002Fproducts\u002Fstorage","docs\u002Fproducts\u002Fstorage\u002Findex",[522,523,529,535,541,547,553,559],{"title":518,"path":519,"stem":520},{"title":524,"path":525,"stem":526,"children":527},"Folders","\u002Fdocs\u002Fproducts\u002Fstorage\u002Fbuckets","docs\u002Fproducts\u002Fstorage\u002Fbuckets\u002Findex",[528],{"title":524,"path":525,"stem":526},{"title":530,"path":531,"stem":532,"children":533},"Signed URLs and access","\u002Fdocs\u002Fproducts\u002Fstorage\u002Ffile-tokens","docs\u002Fproducts\u002Fstorage\u002Ffile-tokens\u002Findex",[534],{"title":530,"path":531,"stem":532},{"title":536,"path":537,"stem":538,"children":539},"Serve and transform images","\u002Fdocs\u002Fproducts\u002Fstorage\u002Fimages","docs\u002Fproducts\u002Fstorage\u002Fimages\u002Findex",[540],{"title":536,"path":537,"stem":538},{"title":542,"path":543,"stem":544,"children":545},"3D assets","\u002Fdocs\u002Fproducts\u002Fstorage\u002Fmodel-viewer","docs\u002Fproducts\u002Fstorage\u002Fmodel-viewer\u002Findex",[546],{"title":542,"path":543,"stem":544},{"title":548,"path":549,"stem":550,"children":551},"Access control and visibility","\u002Fdocs\u002Fproducts\u002Fstorage\u002Fpermissions","docs\u002Fproducts\u002Fstorage\u002Fpermissions\u002Findex",[552],{"title":548,"path":549,"stem":550},{"title":554,"path":555,"stem":556,"children":557},"Quick start","\u002Fdocs\u002Fproducts\u002Fstorage\u002Fquick-start","docs\u002Fproducts\u002Fstorage\u002Fquick-start\u002Findex",[558],{"title":554,"path":555,"stem":556},{"title":560,"path":561,"stem":562,"children":563},"Upload and manage files","\u002Fdocs\u002Fproducts\u002Fstorage\u002Fupload-download","docs\u002Fproducts\u002Fstorage\u002Fupload-download\u002Findex",[564],{"title":560,"path":561,"stem":562},{"title":566,"path":567,"stem":568,"children":569},"Webhooks","\u002Fdocs\u002Fproducts\u002Fwebhooks","docs\u002Fproducts\u002Fwebhooks\u002Findex",[570,571,577],{"title":566,"path":567,"stem":568},{"title":572,"path":573,"stem":574,"children":575},"Delivery","\u002Fdocs\u002Fproducts\u002Fwebhooks\u002Fdelivery","docs\u002Fproducts\u002Fwebhooks\u002Fdelivery\u002Findex",[576],{"title":572,"path":573,"stem":574},{"title":578,"path":579,"stem":580,"children":581},"Security","\u002Fdocs\u002Fproducts\u002Fwebhooks\u002Fsecurity","docs\u002Fproducts\u002Fwebhooks\u002Fsecurity\u002Findex",[582],{"title":578,"path":579,"stem":580},{"title":584,"path":585,"stem":586,"children":587},"SDKs","\u002Fdocs\u002Fsdks","docs\u002Fsdks\u002Findex",[588,589,595,601,607,613,619],{"title":584,"path":585,"stem":586},{"title":590,"path":591,"stem":592,"children":593},"App SDK","\u002Fdocs\u002Fsdks\u002Fapp-sdk","docs\u002Fsdks\u002Fapp-sdk\u002Findex",[594],{"title":590,"path":591,"stem":592},{"title":596,"path":597,"stem":598,"children":599},"CLI","\u002Fdocs\u002Fsdks\u002Fcli","docs\u002Fsdks\u002Fcli\u002Findex",[600],{"title":596,"path":597,"stem":598},{"title":602,"path":603,"stem":604,"children":605},"Integration Node SDK","\u002Fdocs\u002Fsdks\u002Fintegration-nodes","docs\u002Fsdks\u002Fintegration-nodes\u002Findex",[606],{"title":602,"path":603,"stem":604},{"title":608,"path":609,"stem":610,"children":611},"Node SDK","\u002Fdocs\u002Fsdks\u002Fnode","docs\u002Fsdks\u002Fnode\u002Findex",[612],{"title":608,"path":609,"stem":610},{"title":614,"path":615,"stem":616,"children":617},"PHP SDK","\u002Fdocs\u002Fsdks\u002Fphp","docs\u002Fsdks\u002Fphp\u002Findex",[618],{"title":614,"path":615,"stem":616},{"title":620,"path":621,"stem":622,"children":623},"Web \u002F JavaScript SDK","\u002Fdocs\u002Fsdks\u002Fweb","docs\u002Fsdks\u002Fweb\u002Findex",[624],{"title":620,"path":621,"stem":622},{"title":626,"path":627,"stem":628,"children":629},"Tooling","\u002Fdocs\u002Ftooling","docs\u002Ftooling\u002Findex",[630,631,637,864],{"title":626,"path":627,"stem":628},{"title":632,"path":633,"stem":634,"children":635},"Command Center","\u002Fdocs\u002Ftooling\u002Fcommand-center","docs\u002Ftooling\u002Fcommand-center\u002Findex",[636],{"title":632,"path":633,"stem":634},{"title":638,"path":639,"stem":640,"children":641},"Command line","\u002Fdocs\u002Ftooling\u002Fcommand-line","docs\u002Ftooling\u002Fcommand-line\u002Findex",[642,643,649,654,660,666,672,678,684,828,834,840,846,852,858],{"title":638,"path":639,"stem":640},{"title":644,"path":645,"stem":646,"children":647},"Aliases","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Faliases","docs\u002Ftooling\u002Fcommand-line\u002Faliases\u002Findex",[648],{"title":644,"path":645,"stem":646},{"title":171,"path":650,"stem":651,"children":652},"\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Fauthentication","docs\u002Ftooling\u002Fcommand-line\u002Fauthentication\u002Findex",[653],{"title":171,"path":650,"stem":651},{"title":655,"path":656,"stem":657,"children":658},"Commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Fcommands","docs\u002Ftooling\u002Fcommand-line\u002Fcommands\u002Findex",[659],{"title":655,"path":656,"stem":657},{"title":661,"path":662,"stem":663,"children":664},"Installation","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Finstallation","docs\u002Ftooling\u002Fcommand-line\u002Finstallation\u002Findex",[665],{"title":661,"path":662,"stem":663},{"title":667,"path":668,"stem":669,"children":670},"Interactive use","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Finteractive","docs\u002Ftooling\u002Fcommand-line\u002Finteractive\u002Findex",[671],{"title":667,"path":668,"stem":669},{"title":673,"path":674,"stem":675,"children":676},"Non-interactive use","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Fnon-interactive","docs\u002Ftooling\u002Fcommand-line\u002Fnon-interactive\u002Findex",[677],{"title":673,"path":674,"stem":675},{"title":679,"path":680,"stem":681,"children":682},"Project configuration","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Fproject-configuration","docs\u002Ftooling\u002Fcommand-line\u002Fproject-configuration\u002Findex",[683],{"title":679,"path":680,"stem":681},{"title":685,"path":686,"stem":687,"children":688},"Command reference","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Findex",[689,690,696,702,708,714,720,726,732,738,744,750,756,762,768,774,780,786,792,798,804,810,816,822],{"title":685,"path":686,"stem":687},{"title":691,"path":692,"stem":693,"children":694},"About commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fabout","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fabout\u002Findex",[695],{"title":691,"path":692,"stem":693},{"title":697,"path":698,"stem":699,"children":700},"Apps commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fapps","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fapps\u002Findex",[701],{"title":697,"path":698,"stem":699},{"title":703,"path":704,"stem":705,"children":706},"Carts commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fcarts","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fcarts\u002Findex",[707],{"title":703,"path":704,"stem":705},{"title":709,"path":710,"stem":711,"children":712},"Channels commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fchannels","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fchannels\u002Findex",[713],{"title":709,"path":710,"stem":711},{"title":715,"path":716,"stem":717,"children":718},"Create commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fcreate","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fcreate\u002Findex",[719],{"title":715,"path":716,"stem":717},{"title":721,"path":722,"stem":723,"children":724},"Customers commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fcustomers","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fcustomers\u002Findex",[725],{"title":721,"path":722,"stem":723},{"title":727,"path":728,"stem":729,"children":730},"Deploy commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fdeploy","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fdeploy\u002Findex",[731],{"title":727,"path":728,"stem":729},{"title":733,"path":734,"stem":735,"children":736},"Forms commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fforms","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fforms\u002Findex",[737],{"title":733,"path":734,"stem":735},{"title":739,"path":740,"stem":741,"children":742},"Inventories commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Finventories","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Finventories\u002Findex",[743],{"title":739,"path":740,"stem":741},{"title":745,"path":746,"stem":747,"children":748},"Markets commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fmarkets","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fmarkets\u002Findex",[749],{"title":745,"path":746,"stem":747},{"title":751,"path":752,"stem":753,"children":754},"Order lists commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Forderlists","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Forderlists\u002Findex",[755],{"title":751,"path":752,"stem":753},{"title":757,"path":758,"stem":759,"children":760},"Orders commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Forders","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Forders\u002Findex",[761],{"title":757,"path":758,"stem":759},{"title":763,"path":764,"stem":765,"children":766},"Pages commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fpages","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fpages\u002Findex",[767],{"title":763,"path":764,"stem":765},{"title":769,"path":770,"stem":771,"children":772},"Payments commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fpayments","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fpayments\u002Findex",[773],{"title":769,"path":770,"stem":771},{"title":775,"path":776,"stem":777,"children":778},"Prices commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fprices","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fprices\u002Findex",[779],{"title":775,"path":776,"stem":777},{"title":781,"path":782,"stem":783,"children":784},"Products commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fproducts","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fproducts\u002Findex",[785],{"title":781,"path":782,"stem":783},{"title":787,"path":788,"stem":789,"children":790},"Search commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fsearch","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fsearch\u002Findex",[791],{"title":787,"path":788,"stem":789},{"title":793,"path":794,"stem":795,"children":796},"Settings commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fsettings","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fsettings\u002Findex",[797],{"title":793,"path":794,"stem":795},{"title":799,"path":800,"stem":801,"children":802},"Shipping commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fshipping","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fshipping\u002Findex",[803],{"title":799,"path":800,"stem":801},{"title":805,"path":806,"stem":807,"children":808},"Sites commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fsites","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fsites\u002Findex",[809],{"title":805,"path":806,"stem":807},{"title":811,"path":812,"stem":813,"children":814},"Skills commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fskills","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fskills\u002Findex",[815],{"title":811,"path":812,"stem":813},{"title":817,"path":818,"stem":819,"children":820},"Storage commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fstorage","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Fstorage\u002Findex",[821],{"title":817,"path":818,"stem":819},{"title":823,"path":824,"stem":825,"children":826},"Tokens commands","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Freference\u002Ftokens","docs\u002Ftooling\u002Fcommand-line\u002Freference\u002Ftokens\u002Findex",[827],{"title":823,"path":824,"stem":825},{"title":829,"path":830,"stem":831,"children":832},"Interactive shell (REPL)","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Frepl","docs\u002Ftooling\u002Fcommand-line\u002Frepl\u002Findex",[833],{"title":829,"path":830,"stem":831},{"title":835,"path":836,"stem":837,"children":838},"Scaffolding","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Fscaffolding","docs\u002Ftooling\u002Fcommand-line\u002Fscaffolding\u002Findex",[839],{"title":835,"path":836,"stem":837},{"title":841,"path":842,"stem":843,"children":844},"Scripting & output","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Fscripting","docs\u002Ftooling\u002Fcommand-line\u002Fscripting\u002Findex",[845],{"title":841,"path":842,"stem":843},{"title":847,"path":848,"stem":849,"children":850},"Skills","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Fskills","docs\u002Ftooling\u002Fcommand-line\u002Fskills\u002Findex",[851],{"title":847,"path":848,"stem":849},{"title":853,"path":854,"stem":855,"children":856},"Full-screen app (TUI)","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Ftui","docs\u002Ftooling\u002Fcommand-line\u002Ftui\u002Findex",[857],{"title":853,"path":854,"stem":855},{"title":859,"path":860,"stem":861,"children":862},"Type generation","\u002Fdocs\u002Ftooling\u002Fcommand-line\u002Ftype-generation","docs\u002Ftooling\u002Fcommand-line\u002Ftype-generation\u002Findex",[863],{"title":859,"path":860,"stem":861},{"title":865,"path":866,"stem":867,"children":868},"Model Context Protocol","\u002Fdocs\u002Ftooling\u002Fmcp","docs\u002Ftooling\u002Fmcp\u002Findex",[869,870,876,882,888,894,900,906,912],{"title":865,"path":866,"stem":867},{"title":871,"path":872,"stem":873,"children":874},"revenexx docs MCP in Google Antigravity","\u002Fdocs\u002Ftooling\u002Fmcp\u002Fantigravity","docs\u002Ftooling\u002Fmcp\u002Fantigravity\u002Findex",[875],{"title":871,"path":872,"stem":873},{"title":877,"path":878,"stem":879,"children":880},"revenexx docs MCP in Claude Code","\u002Fdocs\u002Ftooling\u002Fmcp\u002Fclaude-code","docs\u002Ftooling\u002Fmcp\u002Fclaude-code\u002Findex",[881],{"title":877,"path":878,"stem":879},{"title":883,"path":884,"stem":885,"children":886},"revenexx docs MCP in Claude Desktop","\u002Fdocs\u002Ftooling\u002Fmcp\u002Fclaude-desktop","docs\u002Ftooling\u002Fmcp\u002Fclaude-desktop\u002Findex",[887],{"title":883,"path":884,"stem":885},{"title":889,"path":890,"stem":891,"children":892},"revenexx docs MCP in Cursor","\u002Fdocs\u002Ftooling\u002Fmcp\u002Fcursor","docs\u002Ftooling\u002Fmcp\u002Fcursor\u002Findex",[893],{"title":889,"path":890,"stem":891},{"title":895,"path":896,"stem":897,"children":898},"revenexx docs MCP in OpenCode","\u002Fdocs\u002Ftooling\u002Fmcp\u002Fopencode","docs\u002Ftooling\u002Fmcp\u002Fopencode\u002Findex",[899],{"title":895,"path":896,"stem":897},{"title":901,"path":902,"stem":903,"children":904},"revenexx docs MCP in VS Code","\u002Fdocs\u002Ftooling\u002Fmcp\u002Fvscode","docs\u002Ftooling\u002Fmcp\u002Fvscode\u002Findex",[905],{"title":901,"path":902,"stem":903},{"title":907,"path":908,"stem":909,"children":910},"revenexx docs MCP in Windsurf","\u002Fdocs\u002Ftooling\u002Fmcp\u002Fwindsurf","docs\u002Ftooling\u002Fmcp\u002Fwindsurf\u002Findex",[911],{"title":907,"path":908,"stem":909},{"title":913,"path":914,"stem":915,"children":916},"revenexx docs MCP in Zenflow","\u002Fdocs\u002Ftooling\u002Fmcp\u002Fzenflow","docs\u002Ftooling\u002Fmcp\u002Fzenflow\u002Findex",[917],{"title":913,"path":914,"stem":915},{"title":919,"path":920,"stem":921,"children":922},"Tutorials","\u002Fdocs\u002Ftutorials","docs\u002Ftutorials\u002Findex",[923,924,948,954],{"title":919,"path":920,"stem":921},{"title":925,"path":926,"stem":927,"children":928},"Build a revenexx App","\u002Fdocs\u002Ftutorials\u002Fapps","docs\u002Ftutorials\u002Fapps\u002Findex",[929,930,936,942],{"title":925,"path":926,"stem":927},{"title":931,"path":932,"stem":933,"children":934},"Add a data model","\u002Fdocs\u002Ftutorials\u002Fapps\u002Fadd-a-data-model","docs\u002Ftutorials\u002Fapps\u002Fadd-a-data-model\u002Findex",[935],{"title":931,"path":932,"stem":933},{"title":937,"path":938,"stem":939,"children":940},"Build your first app","\u002Fdocs\u002Ftutorials\u002Fapps\u002Fbuild-your-first-app","docs\u002Ftutorials\u002Fapps\u002Fbuild-your-first-app\u002Findex",[941],{"title":937,"path":938,"stem":939},{"title":943,"path":944,"stem":945,"children":946},"Deploy with the CLI","\u002Fdocs\u002Ftutorials\u002Fapps\u002Fdeploy-with-the-cli","docs\u002Ftutorials\u002Fapps\u002Fdeploy-with-the-cli\u002Findex",[947],{"title":943,"path":944,"stem":945},{"title":949,"path":950,"stem":951,"children":952},"Examples","\u002Fdocs\u002Ftutorials\u002Fexamples","docs\u002Ftutorials\u002Fexamples\u002Findex",[953],{"title":949,"path":950,"stem":951},{"title":955,"path":956,"stem":957,"children":958},"Build a storefront Theme","\u002Fdocs\u002Ftutorials\u002Fthemes","docs\u002Ftutorials\u002Fthemes\u002Findex",[959,960,966,972,978],{"title":955,"path":956,"stem":957},{"title":961,"path":962,"stem":963,"children":964},"Build your first Theme","\u002Fdocs\u002Ftutorials\u002Fthemes\u002Fbuild-your-first-theme","docs\u002Ftutorials\u002Fthemes\u002Fbuild-your-first-theme\u002Findex",[965],{"title":961,"path":962,"stem":963},{"title":967,"path":968,"stem":969,"children":970},"Customize blocks","\u002Fdocs\u002Ftutorials\u002Fthemes\u002Fcustomize-blocks","docs\u002Ftutorials\u002Fthemes\u002Fcustomize-blocks\u002Findex",[971],{"title":967,"path":968,"stem":969},{"title":973,"path":974,"stem":975,"children":976},"Deploy your storefront","\u002Fdocs\u002Ftutorials\u002Fthemes\u002Fdeploy-your-storefront","docs\u002Ftutorials\u002Fthemes\u002Fdeploy-your-storefront\u002Findex",[977],{"title":973,"path":974,"stem":975},{"title":979,"path":980,"stem":981,"children":982},"Theme tokens and styling","\u002Fdocs\u002Ftutorials\u002Fthemes\u002Ftheme-tokens-and-styling","docs\u002Ftutorials\u002Fthemes\u002Ftheme-tokens-and-styling\u002Findex",[983],{"title":979,"path":980,"stem":981},{"id":985,"title":327,"body":986,"description":2968,"extension":2969,"landing":2970,"links":2970,"meta":2971,"navigation":1696,"path":328,"seo":2973,"sitemap":2974,"stem":329,"__hash__":2975},"docs\u002Fdocs\u002Fproducts\u002Fsites\u002Farchitecture\u002Findex.md",{"type":987,"value":988,"toc":2953},"minimark",[989,998,1013,1018,1021,1065,1068,1078,1082,1089,1094,1100,1105,1112,1213,1217,1228,1255,1258,1564,1570,1754,1758,1765,1775,2102,2116,2120,2123,2128,2131,2287,2290,2301,2305,2313,2568,2573,2741,2745,2756,2903,2906,2910,2913,2917,2920,2924,2949],[990,991,992,993,997],"p",{},"This page is for ",[994,995,996],"strong",{},"frontend developers"," about to start a storefront project — usually at a partner agency or on a customer's product team. It explains the technical stack you'll be working with, why each piece is there, and how the storefront fits into the rest of the platform.",[990,999,1000,1001,1004,1005,1008,1009,1012],{},"If you already know Nuxt 4 well, most of this will look familiar. The revenexx-specific parts are the ",[994,1002,1003],{},"BFF pattern"," between the browser and the platform APIs (the part you write that sits between user-facing pages and the catalog\u002Forders\u002Fetc. APIs), how the storefront's data is ",[994,1006,1007],{},"automatically scoped to its tenant",", and the ",[994,1010,1011],{},"Blökkli integration"," for visual page composition (currently in preview as part of PO-46 — treat the Blökkli specifics as planned rather than shipped).",[1014,1015,1017],"h2",{"id":1016},"what-youre-building-on","What you're building on",[990,1019,1020],{},"The default storefront template is a Nuxt 4 application, and five pieces do most of the work. Each one is there for a reason — together they're what lets the same codebase serve many customers without a rewrite per project.",[1022,1023,1024,1031,1037,1053,1059],"ul",{},[1025,1026,1027,1030],"li",{},[994,1028,1029],{},"Nuxt 4"," — the Vue 3 meta-framework the whole storefront runs on, server-rendered by default. It gives you file-based routing, server routes for the BFF layer, and per-route rendering modes (static, dynamic, ISR), so you can serve a product page from cache and a cart page live without two different stacks.",[1025,1032,1033,1036],{},[994,1034,1035],{},"Nuxt UI"," — the accessible, unstyled component library the standard template builds its product cards, forms, and navigation from. It's a starting point, not a cage: if a customer's design system is fundamentally different, you can swap it out.",[1025,1038,1039,1042,1043,1047,1048,1052],{},[994,1040,1041],{},"Blökkli"," ",[1044,1045,1046],"em",{},"(preview, PO-46)"," — the visual page builder. Marketing teams compose Hero, ProductGrid, FAQ, and custom blocks in Cockpit, and the storefront renders them by mapping each block's ",[1049,1050,1051],"code",{},"type"," to a Vue component — so content people change pages without touching code.",[1025,1054,1055,1058],{},[994,1056,1057],{},"Formily"," — schema-driven forms, leaned on heavily in checkout. Because a form is defined by a JSON schema rather than hand-written markup, you can change which fields a customer's checkout collects by editing config instead of rebuilding components.",[1025,1060,1061,1064],{},[994,1062,1063],{},"Platform APIs"," — the REST and GraphQL endpoints the platform generates automatically from your app's tables, with every response automatically scoped to the tenant. This is where your data comes from; you consume it rather than building it.",[1014,1066,57],{"id":1067},"architecture-overview",[1069,1070,1075],"pre",{"className":1071,"code":1073,"language":1074},[1072],"language-text","┌─────────────────────────────────────────┐\n│        Customer Browser                 │\n│  (Desktop \u002F Mobile \u002F PWA)               │\n└────────────────┬────────────────────────┘\n                 │\n         HTTP\u002FHTTPS (SSR\u002FCSR)\n                 │\n┌─────────────────▼────────────────────────┐\n│      Nuxt 4 Storefront (BFF)            │\n│  ┌──────────────────────────────────┐   │\n│  │  File-based Routing              │   │\n│  │  \u002Fproducts  \u002Fcheckout  \u002Faccount  │   │\n│  └──────────────────────────────────┘   │\n│  ┌──────────────────────────────────┐   │\n│  │  Blökkli Pages (Editable)        │   │\n│  │  Homepage \u002F Category \u002F CMS       │   │\n│  └──────────────────────────────────┘   │\n│  ┌──────────────────────────────────┐   │\n│  │  BFF Layer                       │   │\n│  │  - Cart aggregation              │   │\n│  │  - Checkout orchestration        │   │\n│  │  - Authentication                │   │\n│  └──────────────────────────────────┘   │\n└─────────────────┬────────────────────────┘\n                  │\n    GraphQL \u002F REST (tenant-scoped)\n                  │\n    ┌─────────────┼─────────────┐\n    │             │             │\n    ▼             ▼             ▼\n┌────────┐  ┌────────┐  ┌────────────┐\n│ Cockpit│  │ Catalog│  │ Orders App │\n│(Content)│ │ (SKUs) │  │(tenant-    │\n│        │  │        │  │ scoped)    │\n└────────┘  └────────┘  └────────────┘\n    │             │             │\n    └─────────────┼─────────────┘\n                  │\n       Platform data (tenant-scoped)\n","text",[1049,1076,1073],{"__ignoreMap":1077},"",[1014,1079,1081],{"id":1080},"file-based-routing","File-Based Routing",[990,1083,1084,1085,1088],{},"Nuxt's file-based routing automatically creates routes from your ",[1049,1086,1087],{},"pages\u002F"," directory structure.",[990,1090,1091],{},[994,1092,1093],{},"Directory → Route Mapping:",[1069,1095,1098],{"className":1096,"code":1097,"language":1074},[1072],"pages\u002F\n  └─ index.vue                      → \u002F\n  └─ products\u002F\n     └─ index.vue                   → \u002Fproducts\n     └─ [id].vue                    → \u002Fproducts\u002F:id\n  └─ checkout\u002F\n     └─ index.vue                   → \u002Fcheckout\n     └─ [step].vue                  → \u002Fcheckout\u002F:step\n  └─ account\u002F\n     └─ index.vue                   → \u002Faccount\n     └─ orders.vue                  → \u002Faccount\u002Forders\n     └─ settings.vue                → \u002Faccount\u002Fsettings\n",[1049,1099,1097],{"__ignoreMap":1077},[990,1101,1102],{},[994,1103,1104],{},"Dynamic Routes:",[990,1106,1107,1108,1111],{},"Pages with ",[1049,1109,1110],{},"[id].vue"," create a catch-all route that passes the segment as a parameter:",[1069,1113,1117],{"className":1114,"code":1115,"language":1116,"meta":1077,"style":1077},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup>\nconst route = useRoute()\nconst productId = route.params.id\nconst product = await fetchProduct(productId)\n\u003C\u002Fscript>\n","vue",[1049,1118,1119,1139,1159,1183,1203],{"__ignoreMap":1077},[1120,1121,1124,1128,1132,1136],"span",{"class":1122,"line":1123},"line",1,[1120,1125,1127],{"class":1126},"sMK4o","\u003C",[1120,1129,1131],{"class":1130},"swJcz","script",[1120,1133,1135],{"class":1134},"spNyl"," setup",[1120,1137,1138],{"class":1126},">\n",[1120,1140,1142,1145,1149,1152,1156],{"class":1122,"line":1141},2,[1120,1143,1144],{"class":1134},"const",[1120,1146,1148],{"class":1147},"sTEyZ"," route ",[1120,1150,1151],{"class":1126},"=",[1120,1153,1155],{"class":1154},"s2Zo4"," useRoute",[1120,1157,1158],{"class":1147},"()\n",[1120,1160,1162,1164,1167,1169,1172,1175,1178,1180],{"class":1122,"line":1161},3,[1120,1163,1144],{"class":1134},[1120,1165,1166],{"class":1147}," productId ",[1120,1168,1151],{"class":1126},[1120,1170,1171],{"class":1147}," route",[1120,1173,1174],{"class":1126},".",[1120,1176,1177],{"class":1147},"params",[1120,1179,1174],{"class":1126},[1120,1181,1182],{"class":1147},"id\n",[1120,1184,1186,1188,1191,1193,1197,1200],{"class":1122,"line":1185},4,[1120,1187,1144],{"class":1134},[1120,1189,1190],{"class":1147}," product ",[1120,1192,1151],{"class":1126},[1120,1194,1196],{"class":1195},"s7zQu"," await",[1120,1198,1199],{"class":1154}," fetchProduct",[1120,1201,1202],{"class":1147},"(productId)\n",[1120,1204,1206,1209,1211],{"class":1122,"line":1205},5,[1120,1207,1208],{"class":1126},"\u003C\u002F",[1120,1210,1131],{"class":1130},[1120,1212,1138],{"class":1126},[1014,1214,1216],{"id":1215},"blökkli-visual-page-composition","Blökkli: Visual Page Composition",[990,1218,1219,1220,1223,1224,1227],{},"Blökkli is a headless page builder that lets non-developers compose pages by dragging and dropping pre-built blocks. The reason it matters architecturally is the division of labour it creates: marketing owns the ",[1044,1221,1222],{},"content and layout"," of a page, while you own the ",[1044,1225,1226],{},"blocks"," it's assembled from. A page is never code a developer has to ship — it's data the marketing team edits.",[990,1229,1230,1231,1234,1235,1238,1239,1242,1243,1246,1247,1250,1251,1254],{},"The standard library covers the blocks most storefronts need — a ",[994,1232,1233],{},"Hero"," banner with image, headline, and CTA; a ",[994,1236,1237],{},"ProductGrid"," that renders the catalog with filters and sorting; ",[994,1240,1241],{},"Testimonials",", ",[994,1244,1245],{},"Newsletter"," signup, ",[994,1248,1249],{},"FAQ",", and ",[994,1252,1253],{},"Navigation"," blocks — and you can extend it with your own Vue components, which then appear in the editor as block types like any other.",[990,1256,1257],{},"The flow has three stages. First, each page lives as a JSON tree of blocks stored in Cockpit content — a title, a slug, and an ordered list of blocks with their props:",[1069,1259,1263],{"className":1260,"code":1261,"language":1262,"meta":1077,"style":1077},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"title\": \"Clearance Sale\",\n  \"slug\": \"clearance-sale\",\n  \"blocks\": [\n    {\n      \"type\": \"hero\",\n      \"props\": {\n        \"title\": \"Up to 70% Off\",\n        \"image\": \"url\u002Fto\u002Fbanner.jpg\",\n        \"cta_url\": \"\u002Fproducts?sale=true\"\n      }\n    },\n    {\n      \"type\": \"productGrid\",\n      \"props\": {\n        \"category\": \"clearance\",\n        \"per_page\": 12,\n        \"sort\": \"price-asc\"\n      }\n    }\n  ]\n}\n","json",[1049,1264,1265,1270,1296,1316,1329,1334,1356,1371,1393,1414,1434,1440,1446,1451,1471,1484,1505,1522,1541,1546,1552,1558],{"__ignoreMap":1077},[1120,1266,1267],{"class":1122,"line":1123},[1120,1268,1269],{"class":1126},"{\n",[1120,1271,1272,1275,1278,1281,1284,1287,1291,1293],{"class":1122,"line":1141},[1120,1273,1274],{"class":1126},"  \"",[1120,1276,1277],{"class":1134},"title",[1120,1279,1280],{"class":1126},"\"",[1120,1282,1283],{"class":1126},":",[1120,1285,1286],{"class":1126}," \"",[1120,1288,1290],{"class":1289},"sfazB","Clearance Sale",[1120,1292,1280],{"class":1126},[1120,1294,1295],{"class":1126},",\n",[1120,1297,1298,1300,1303,1305,1307,1309,1312,1314],{"class":1122,"line":1161},[1120,1299,1274],{"class":1126},[1120,1301,1302],{"class":1134},"slug",[1120,1304,1280],{"class":1126},[1120,1306,1283],{"class":1126},[1120,1308,1286],{"class":1126},[1120,1310,1311],{"class":1289},"clearance-sale",[1120,1313,1280],{"class":1126},[1120,1315,1295],{"class":1126},[1120,1317,1318,1320,1322,1324,1326],{"class":1122,"line":1185},[1120,1319,1274],{"class":1126},[1120,1321,1226],{"class":1134},[1120,1323,1280],{"class":1126},[1120,1325,1283],{"class":1126},[1120,1327,1328],{"class":1126}," [\n",[1120,1330,1331],{"class":1122,"line":1205},[1120,1332,1333],{"class":1126},"    {\n",[1120,1335,1337,1340,1343,1345,1347,1349,1352,1354],{"class":1122,"line":1336},6,[1120,1338,1339],{"class":1126},"      \"",[1120,1341,1051],{"class":1342},"sBMFI",[1120,1344,1280],{"class":1126},[1120,1346,1283],{"class":1126},[1120,1348,1286],{"class":1126},[1120,1350,1351],{"class":1289},"hero",[1120,1353,1280],{"class":1126},[1120,1355,1295],{"class":1126},[1120,1357,1359,1361,1364,1366,1368],{"class":1122,"line":1358},7,[1120,1360,1339],{"class":1126},[1120,1362,1363],{"class":1342},"props",[1120,1365,1280],{"class":1126},[1120,1367,1283],{"class":1126},[1120,1369,1370],{"class":1126}," {\n",[1120,1372,1374,1377,1380,1382,1384,1386,1389,1391],{"class":1122,"line":1373},8,[1120,1375,1376],{"class":1126},"        \"",[1120,1378,1277],{"class":1379},"sbssI",[1120,1381,1280],{"class":1126},[1120,1383,1283],{"class":1126},[1120,1385,1286],{"class":1126},[1120,1387,1388],{"class":1289},"Up to 70% Off",[1120,1390,1280],{"class":1126},[1120,1392,1295],{"class":1126},[1120,1394,1396,1398,1401,1403,1405,1407,1410,1412],{"class":1122,"line":1395},9,[1120,1397,1376],{"class":1126},[1120,1399,1400],{"class":1379},"image",[1120,1402,1280],{"class":1126},[1120,1404,1283],{"class":1126},[1120,1406,1286],{"class":1126},[1120,1408,1409],{"class":1289},"url\u002Fto\u002Fbanner.jpg",[1120,1411,1280],{"class":1126},[1120,1413,1295],{"class":1126},[1120,1415,1417,1419,1422,1424,1426,1428,1431],{"class":1122,"line":1416},10,[1120,1418,1376],{"class":1126},[1120,1420,1421],{"class":1379},"cta_url",[1120,1423,1280],{"class":1126},[1120,1425,1283],{"class":1126},[1120,1427,1286],{"class":1126},[1120,1429,1430],{"class":1289},"\u002Fproducts?sale=true",[1120,1432,1433],{"class":1126},"\"\n",[1120,1435,1437],{"class":1122,"line":1436},11,[1120,1438,1439],{"class":1126},"      }\n",[1120,1441,1443],{"class":1122,"line":1442},12,[1120,1444,1445],{"class":1126},"    },\n",[1120,1447,1449],{"class":1122,"line":1448},13,[1120,1450,1333],{"class":1126},[1120,1452,1454,1456,1458,1460,1462,1464,1467,1469],{"class":1122,"line":1453},14,[1120,1455,1339],{"class":1126},[1120,1457,1051],{"class":1342},[1120,1459,1280],{"class":1126},[1120,1461,1283],{"class":1126},[1120,1463,1286],{"class":1126},[1120,1465,1466],{"class":1289},"productGrid",[1120,1468,1280],{"class":1126},[1120,1470,1295],{"class":1126},[1120,1472,1474,1476,1478,1480,1482],{"class":1122,"line":1473},15,[1120,1475,1339],{"class":1126},[1120,1477,1363],{"class":1342},[1120,1479,1280],{"class":1126},[1120,1481,1283],{"class":1126},[1120,1483,1370],{"class":1126},[1120,1485,1487,1489,1492,1494,1496,1498,1501,1503],{"class":1122,"line":1486},16,[1120,1488,1376],{"class":1126},[1120,1490,1491],{"class":1379},"category",[1120,1493,1280],{"class":1126},[1120,1495,1283],{"class":1126},[1120,1497,1286],{"class":1126},[1120,1499,1500],{"class":1289},"clearance",[1120,1502,1280],{"class":1126},[1120,1504,1295],{"class":1126},[1120,1506,1508,1510,1513,1515,1517,1520],{"class":1122,"line":1507},17,[1120,1509,1376],{"class":1126},[1120,1511,1512],{"class":1379},"per_page",[1120,1514,1280],{"class":1126},[1120,1516,1283],{"class":1126},[1120,1518,1519],{"class":1379}," 12",[1120,1521,1295],{"class":1126},[1120,1523,1525,1527,1530,1532,1534,1536,1539],{"class":1122,"line":1524},18,[1120,1526,1376],{"class":1126},[1120,1528,1529],{"class":1379},"sort",[1120,1531,1280],{"class":1126},[1120,1533,1283],{"class":1126},[1120,1535,1286],{"class":1126},[1120,1537,1538],{"class":1289},"price-asc",[1120,1540,1433],{"class":1126},[1120,1542,1544],{"class":1122,"line":1543},19,[1120,1545,1439],{"class":1126},[1120,1547,1549],{"class":1122,"line":1548},20,[1120,1550,1551],{"class":1126},"    }\n",[1120,1553,1555],{"class":1122,"line":1554},21,[1120,1556,1557],{"class":1126},"  ]\n",[1120,1559,1561],{"class":1122,"line":1560},22,[1120,1562,1563],{"class":1126},"}\n",[990,1565,1566,1567,1569],{},"Second, the marketing team edits that tree visually in Cockpit — they never see the JSON. Third, the storefront fetches the page and renders it by walking the block list and mapping each ",[1049,1568,1051],{}," to a registered component:",[1069,1571,1573],{"className":1114,"code":1572,"language":1116,"meta":1077,"style":1077},"\u003Ctemplate>\n  \u003Cdiv class=\"page\">\n    \u003Ccomponent\n      v-for=\"block in page.blocks\"\n      :key=\"block.id\"\n      :is=\"`Block${block.type}`\"\n      :props=\"block.props\"\n    \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nconst route = useRoute()\nconst page = await fetchBlökkliPage(route.params.slug)\n\u003C\u002Fscript>\n",[1049,1574,1575,1584,1606,1614,1628,1642,1656,1670,1675,1684,1692,1698,1708,1720,1746],{"__ignoreMap":1077},[1120,1576,1577,1579,1582],{"class":1122,"line":1123},[1120,1578,1127],{"class":1126},[1120,1580,1581],{"class":1130},"template",[1120,1583,1138],{"class":1126},[1120,1585,1586,1589,1592,1595,1597,1599,1602,1604],{"class":1122,"line":1141},[1120,1587,1588],{"class":1126},"  \u003C",[1120,1590,1591],{"class":1130},"div",[1120,1593,1594],{"class":1134}," class",[1120,1596,1151],{"class":1126},[1120,1598,1280],{"class":1126},[1120,1600,1601],{"class":1289},"page",[1120,1603,1280],{"class":1126},[1120,1605,1138],{"class":1126},[1120,1607,1608,1611],{"class":1122,"line":1161},[1120,1609,1610],{"class":1126},"    \u003C",[1120,1612,1613],{"class":1130},"component\n",[1120,1615,1616,1619,1621,1623,1626],{"class":1122,"line":1185},[1120,1617,1618],{"class":1134},"      v-for",[1120,1620,1151],{"class":1126},[1120,1622,1280],{"class":1126},[1120,1624,1625],{"class":1289},"block in page.blocks",[1120,1627,1433],{"class":1126},[1120,1629,1630,1633,1635,1637,1640],{"class":1122,"line":1205},[1120,1631,1632],{"class":1134},"      :key",[1120,1634,1151],{"class":1126},[1120,1636,1280],{"class":1126},[1120,1638,1639],{"class":1289},"block.id",[1120,1641,1433],{"class":1126},[1120,1643,1644,1647,1649,1651,1654],{"class":1122,"line":1336},[1120,1645,1646],{"class":1134},"      :is",[1120,1648,1151],{"class":1126},[1120,1650,1280],{"class":1126},[1120,1652,1653],{"class":1289},"`Block${block.type}`",[1120,1655,1433],{"class":1126},[1120,1657,1658,1661,1663,1665,1668],{"class":1122,"line":1358},[1120,1659,1660],{"class":1134},"      :props",[1120,1662,1151],{"class":1126},[1120,1664,1280],{"class":1126},[1120,1666,1667],{"class":1289},"block.props",[1120,1669,1433],{"class":1126},[1120,1671,1672],{"class":1122,"line":1373},[1120,1673,1674],{"class":1126},"    \u002F>\n",[1120,1676,1677,1680,1682],{"class":1122,"line":1395},[1120,1678,1679],{"class":1126},"  \u003C\u002F",[1120,1681,1591],{"class":1130},[1120,1683,1138],{"class":1126},[1120,1685,1686,1688,1690],{"class":1122,"line":1416},[1120,1687,1208],{"class":1126},[1120,1689,1581],{"class":1130},[1120,1691,1138],{"class":1126},[1120,1693,1694],{"class":1122,"line":1436},[1120,1695,1697],{"emptyLinePlaceholder":1696},true,"\n",[1120,1699,1700,1702,1704,1706],{"class":1122,"line":1442},[1120,1701,1127],{"class":1126},[1120,1703,1131],{"class":1130},[1120,1705,1135],{"class":1134},[1120,1707,1138],{"class":1126},[1120,1709,1710,1712,1714,1716,1718],{"class":1122,"line":1448},[1120,1711,1144],{"class":1134},[1120,1713,1148],{"class":1147},[1120,1715,1151],{"class":1126},[1120,1717,1155],{"class":1154},[1120,1719,1158],{"class":1147},[1120,1721,1722,1724,1727,1729,1731,1734,1737,1739,1741,1743],{"class":1122,"line":1453},[1120,1723,1144],{"class":1134},[1120,1725,1726],{"class":1147}," page ",[1120,1728,1151],{"class":1126},[1120,1730,1196],{"class":1195},[1120,1732,1733],{"class":1154}," fetchBlökkliPage",[1120,1735,1736],{"class":1147},"(route",[1120,1738,1174],{"class":1126},[1120,1740,1177],{"class":1147},[1120,1742,1174],{"class":1126},[1120,1744,1745],{"class":1147},"slug)\n",[1120,1747,1748,1750,1752],{"class":1122,"line":1473},[1120,1749,1208],{"class":1126},[1120,1751,1131],{"class":1130},[1120,1753,1138],{"class":1126},[1014,1755,1757],{"id":1756},"backend-for-frontend-bff-pattern","Backend-for-Frontend (BFF) Pattern",[990,1759,1760,1761,1764],{},"This is the most important revenexx-specific idea on the page. The storefront doesn't talk to the platform's core APIs straight from the browser; it has a server layer of its own — the ",[994,1762,1763],{},"backend-for-frontend"," — that sits in between. That layer exists because the browser and the platform APIs want different things: the browser wants one tidy response shaped for the page it's rendering, while the platform exposes several granular, normalized APIs. The BFF is where you bridge that gap, and it's also where anything secret or sensitive stays, safely server-side. Four jobs land here on most projects.",[990,1766,1767,1770,1771,1774],{},[994,1768,1769],{},"Cart aggregation"," is the clearest example. A cart on screen needs product details from the Catalog API and live stock from the Orders API, combined into a single object the page can render, with the cart's own state synced between ",[1049,1772,1773],{},"localStorage"," and the server. Rather than make the browser fire several calls and stitch the results together, a server route does it once:",[1069,1776,1780],{"className":1777,"code":1778,"language":1779,"meta":1077,"style":1077},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Storefront server-side (Nuxt server route)\nexport default defineEventHandler(async (event) => {\n  const cartItems = getCookie(event, 'cart') || []\n  const products = await cockpit.catalog.getProducts(cartItems.map(i => i.id))\n  const inventory = await cockpit.orders.checkInventory(cartItems)\n  \n  return {\n    items: cartItems.map(item => ({\n      ...item,\n      product: products.find(p => p.id === item.id),\n      in_stock: inventory[item.id]?.available > 0\n    })),\n    total: calculateTotal(cartItems, products)\n  }\n})\n","typescript",[1049,1781,1782,1788,1820,1859,1911,1941,1946,1953,1977,1986,2027,2060,2070,2090,2095],{"__ignoreMap":1077},[1120,1783,1784],{"class":1122,"line":1123},[1120,1785,1787],{"class":1786},"sHwdD","\u002F\u002F Storefront server-side (Nuxt server route)\n",[1120,1789,1790,1793,1796,1799,1802,1805,1808,1812,1815,1818],{"class":1122,"line":1141},[1120,1791,1792],{"class":1195},"export",[1120,1794,1795],{"class":1195}," default",[1120,1797,1798],{"class":1154}," defineEventHandler",[1120,1800,1801],{"class":1147},"(",[1120,1803,1804],{"class":1134},"async",[1120,1806,1807],{"class":1126}," (",[1120,1809,1811],{"class":1810},"sHdIc","event",[1120,1813,1814],{"class":1126},")",[1120,1816,1817],{"class":1134}," =>",[1120,1819,1370],{"class":1126},[1120,1821,1822,1825,1828,1831,1834,1836,1838,1841,1844,1847,1850,1853,1856],{"class":1122,"line":1161},[1120,1823,1824],{"class":1134},"  const",[1120,1826,1827],{"class":1147}," cartItems",[1120,1829,1830],{"class":1126}," =",[1120,1832,1833],{"class":1154}," getCookie",[1120,1835,1801],{"class":1130},[1120,1837,1811],{"class":1147},[1120,1839,1840],{"class":1126},",",[1120,1842,1843],{"class":1126}," '",[1120,1845,1846],{"class":1289},"cart",[1120,1848,1849],{"class":1126},"'",[1120,1851,1852],{"class":1130},") ",[1120,1854,1855],{"class":1126},"||",[1120,1857,1858],{"class":1130}," []\n",[1120,1860,1861,1863,1866,1868,1870,1873,1875,1878,1880,1883,1885,1888,1890,1893,1895,1898,1900,1903,1905,1908],{"class":1122,"line":1185},[1120,1862,1824],{"class":1134},[1120,1864,1865],{"class":1147}," products",[1120,1867,1830],{"class":1126},[1120,1869,1196],{"class":1195},[1120,1871,1872],{"class":1147}," cockpit",[1120,1874,1174],{"class":1126},[1120,1876,1877],{"class":1147},"catalog",[1120,1879,1174],{"class":1126},[1120,1881,1882],{"class":1154},"getProducts",[1120,1884,1801],{"class":1130},[1120,1886,1887],{"class":1147},"cartItems",[1120,1889,1174],{"class":1126},[1120,1891,1892],{"class":1154},"map",[1120,1894,1801],{"class":1130},[1120,1896,1897],{"class":1810},"i",[1120,1899,1817],{"class":1134},[1120,1901,1902],{"class":1147}," i",[1120,1904,1174],{"class":1126},[1120,1906,1907],{"class":1147},"id",[1120,1909,1910],{"class":1130},"))\n",[1120,1912,1913,1915,1918,1920,1922,1924,1926,1929,1931,1934,1936,1938],{"class":1122,"line":1205},[1120,1914,1824],{"class":1134},[1120,1916,1917],{"class":1147}," inventory",[1120,1919,1830],{"class":1126},[1120,1921,1196],{"class":1195},[1120,1923,1872],{"class":1147},[1120,1925,1174],{"class":1126},[1120,1927,1928],{"class":1147},"orders",[1120,1930,1174],{"class":1126},[1120,1932,1933],{"class":1154},"checkInventory",[1120,1935,1801],{"class":1130},[1120,1937,1887],{"class":1147},[1120,1939,1940],{"class":1130},")\n",[1120,1942,1943],{"class":1122,"line":1336},[1120,1944,1945],{"class":1130},"  \n",[1120,1947,1948,1951],{"class":1122,"line":1358},[1120,1949,1950],{"class":1195},"  return",[1120,1952,1370],{"class":1126},[1120,1954,1955,1958,1960,1962,1964,1966,1968,1971,1973,1975],{"class":1122,"line":1373},[1120,1956,1957],{"class":1130},"    items",[1120,1959,1283],{"class":1126},[1120,1961,1827],{"class":1147},[1120,1963,1174],{"class":1126},[1120,1965,1892],{"class":1154},[1120,1967,1801],{"class":1130},[1120,1969,1970],{"class":1810},"item",[1120,1972,1817],{"class":1134},[1120,1974,1807],{"class":1130},[1120,1976,1269],{"class":1126},[1120,1978,1979,1982,1984],{"class":1122,"line":1395},[1120,1980,1981],{"class":1126},"      ...",[1120,1983,1970],{"class":1147},[1120,1985,1295],{"class":1126},[1120,1987,1988,1991,1993,1995,1997,2000,2002,2004,2006,2009,2011,2013,2016,2019,2021,2023,2025],{"class":1122,"line":1416},[1120,1989,1990],{"class":1130},"      product",[1120,1992,1283],{"class":1126},[1120,1994,1865],{"class":1147},[1120,1996,1174],{"class":1126},[1120,1998,1999],{"class":1154},"find",[1120,2001,1801],{"class":1130},[1120,2003,990],{"class":1810},[1120,2005,1817],{"class":1134},[1120,2007,2008],{"class":1147}," p",[1120,2010,1174],{"class":1126},[1120,2012,1907],{"class":1147},[1120,2014,2015],{"class":1126}," ===",[1120,2017,2018],{"class":1147}," item",[1120,2020,1174],{"class":1126},[1120,2022,1907],{"class":1147},[1120,2024,1814],{"class":1130},[1120,2026,1295],{"class":1126},[1120,2028,2029,2032,2034,2036,2039,2041,2043,2045,2048,2051,2054,2057],{"class":1122,"line":1436},[1120,2030,2031],{"class":1130},"      in_stock",[1120,2033,1283],{"class":1126},[1120,2035,1917],{"class":1147},[1120,2037,2038],{"class":1130},"[",[1120,2040,1970],{"class":1147},[1120,2042,1174],{"class":1126},[1120,2044,1907],{"class":1147},[1120,2046,2047],{"class":1130},"]",[1120,2049,2050],{"class":1126},"?.",[1120,2052,2053],{"class":1147},"available",[1120,2055,2056],{"class":1126}," >",[1120,2058,2059],{"class":1379}," 0\n",[1120,2061,2062,2065,2068],{"class":1122,"line":1442},[1120,2063,2064],{"class":1126},"    }",[1120,2066,2067],{"class":1130},"))",[1120,2069,1295],{"class":1126},[1120,2071,2072,2075,2077,2080,2082,2084,2086,2088],{"class":1122,"line":1448},[1120,2073,2074],{"class":1130},"    total",[1120,2076,1283],{"class":1126},[1120,2078,2079],{"class":1154}," calculateTotal",[1120,2081,1801],{"class":1130},[1120,2083,1887],{"class":1147},[1120,2085,1840],{"class":1126},[1120,2087,1865],{"class":1147},[1120,2089,1940],{"class":1130},[1120,2091,2092],{"class":1122,"line":1453},[1120,2093,2094],{"class":1126},"  }\n",[1120,2096,2097,2100],{"class":1122,"line":1473},[1120,2098,2099],{"class":1126},"}",[1120,2101,1940],{"class":1147},[990,2103,2104,2107,2108,2111,2112,2115],{},[994,2105,2106],{},"Checkout orchestration"," is the second job, and the most delicate: the BFF runs the multi-step validation across address, payment, and confirmation, coordinates between the payment gateway and the orders service, and rolls the transaction back if any step fails — logic that has no business running in the browser. ",[994,2109,2110],{},"Authentication and session"," is the third: login and logout flows, issuing and validating session tokens, and keeping each customer pinned to the right tenant. And ",[994,2113,2114],{},"search"," is the fourth, where the BFF handles pagination, filtering, faceted search across category, price, and brand, and integration with the suggest API. In every case the pattern is the same — the browser asks the BFF a page-shaped question, and the BFF does the fan-out to the platform.",[1014,2117,2119],{"id":2118},"security-automatic-tenant-scoping","Security: automatic tenant scoping",[990,2121,2122],{},"All platform API calls from the storefront carry the current tenant. The platform automatically scopes every response to that tenant — your data is scoped to your tenant without any app-level filtering.",[990,2124,2125],{},[994,2126,2127],{},"Example:",[990,2129,2130],{},"Customer A logs into their storefront:",[1069,2132,2134],{"className":1777,"code":2133,"language":1779,"meta":1077,"style":1077},"\u002F\u002F Set tenant context\nconst headers = {\n  'X-Revenexx-Tenant': 'customer-a',\n  'Authorization': `Bearer ${session.token}`\n}\n\n\u002F\u002F The API returns only this tenant's data\nconst products = await fetch('\u002Fgraphql', {\n  headers,\n  body: { query: 'products { id sku price }' }\n})\n\u002F\u002F Returns only products visible to customer-a\n",[1049,2135,2136,2141,2152,2173,2204,2208,2212,2217,2244,2251,2276,2282],{"__ignoreMap":1077},[1120,2137,2138],{"class":1122,"line":1123},[1120,2139,2140],{"class":1786},"\u002F\u002F Set tenant context\n",[1120,2142,2143,2145,2148,2150],{"class":1122,"line":1141},[1120,2144,1144],{"class":1134},[1120,2146,2147],{"class":1147}," headers ",[1120,2149,1151],{"class":1126},[1120,2151,1370],{"class":1126},[1120,2153,2154,2157,2160,2162,2164,2166,2169,2171],{"class":1122,"line":1161},[1120,2155,2156],{"class":1126},"  '",[1120,2158,2159],{"class":1130},"X-Revenexx-Tenant",[1120,2161,1849],{"class":1126},[1120,2163,1283],{"class":1126},[1120,2165,1843],{"class":1126},[1120,2167,2168],{"class":1289},"customer-a",[1120,2170,1849],{"class":1126},[1120,2172,1295],{"class":1126},[1120,2174,2175,2177,2180,2182,2184,2187,2190,2193,2196,2198,2201],{"class":1122,"line":1185},[1120,2176,2156],{"class":1126},[1120,2178,2179],{"class":1130},"Authorization",[1120,2181,1849],{"class":1126},[1120,2183,1283],{"class":1126},[1120,2185,2186],{"class":1126}," `",[1120,2188,2189],{"class":1289},"Bearer ",[1120,2191,2192],{"class":1126},"${",[1120,2194,2195],{"class":1147},"session",[1120,2197,1174],{"class":1126},[1120,2199,2200],{"class":1147},"token",[1120,2202,2203],{"class":1126},"}`\n",[1120,2205,2206],{"class":1122,"line":1205},[1120,2207,1563],{"class":1126},[1120,2209,2210],{"class":1122,"line":1336},[1120,2211,1697],{"emptyLinePlaceholder":1696},[1120,2213,2214],{"class":1122,"line":1358},[1120,2215,2216],{"class":1786},"\u002F\u002F The API returns only this tenant's data\n",[1120,2218,2219,2221,2224,2226,2228,2231,2233,2235,2238,2240,2242],{"class":1122,"line":1373},[1120,2220,1144],{"class":1134},[1120,2222,2223],{"class":1147}," products ",[1120,2225,1151],{"class":1126},[1120,2227,1196],{"class":1195},[1120,2229,2230],{"class":1154}," fetch",[1120,2232,1801],{"class":1147},[1120,2234,1849],{"class":1126},[1120,2236,2237],{"class":1289},"\u002Fgraphql",[1120,2239,1849],{"class":1126},[1120,2241,1840],{"class":1126},[1120,2243,1370],{"class":1126},[1120,2245,2246,2249],{"class":1122,"line":1395},[1120,2247,2248],{"class":1147},"  headers",[1120,2250,1295],{"class":1126},[1120,2252,2253,2256,2258,2261,2264,2266,2268,2271,2273],{"class":1122,"line":1416},[1120,2254,2255],{"class":1130},"  body",[1120,2257,1283],{"class":1126},[1120,2259,2260],{"class":1126}," {",[1120,2262,2263],{"class":1130}," query",[1120,2265,1283],{"class":1126},[1120,2267,1843],{"class":1126},[1120,2269,2270],{"class":1289},"products { id sku price }",[1120,2272,1849],{"class":1126},[1120,2274,2275],{"class":1126}," }\n",[1120,2277,2278,2280],{"class":1122,"line":1436},[1120,2279,2099],{"class":1126},[1120,2281,1940],{"class":1147},[1120,2283,2284],{"class":1122,"line":1442},[1120,2285,2286],{"class":1786},"\u002F\u002F Returns only products visible to customer-a\n",[990,2288,2289],{},"Tenant scoping ensures:",[1022,2291,2292,2295,2298],{},[1025,2293,2294],{},"Customer A never sees Customer B's products",[1025,2296,2297],{},"Each tenant's data is completely isolated",[1025,2299,2300],{},"No cross-tenant leakage possible",[1014,2302,2304],{"id":2303},"styling-nuxt-ui-custom-themes","Styling: Nuxt UI + Custom Themes",[990,2306,2307,2308,2312],{},"Theming runs entirely on CSS custom properties: the palette, typography, and spacing are defined as variables, the template ships a set of built-in themes (Default, Dark, Ocean, Forest, Sunset, Monochrome), and because components read the variables rather than hard-coded values, a customer can switch theme at runtime with no reload. This is the same mechanism the dedicated ",[2309,2310,512],"a",{"href":2311},"\u002Fdocs\u002Fproducts\u002Fsites\u002Ftheming\u002F"," page covers in depth; the short version is that swapping the variable values reskins the whole storefront.",[1069,2314,2316],{"className":1114,"code":2315,"language":1116,"meta":1077,"style":1077},"\u003Cscript setup>\nconst theme = ref('default')\n\nconst setTheme = (newTheme) => {\n  document.documentElement.setAttribute('data-theme', newTheme)\n  theme.value = newTheme\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cselect @change=\"e => setTheme(e.target.value)\">\n    \u003Coption value=\"default\">Default\u003C\u002Foption>\n    \u003Coption value=\"dark\">Dark\u003C\u002Foption>\n    \u003Coption value=\"ocean\">Ocean\u003C\u002Foption>\n  \u003C\u002Fselect>\n\u003C\u002Ftemplate>\n",[1049,2317,2318,2328,2351,2355,2375,2406,2421,2425,2433,2437,2445,2466,2496,2524,2552,2560],{"__ignoreMap":1077},[1120,2319,2320,2322,2324,2326],{"class":1122,"line":1123},[1120,2321,1127],{"class":1126},[1120,2323,1131],{"class":1130},[1120,2325,1135],{"class":1134},[1120,2327,1138],{"class":1126},[1120,2329,2330,2332,2335,2337,2340,2342,2344,2347,2349],{"class":1122,"line":1141},[1120,2331,1144],{"class":1134},[1120,2333,2334],{"class":1147}," theme ",[1120,2336,1151],{"class":1126},[1120,2338,2339],{"class":1154}," ref",[1120,2341,1801],{"class":1147},[1120,2343,1849],{"class":1126},[1120,2345,2346],{"class":1289},"default",[1120,2348,1849],{"class":1126},[1120,2350,1940],{"class":1147},[1120,2352,2353],{"class":1122,"line":1161},[1120,2354,1697],{"emptyLinePlaceholder":1696},[1120,2356,2357,2359,2362,2364,2366,2369,2371,2373],{"class":1122,"line":1185},[1120,2358,1144],{"class":1134},[1120,2360,2361],{"class":1147}," setTheme ",[1120,2363,1151],{"class":1126},[1120,2365,1807],{"class":1126},[1120,2367,2368],{"class":1810},"newTheme",[1120,2370,1814],{"class":1126},[1120,2372,1817],{"class":1134},[1120,2374,1370],{"class":1126},[1120,2376,2377,2380,2382,2385,2387,2390,2392,2394,2397,2399,2401,2404],{"class":1122,"line":1205},[1120,2378,2379],{"class":1147},"  document",[1120,2381,1174],{"class":1126},[1120,2383,2384],{"class":1147},"documentElement",[1120,2386,1174],{"class":1126},[1120,2388,2389],{"class":1154},"setAttribute",[1120,2391,1801],{"class":1130},[1120,2393,1849],{"class":1126},[1120,2395,2396],{"class":1289},"data-theme",[1120,2398,1849],{"class":1126},[1120,2400,1840],{"class":1126},[1120,2402,2403],{"class":1147}," newTheme",[1120,2405,1940],{"class":1130},[1120,2407,2408,2411,2413,2416,2418],{"class":1122,"line":1336},[1120,2409,2410],{"class":1147},"  theme",[1120,2412,1174],{"class":1126},[1120,2414,2415],{"class":1147},"value",[1120,2417,1830],{"class":1126},[1120,2419,2420],{"class":1147}," newTheme\n",[1120,2422,2423],{"class":1122,"line":1358},[1120,2424,1563],{"class":1126},[1120,2426,2427,2429,2431],{"class":1122,"line":1373},[1120,2428,1208],{"class":1126},[1120,2430,1131],{"class":1130},[1120,2432,1138],{"class":1126},[1120,2434,2435],{"class":1122,"line":1395},[1120,2436,1697],{"emptyLinePlaceholder":1696},[1120,2438,2439,2441,2443],{"class":1122,"line":1416},[1120,2440,1127],{"class":1126},[1120,2442,1581],{"class":1130},[1120,2444,1138],{"class":1126},[1120,2446,2447,2449,2452,2455,2457,2459,2462,2464],{"class":1122,"line":1436},[1120,2448,1588],{"class":1126},[1120,2450,2451],{"class":1130},"select",[1120,2453,2454],{"class":1134}," @change",[1120,2456,1151],{"class":1126},[1120,2458,1280],{"class":1126},[1120,2460,2461],{"class":1289},"e => setTheme(e.target.value)",[1120,2463,1280],{"class":1126},[1120,2465,1138],{"class":1126},[1120,2467,2468,2470,2473,2476,2478,2480,2482,2484,2487,2490,2492,2494],{"class":1122,"line":1442},[1120,2469,1610],{"class":1126},[1120,2471,2472],{"class":1130},"option",[1120,2474,2475],{"class":1134}," value",[1120,2477,1151],{"class":1126},[1120,2479,1280],{"class":1126},[1120,2481,2346],{"class":1289},[1120,2483,1280],{"class":1126},[1120,2485,2486],{"class":1126},">",[1120,2488,2489],{"class":1147},"Default",[1120,2491,1208],{"class":1126},[1120,2493,2472],{"class":1130},[1120,2495,1138],{"class":1126},[1120,2497,2498,2500,2502,2504,2506,2508,2511,2513,2515,2518,2520,2522],{"class":1122,"line":1448},[1120,2499,1610],{"class":1126},[1120,2501,2472],{"class":1130},[1120,2503,2475],{"class":1134},[1120,2505,1151],{"class":1126},[1120,2507,1280],{"class":1126},[1120,2509,2510],{"class":1289},"dark",[1120,2512,1280],{"class":1126},[1120,2514,2486],{"class":1126},[1120,2516,2517],{"class":1147},"Dark",[1120,2519,1208],{"class":1126},[1120,2521,2472],{"class":1130},[1120,2523,1138],{"class":1126},[1120,2525,2526,2528,2530,2532,2534,2536,2539,2541,2543,2546,2548,2550],{"class":1122,"line":1453},[1120,2527,1610],{"class":1126},[1120,2529,2472],{"class":1130},[1120,2531,2475],{"class":1134},[1120,2533,1151],{"class":1126},[1120,2535,1280],{"class":1126},[1120,2537,2538],{"class":1289},"ocean",[1120,2540,1280],{"class":1126},[1120,2542,2486],{"class":1126},[1120,2544,2545],{"class":1147},"Ocean",[1120,2547,1208],{"class":1126},[1120,2549,2472],{"class":1130},[1120,2551,1138],{"class":1126},[1120,2553,2554,2556,2558],{"class":1122,"line":1473},[1120,2555,1679],{"class":1126},[1120,2557,2451],{"class":1130},[1120,2559,1138],{"class":1126},[1120,2561,2562,2564,2566],{"class":1122,"line":1486},[1120,2563,1208],{"class":1126},[1120,2565,1581],{"class":1130},[1120,2567,1138],{"class":1126},[2569,2570,2572],"h3",{"id":2571},"css-custom-properties","CSS Custom Properties",[1069,2574,2578],{"className":2575,"code":2576,"language":2577,"meta":1077,"style":1077},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight",":root {\n  --color-primary: #4f46e5;\n  --color-secondary: #10b981;\n  --color-text: #1f2937;\n  --color-bg: #ffffff;\n  --spacing-unit: 0.5rem;\n  --font-primary: 'Inter', sans-serif;\n}\n\n\u002F* Dark theme *\u002F\n[data-theme=\"dark\"] {\n  --color-text: #f3f4f6;\n  --color-bg: #111827;\n}\n","css",[1049,2579,2580,2589,2605,2619,2633,2647,2659,2680,2684,2688,2693,2711,2724,2737],{"__ignoreMap":1077},[1120,2581,2582,2584,2587],{"class":1122,"line":1123},[1120,2583,1283],{"class":1126},[1120,2585,2586],{"class":1134},"root",[1120,2588,1370],{"class":1126},[1120,2590,2591,2594,2596,2599,2602],{"class":1122,"line":1141},[1120,2592,2593],{"class":1147},"  --color-primary",[1120,2595,1283],{"class":1126},[1120,2597,2598],{"class":1126}," #",[1120,2600,2601],{"class":1147},"4f46e5",[1120,2603,2604],{"class":1126},";\n",[1120,2606,2607,2610,2612,2614,2617],{"class":1122,"line":1161},[1120,2608,2609],{"class":1147},"  --color-secondary",[1120,2611,1283],{"class":1126},[1120,2613,2598],{"class":1126},[1120,2615,2616],{"class":1147},"10b981",[1120,2618,2604],{"class":1126},[1120,2620,2621,2624,2626,2628,2631],{"class":1122,"line":1185},[1120,2622,2623],{"class":1147},"  --color-text",[1120,2625,1283],{"class":1126},[1120,2627,2598],{"class":1126},[1120,2629,2630],{"class":1147},"1f2937",[1120,2632,2604],{"class":1126},[1120,2634,2635,2638,2640,2642,2645],{"class":1122,"line":1205},[1120,2636,2637],{"class":1147},"  --color-bg",[1120,2639,1283],{"class":1126},[1120,2641,2598],{"class":1126},[1120,2643,2644],{"class":1147},"ffffff",[1120,2646,2604],{"class":1126},[1120,2648,2649,2652,2654,2657],{"class":1122,"line":1336},[1120,2650,2651],{"class":1147},"  --spacing-unit",[1120,2653,1283],{"class":1126},[1120,2655,2656],{"class":1379}," 0.5rem",[1120,2658,2604],{"class":1126},[1120,2660,2661,2664,2666,2668,2671,2673,2675,2678],{"class":1122,"line":1358},[1120,2662,2663],{"class":1147},"  --font-primary",[1120,2665,1283],{"class":1126},[1120,2667,1843],{"class":1126},[1120,2669,2670],{"class":1289},"Inter",[1120,2672,1849],{"class":1126},[1120,2674,1840],{"class":1126},[1120,2676,2677],{"class":1147}," sans-serif",[1120,2679,2604],{"class":1126},[1120,2681,2682],{"class":1122,"line":1373},[1120,2683,1563],{"class":1126},[1120,2685,2686],{"class":1122,"line":1395},[1120,2687,1697],{"emptyLinePlaceholder":1696},[1120,2689,2690],{"class":1122,"line":1416},[1120,2691,2692],{"class":1786},"\u002F* Dark theme *\u002F\n",[1120,2694,2695,2697,2699,2701,2703,2705,2707,2709],{"class":1122,"line":1436},[1120,2696,2038],{"class":1126},[1120,2698,2396],{"class":1134},[1120,2700,1151],{"class":1126},[1120,2702,1280],{"class":1126},[1120,2704,2510],{"class":1289},[1120,2706,1280],{"class":1126},[1120,2708,2047],{"class":1126},[1120,2710,1370],{"class":1126},[1120,2712,2713,2715,2717,2719,2722],{"class":1122,"line":1442},[1120,2714,2623],{"class":1147},[1120,2716,1283],{"class":1126},[1120,2718,2598],{"class":1126},[1120,2720,2721],{"class":1147},"f3f4f6",[1120,2723,2604],{"class":1126},[1120,2725,2726,2728,2730,2732,2735],{"class":1122,"line":1448},[1120,2727,2637],{"class":1147},[1120,2729,1283],{"class":1126},[1120,2731,2598],{"class":1126},[1120,2733,2734],{"class":1147},"111827",[1120,2736,2604],{"class":1126},[1120,2738,2739],{"class":1122,"line":1453},[1120,2740,1563],{"class":1126},[1014,2742,2744],{"id":2743},"server-routes-api-routes","Server Routes (API Routes)",[990,2746,2747,2748,2751,2752,2755],{},"Nuxt allows server-side logic via server routes (in ",[1049,2749,2750],{},"server\u002Fapi\u002F"," or ",[1049,2753,2754],{},"server\u002Froutes\u002F","):",[1069,2757,2759],{"className":1777,"code":2758,"language":1779,"meta":1077,"style":1077},"\u002F\u002F server\u002Fapi\u002Fcart.post.ts\nexport default defineEventHandler(async (event) => {\n  const { productId, quantity } = await readBody(event)\n  const tenantId = event.context.user?.tenant_id\n  \n  await cockpit.cart.addItem(tenantId, productId, quantity)\n  return { success: true }\n})\n",[1049,2760,2761,2766,2788,2818,2845,2849,2880,2897],{"__ignoreMap":1077},[1120,2762,2763],{"class":1122,"line":1123},[1120,2764,2765],{"class":1786},"\u002F\u002F server\u002Fapi\u002Fcart.post.ts\n",[1120,2767,2768,2770,2772,2774,2776,2778,2780,2782,2784,2786],{"class":1122,"line":1141},[1120,2769,1792],{"class":1195},[1120,2771,1795],{"class":1195},[1120,2773,1798],{"class":1154},[1120,2775,1801],{"class":1147},[1120,2777,1804],{"class":1134},[1120,2779,1807],{"class":1126},[1120,2781,1811],{"class":1810},[1120,2783,1814],{"class":1126},[1120,2785,1817],{"class":1134},[1120,2787,1370],{"class":1126},[1120,2789,2790,2792,2794,2797,2799,2802,2805,2807,2809,2812,2814,2816],{"class":1122,"line":1161},[1120,2791,1824],{"class":1134},[1120,2793,2260],{"class":1126},[1120,2795,2796],{"class":1147}," productId",[1120,2798,1840],{"class":1126},[1120,2800,2801],{"class":1147}," quantity",[1120,2803,2804],{"class":1126}," }",[1120,2806,1830],{"class":1126},[1120,2808,1196],{"class":1195},[1120,2810,2811],{"class":1154}," readBody",[1120,2813,1801],{"class":1130},[1120,2815,1811],{"class":1147},[1120,2817,1940],{"class":1130},[1120,2819,2820,2822,2825,2827,2830,2832,2835,2837,2840,2842],{"class":1122,"line":1185},[1120,2821,1824],{"class":1134},[1120,2823,2824],{"class":1147}," tenantId",[1120,2826,1830],{"class":1126},[1120,2828,2829],{"class":1147}," event",[1120,2831,1174],{"class":1126},[1120,2833,2834],{"class":1147},"context",[1120,2836,1174],{"class":1126},[1120,2838,2839],{"class":1147},"user",[1120,2841,2050],{"class":1126},[1120,2843,2844],{"class":1147},"tenant_id\n",[1120,2846,2847],{"class":1122,"line":1205},[1120,2848,1945],{"class":1130},[1120,2850,2851,2854,2856,2858,2860,2862,2865,2867,2870,2872,2874,2876,2878],{"class":1122,"line":1336},[1120,2852,2853],{"class":1195},"  await",[1120,2855,1872],{"class":1147},[1120,2857,1174],{"class":1126},[1120,2859,1846],{"class":1147},[1120,2861,1174],{"class":1126},[1120,2863,2864],{"class":1154},"addItem",[1120,2866,1801],{"class":1130},[1120,2868,2869],{"class":1147},"tenantId",[1120,2871,1840],{"class":1126},[1120,2873,2796],{"class":1147},[1120,2875,1840],{"class":1126},[1120,2877,2801],{"class":1147},[1120,2879,1940],{"class":1130},[1120,2881,2882,2884,2886,2889,2891,2895],{"class":1122,"line":1358},[1120,2883,1950],{"class":1195},[1120,2885,2260],{"class":1126},[1120,2887,2888],{"class":1130}," success",[1120,2890,1283],{"class":1126},[1120,2892,2894],{"class":2893},"sfNiH"," true",[1120,2896,2275],{"class":1126},[1120,2898,2899,2901],{"class":1122,"line":1373},[1120,2900,2099],{"class":1126},[1120,2902,1940],{"class":1147},[990,2904,2905],{},"Running this logic in a server route rather than the browser pays off three ways: your API secrets stay server-side and never reach the client, you avoid an extra network hop so latency drops, and error handling and logging all happen in one place you control.",[1014,2907,2909],{"id":2908},"performance-nuxt-4-optimizations","Performance: Nuxt 4 Optimizations",[990,2911,2912],{},"Nuxt 4 gives you several performance levers, and they matter most on the high-traffic pages of a storefront. Hybrid rendering lets each page be static, dynamic, or cached as appropriate, and route caching lets you set a per-route TTL — a product page might cache for an hour while a cart page never does. On top of that, images are optimized and lazy-loaded automatically, code splitting ensures a visitor only downloads the JavaScript for the page they're on, and the underlying Nitro server keeps the server routes fast and lightweight. The net effect is that the common pages stay cheap to serve under load.",[1014,2914,2916],{"id":2915},"deployment-edge-serverless","Deployment: Edge + Serverless",[990,2918,2919],{},"A storefront is usually deployed to a serverless-plus-edge host — Vercel and Netlify are the common choices, both pairing serverless functions with an edge CDN, though a self-hosted Docker and Kubernetes setup works too. Whatever the target, the deployment auto-scales with traffic, serves static assets from the edge close to the customer, caches API responses (in-process or a shared cache), and supports A\u002FB testing and feature flags. The goal in every case is the same: keep the storefront fast and resilient as traffic spikes, without hand-tuning capacity.",[1014,2921,2923],{"id":2922},"next-steps","Next Steps",[1022,2925,2926,2934,2942],{},[1025,2927,2928,2933],{},[994,2929,2930],{},[2309,2931,344],{"href":2932},"\u002Fdocs\u002Fproducts\u002Fsites\u002Fcheckout\u002F"," — Multi-step checkout flow with Formily",[1025,2935,2936,2941],{},[994,2937,2938],{},[2309,2939,171],{"href":2940},"\u002Fdocs\u002Fproducts\u002Fsites\u002Fauthentication\u002F"," — Login, register, password reset",[1025,2943,2944,2948],{},[994,2945,2946],{},[2309,2947,512],{"href":2311}," — Customizing colors, fonts, and layouts",[2950,2951,2952],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":1077,"searchDepth":1141,"depth":1141,"links":2954},[2955,2956,2957,2958,2959,2960,2961,2964,2965,2966,2967],{"id":1016,"depth":1141,"text":1017},{"id":1067,"depth":1141,"text":57},{"id":1080,"depth":1141,"text":1081},{"id":1215,"depth":1141,"text":1216},{"id":1756,"depth":1141,"text":1757},{"id":2118,"depth":1141,"text":2119},{"id":2303,"depth":1141,"text":2304,"children":2962},[2963],{"id":2571,"depth":1161,"text":2572},{"id":2743,"depth":1141,"text":2744},{"id":2908,"depth":1141,"text":2909},{"id":2915,"depth":1141,"text":2916},{"id":2922,"depth":1141,"text":2923},"Nuxt 4 + Blökkli visual site builder, file-based routing, BFF pattern","md",null,{"status":2972},"published",{"title":327,"description":2968},{"loc":328},"mDmFz1dzqf9dlpdY7gUJ2gbGZtAAvTbIn9x10GHWYlI",1785229255978]