[{"data":1,"prerenderedAt":1433},["ShallowReactive",2],{"navigation_docs":3,"-docs-storefront-sdk-nextjs-components":357,"-docs-storefront-sdk-nextjs-components-surround":1430,"docs-site-config":1420},[4,74,135,139,161,195,273],{"title":5,"path":6,"stem":7,"children":8},"Assets API","\u002Fdocs\u002Fassets","docs\u002Fassets\u002Findex",[9,10,32,57],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13,"children":14,"page":31},"Getting Started","\u002Fdocs\u002Fassets\u002Fgetting-started","docs\u002Fassets\u002F1.getting-started",[15,19,23,27],{"title":16,"path":17,"stem":18},"Base URL","\u002Fdocs\u002Fassets\u002Fgetting-started\u002Fbase-url","docs\u002Fassets\u002F1.getting-started\u002F1.base-url",{"title":20,"path":21,"stem":22},"Important Notes","\u002Fdocs\u002Fassets\u002Fgetting-started\u002Fimportant-notes","docs\u002Fassets\u002F1.getting-started\u002F2.important-notes",{"title":24,"path":25,"stem":26},"URL Format","\u002Fdocs\u002Fassets\u002Fgetting-started\u002Furl-format","docs\u002Fassets\u002F1.getting-started\u002F3.url-format",{"title":28,"path":29,"stem":30},"Custom Domains","\u002Fdocs\u002Fassets\u002Fgetting-started\u002Fcustom-domains","docs\u002Fassets\u002F1.getting-started\u002F4.custom-domains",false,{"title":33,"path":34,"stem":35,"children":36,"page":31},"Usage","\u002Fdocs\u002Fassets\u002Fusage","docs\u002Fassets\u002F2.usage",[37,41,45,49,53],{"title":38,"path":39,"stem":40},"Transforms","\u002Fdocs\u002Fassets\u002Fusage\u002Ftransforms","docs\u002Fassets\u002F2.usage\u002F1.transforms",{"title":42,"path":43,"stem":44},"Caching","\u002Fdocs\u002Fassets\u002Fusage\u002Fcaching","docs\u002Fassets\u002F2.usage\u002F2.caching",{"title":46,"path":47,"stem":48},"Recipes","\u002Fdocs\u002Fassets\u002Fusage\u002Frecipes","docs\u002Fassets\u002F2.usage\u002F3.recipes",{"title":50,"path":51,"stem":52},"Best Practices","\u002Fdocs\u002Fassets\u002Fusage\u002Fbest-practices","docs\u002Fassets\u002F2.usage\u002F4.best-practices",{"title":54,"path":55,"stem":56},"Reference","\u002Fdocs\u002Fassets\u002Fusage\u002Freference","docs\u002Fassets\u002F2.usage\u002F5.reference",{"title":58,"path":59,"stem":60,"children":61,"page":31},"Integration","\u002Fdocs\u002Fassets\u002Fintegration","docs\u002Fassets\u002F3.integration",[62,66,70],{"title":63,"path":64,"stem":65},"Nuxt","\u002Fdocs\u002Fassets\u002Fintegration\u002Fnuxt","docs\u002Fassets\u002F3.integration\u002F1.nuxt",{"title":67,"path":68,"stem":69},"Next.js","\u002Fdocs\u002Fassets\u002Fintegration\u002Fnextjs","docs\u002Fassets\u002F3.integration\u002F2.nextjs",{"title":71,"path":72,"stem":73},"Plain HTML","\u002Fdocs\u002Fassets\u002Fintegration\u002Fhtml","docs\u002Fassets\u002F3.integration\u002F3.html",{"title":75,"path":76,"stem":77,"children":78},"Avvyr CMS","\u002Fdocs\u002Fcms","docs\u002Fcms\u002Findex",[79,80,92,105,118,131],{"title":75,"path":76,"stem":77},{"title":11,"path":81,"stem":82,"children":83,"page":31},"\u002Fdocs\u002Fcms\u002Fgetting-started","docs\u002Fcms\u002F1.getting-started",[84,88],{"title":85,"path":86,"stem":87},"Quickstart","\u002Fdocs\u002Fcms\u002Fgetting-started\u002Fquickstart","docs\u002Fcms\u002F1.getting-started\u002F1.quickstart",{"title":89,"path":90,"stem":91},"Keys and access","\u002Fdocs\u002Fcms\u002Fgetting-started\u002Fkeys-and-access","docs\u002Fcms\u002F1.getting-started\u002F2.keys-and-access",{"title":93,"path":94,"stem":95,"children":96,"page":31},"Content Model","\u002Fdocs\u002Fcms\u002Fcontent-model","docs\u002Fcms\u002F2.content-model",[97,101],{"title":98,"path":99,"stem":100},"Types and fields","\u002Fdocs\u002Fcms\u002Fcontent-model\u002Ftypes-and-fields","docs\u002Fcms\u002F2.content-model\u002F1.types-and-fields",{"title":102,"path":103,"stem":104},"Entries and publishing","\u002Fdocs\u002Fcms\u002Fcontent-model\u002Fentries-and-publishing","docs\u002Fcms\u002F2.content-model\u002F2.entries-and-publishing",{"title":106,"path":107,"stem":108,"children":109,"page":31},"Delivery","\u002Fdocs\u002Fcms\u002Fdelivery","docs\u002Fcms\u002F3.delivery",[110,114],{"title":111,"path":112,"stem":113},"Delivery API","\u002Fdocs\u002Fcms\u002Fdelivery\u002Fdelivery-api","docs\u002Fcms\u002F3.delivery\u002F1.delivery-api",{"title":115,"path":116,"stem":117},"Preview and live editing","\u002Fdocs\u002Fcms\u002Fdelivery\u002Fpreview","docs\u002Fcms\u002F3.delivery\u002F2.preview",{"title":119,"path":120,"stem":121,"children":122,"page":31},"Frameworks","\u002Fdocs\u002Fcms\u002Fframeworks","docs\u002Fcms\u002F4.frameworks",[123,127],{"title":124,"path":125,"stem":126},"JavaScript client","\u002Fdocs\u002Fcms\u002Fframeworks\u002Fjavascript-client","docs\u002Fcms\u002F4.frameworks\u002F1.javascript-client",{"title":128,"path":129,"stem":130},"Nuxt layer","\u002Fdocs\u002Fcms\u002Fframeworks\u002Fnuxt","docs\u002Fcms\u002F4.frameworks\u002F2.nuxt",{"title":132,"path":133,"stem":134},"Management API","\u002Fdocs\u002Fcms\u002Fmanagement-api","docs\u002Fcms\u002F5.management-api",{"title":136,"path":137,"stem":138},"Early Access","\u002Fdocs\u002Fearly-access","docs\u002Fearly-access",{"title":140,"path":141,"stem":142,"children":143},"Events API","\u002Fdocs\u002Fevents","docs\u002Fevents\u002Findex",[144,145],{"title":140,"path":141,"stem":142},{"title":11,"path":146,"stem":147,"children":148,"page":31},"\u002Fdocs\u002Fevents\u002Fgetting-started","docs\u002Fevents\u002F1.getting-started",[149,153,157],{"title":150,"path":151,"stem":152},"Subscribing","\u002Fdocs\u002Fevents\u002Fgetting-started\u002Fsubscribing","docs\u002Fevents\u002F1.getting-started\u002F1.subscribing",{"title":154,"path":155,"stem":156},"Event Delivery","\u002Fdocs\u002Fevents\u002Fgetting-started\u002Fevent-delivery","docs\u002Fevents\u002F1.getting-started\u002F2.event-delivery",{"title":158,"path":159,"stem":160},"Event Reference","\u002Fdocs\u002Fevents\u002Fgetting-started\u002Fevent-reference","docs\u002Fevents\u002F1.getting-started\u002F3.event-reference",{"title":162,"path":163,"stem":164,"children":165},"Integrations API","\u002Fdocs\u002Fintegrations","docs\u002Fintegrations\u002Findex",[166,167],{"title":162,"path":163,"stem":164},{"title":11,"path":168,"stem":169,"children":170,"page":31},"\u002Fdocs\u002Fintegrations\u002Fgetting-started","docs\u002Fintegrations\u002F1.getting-started",[171,175,179,183,187,191],{"title":172,"path":173,"stem":174},"Why Use It?","\u002Fdocs\u002Fintegrations\u002Fgetting-started\u002Fwhy-integrations-api","docs\u002Fintegrations\u002F1.getting-started\u002F1.why-integrations-api",{"title":176,"path":177,"stem":178},"Use Cases","\u002Fdocs\u002Fintegrations\u002Fgetting-started\u002Fwho-is-it-for","docs\u002Fintegrations\u002F1.getting-started\u002F2.who-is-it-for",{"title":180,"path":181,"stem":182},"Pre-built Connectors","\u002Fdocs\u002Fintegrations\u002Fgetting-started\u002Fpre-built-integrations","docs\u002Fintegrations\u002F1.getting-started\u002F3.pre-built-integrations",{"title":184,"path":185,"stem":186},"Custom Inbound","\u002Fdocs\u002Fintegrations\u002Fgetting-started\u002Fcustom-inbound-api","docs\u002Fintegrations\u002F1.getting-started\u002F4.custom-inbound-api",{"title":188,"path":189,"stem":190},"Event Lifecycle","\u002Fdocs\u002Fintegrations\u002Fgetting-started\u002Fevent-lifecycle","docs\u002Fintegrations\u002F1.getting-started\u002F5.event-lifecycle",{"title":192,"path":193,"stem":194},"API Endpoints","\u002Fdocs\u002Fintegrations\u002Fgetting-started\u002Fmanagement-api-endpoints","docs\u002Fintegrations\u002F1.getting-started\u002F6.management-api-endpoints",{"title":196,"path":197,"stem":198,"children":199},"MCP Server","\u002Fdocs\u002Fmcp","docs\u002Fmcp\u002Findex",[200,201,225,234,244],{"title":196,"path":197,"stem":198},{"title":11,"path":202,"stem":203,"children":204,"page":31},"\u002Fdocs\u002Fmcp\u002Fgetting-started","docs\u002Fmcp\u002F1.getting-started",[205,209,213,217,221],{"title":206,"path":207,"stem":208},"Claude","\u002Fdocs\u002Fmcp\u002Fgetting-started\u002Fclaude","docs\u002Fmcp\u002F1.getting-started\u002F1.claude",{"title":210,"path":211,"stem":212},"Claude Code","\u002Fdocs\u002Fmcp\u002Fgetting-started\u002Fclaude-code","docs\u002Fmcp\u002F1.getting-started\u002F2.claude-code",{"title":214,"path":215,"stem":216},"VS Code","\u002Fdocs\u002Fmcp\u002Fgetting-started\u002Fvscode","docs\u002Fmcp\u002F1.getting-started\u002F3.vscode",{"title":218,"path":219,"stem":220},"Cursor","\u002Fdocs\u002Fmcp\u002Fgetting-started\u002Fcursor","docs\u002Fmcp\u002F1.getting-started\u002F4.cursor",{"title":222,"path":223,"stem":224},"Verify the connection","\u002Fdocs\u002Fmcp\u002Fgetting-started\u002Fverify","docs\u002Fmcp\u002F1.getting-started\u002F5.verify",{"title":226,"path":227,"stem":228,"children":229,"page":31},"Docs Server","\u002Fdocs\u002Fmcp\u002Fdocs-server","docs\u002Fmcp\u002F2.docs-server",[230],{"title":231,"path":232,"stem":233},"Docs server tools","\u002Fdocs\u002Fmcp\u002Fdocs-server\u002Ftools","docs\u002Fmcp\u002F2.docs-server\u002F1.tools",{"title":235,"path":236,"stem":237,"children":238},"API Server","\u002Fdocs\u002Fmcp\u002Fapi-server","docs\u002Fmcp\u002F3.api-server\u002Findex",[239,240],{"title":235,"path":236,"stem":237},{"title":241,"path":242,"stem":243},"Available tools","\u002Fdocs\u002Fmcp\u002Fapi-server\u002Ftools","docs\u002Fmcp\u002F3.api-server\u002F1.tools",{"title":245,"path":246,"stem":247,"children":248,"page":31},"Examples","\u002Fdocs\u002Fmcp\u002Fexamples","docs\u002Fmcp\u002F4.examples",[249,253,257,261,265,269],{"title":250,"path":251,"stem":252},"Exploring an API","\u002Fdocs\u002Fmcp\u002Fexamples\u002Fexploring-an-api","docs\u002Fmcp\u002F4.examples\u002F1.exploring-an-api",{"title":254,"path":255,"stem":256},"Building a Feature","\u002Fdocs\u002Fmcp\u002Fexamples\u002Fbuilding-a-feature","docs\u002Fmcp\u002F4.examples\u002F2.building-a-feature",{"title":258,"path":259,"stem":260},"Understanding Models","\u002Fdocs\u002Fmcp\u002Fexamples\u002Funderstanding-models","docs\u002Fmcp\u002F4.examples\u002F3.understanding-models",{"title":262,"path":263,"stem":264},"Code Review","\u002Fdocs\u002Fmcp\u002Fexamples\u002Fcode-review","docs\u002Fmcp\u002F4.examples\u002F4.code-review",{"title":266,"path":267,"stem":268},"Combining MCP Servers","\u002Fdocs\u002Fmcp\u002Fexamples\u002Fmulti-mcp","docs\u002Fmcp\u002F4.examples\u002F5.multi-mcp",{"title":270,"path":271,"stem":272},"Tips","\u002Fdocs\u002Fmcp\u002Fexamples\u002Ftips","docs\u002Fmcp\u002F4.examples\u002F6.tips",{"title":274,"path":275,"stem":276,"children":277,"page":31},"Storefront SDK","\u002Fdocs\u002Fstorefront-sdk","docs\u002Fstorefront-sdk",[278,290,323,338],{"title":11,"path":279,"stem":280,"children":281,"page":31},"\u002Fdocs\u002Fstorefront-sdk\u002Fgetting-started","docs\u002Fstorefront-sdk\u002F1.getting-started",[282,286],{"title":283,"path":284,"stem":285},"Installation","\u002Fdocs\u002Fstorefront-sdk\u002Fgetting-started\u002Finstallation","docs\u002Fstorefront-sdk\u002F1.getting-started\u002F1.installation",{"title":287,"path":288,"stem":289},"Configuration","\u002Fdocs\u002Fstorefront-sdk\u002Fgetting-started\u002Fconfiguration","docs\u002Fstorefront-sdk\u002F1.getting-started\u002F2.configuration",{"title":291,"path":292,"stem":293,"children":294,"page":31},"Resources","\u002Fdocs\u002Fstorefront-sdk\u002Fresources","docs\u002Fstorefront-sdk\u002F2.resources",[295,299,303,307,311,315,319],{"title":296,"path":297,"stem":298},"Products","\u002Fdocs\u002Fstorefront-sdk\u002Fresources\u002Fproducts","docs\u002Fstorefront-sdk\u002F2.resources\u002F1.products",{"title":300,"path":301,"stem":302},"Cart","\u002Fdocs\u002Fstorefront-sdk\u002Fresources\u002Fcart","docs\u002Fstorefront-sdk\u002F2.resources\u002F2.cart",{"title":304,"path":305,"stem":306},"Auth","\u002Fdocs\u002Fstorefront-sdk\u002Fresources\u002Fauth","docs\u002Fstorefront-sdk\u002F2.resources\u002F3.auth",{"title":308,"path":309,"stem":310},"Checkout & Shipping","\u002Fdocs\u002Fstorefront-sdk\u002Fresources\u002Fcheckout-shipping","docs\u002Fstorefront-sdk\u002F2.resources\u002F4.checkout-shipping",{"title":312,"path":313,"stem":314},"Orders, Returns & Reviews","\u002Fdocs\u002Fstorefront-sdk\u002Fresources\u002Forders-returns-reviews","docs\u002Fstorefront-sdk\u002F2.resources\u002F5.orders-returns-reviews",{"title":316,"path":317,"stem":318},"Customer assistant","\u002Fdocs\u002Fstorefront-sdk\u002Fresources\u002Fassistant","docs\u002Fstorefront-sdk\u002F2.resources\u002F6.assistant",{"title":320,"path":321,"stem":322},"Products in images","\u002Fdocs\u002Fstorefront-sdk\u002Fresources\u002Fproducts-in-images","docs\u002Fstorefront-sdk\u002F2.resources\u002F7.products-in-images",{"title":128,"path":324,"stem":325,"children":326,"page":31},"\u002Fdocs\u002Fstorefront-sdk\u002Fnuxt-layer","docs\u002Fstorefront-sdk\u002F3.nuxt-layer",[327,331,335],{"title":328,"path":329,"stem":330},"Overview","\u002Fdocs\u002Fstorefront-sdk\u002Fnuxt-layer\u002Foverview","docs\u002Fstorefront-sdk\u002F3.nuxt-layer\u002F1.overview",{"title":332,"path":333,"stem":334},"Composables","\u002Fdocs\u002Fstorefront-sdk\u002Fnuxt-layer\u002Fcomposables","docs\u002Fstorefront-sdk\u002F3.nuxt-layer\u002F2.composables",{"title":316,"path":336,"stem":337},"\u002Fdocs\u002Fstorefront-sdk\u002Fnuxt-layer\u002Fassistant","docs\u002Fstorefront-sdk\u002F3.nuxt-layer\u002F3.assistant",{"title":67,"path":339,"stem":340,"children":341,"page":31},"\u002Fdocs\u002Fstorefront-sdk\u002Fnextjs","docs\u002Fstorefront-sdk\u002F4.nextjs",[342,345,349,353],{"title":328,"path":343,"stem":344},"\u002Fdocs\u002Fstorefront-sdk\u002Fnextjs\u002Foverview","docs\u002Fstorefront-sdk\u002F4.nextjs\u002F1.overview",{"title":346,"path":347,"stem":348},"Hooks","\u002Fdocs\u002Fstorefront-sdk\u002Fnextjs\u002Fhooks","docs\u002Fstorefront-sdk\u002F4.nextjs\u002F2.hooks",{"title":350,"path":351,"stem":352},"Server helpers and proxy","\u002Fdocs\u002Fstorefront-sdk\u002Fnextjs\u002Fserver","docs\u002Fstorefront-sdk\u002F4.nextjs\u002F3.server",{"title":354,"path":355,"stem":356},"Components","\u002Fdocs\u002Fstorefront-sdk\u002Fnextjs\u002Fcomponents","docs\u002Fstorefront-sdk\u002F4.nextjs\u002F4.components",{"id":358,"title":354,"body":359,"description":1418,"extension":1419,"links":1420,"meta":1421,"navigation":434,"path":355,"seo":1428,"stem":356,"__hash__":1429},"docs\u002Fdocs\u002Fstorefront-sdk\u002F4.nextjs\u002F4.components.md",{"type":360,"value":361,"toc":1409},"minimark",[362,366,396,407,414,417,442,449,473,480,513,598,601,616,625,630,644,659,686,692,700,719,730,953,956,994,1077,1083,1090,1177,1183,1331,1337,1344,1363,1380,1384,1405],[363,364,365],"p",{},"The Next.js package ships the same components as the Nuxt layer, ported to React. Import the stylesheet once, in the root layout:",[367,368,373],"pre",{"className":369,"code":370,"language":371,"meta":372,"style":372},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import '@avvyr\u002Fstorefront-next\u002Fstyles.css'\n","ts","",[374,375,376],"code",{"__ignoreMap":372},[377,378,381,385,389,393],"span",{"class":379,"line":380},"line",1,[377,382,384],{"class":383},"s7zQu","import",[377,386,388],{"class":387},"sMK4o"," '",[377,390,392],{"class":391},"sfazB","@avvyr\u002Fstorefront-next\u002Fstyles.css",[377,394,395],{"class":387},"'\n",[363,397,398,399,402,403,406],{},"The styles use BEM classes (",[374,400,401],{},"avvyr-consent__card",", ",[374,404,405],{},"avvyr-assistant__panel"," and so on) and CSS variables, so you can theme or override them with your own CSS.",[408,409,411],"h2",{"id":410},"avvyrcookieconsent",[374,412,413],{},"\u003CAvvyrCookieConsent \u002F>",[363,415,416],{},"The cookie banner. Place it in the layout:",[367,418,422],{"className":419,"code":420,"language":421,"meta":372,"style":372},"language-tsx shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { AvvyrCookieConsent } from '@avvyr\u002Fstorefront-next'\n\n\u003CAvvyrCookieConsent \u002F>\n","tsx",[374,423,424,429,436],{"__ignoreMap":372},[377,425,426],{"class":379,"line":380},[377,427,428],{},"import { AvvyrCookieConsent } from '@avvyr\u002Fstorefront-next'\n",[377,430,432],{"class":379,"line":431},2,[377,433,435],{"emptyLinePlaceholder":434},true,"\n",[377,437,439],{"class":379,"line":438},3,[377,440,441],{},"\u003CAvvyrCookieConsent \u002F>\n",[363,443,444,445,448],{},"The visitor's choice is stored in the ",[374,446,447],{},"avvyr_consent"," cookie, so the server and the browser render the same banner. Saving a choice:",[450,451,452,456,459,466],"ul",{},[453,454,455],"li",{},"grants or revokes Avvyr tracking (identity cookies are only set after consent),",[453,457,458],{},"logs a receipt with the platform (append-only evidence log, GDPR art. 7.1),",[453,460,461,462,465],{},"sends a Google Consent Mode v2 update to the dataLayer, followed by the ",[374,463,464],{},"analytics.consentUpdateEvent"," event.",[453,467,468,469,472],{},"stores the choice on the cart (",[374,470,471],{},"useCart().setConsent","). It follows the cart onto the order and decides whether the purchase may be sent server-side to marketing channels. A cart created later picks up the cookie by itself.",[363,474,475,476,479],{},"With your own consent manager (CookieFirst, Cookiebot), call ",[374,477,478],{},"useCart().setConsent({ analytics, marketing })"," when the visitor saves a choice, so the order still knows what they agreed to.",[363,481,482,483,486,487,490,491,402,494,497,498,402,501,504,505,508,509,512],{},"Configure it under ",[374,484,485],{},"consent"," in ",[374,488,489],{},"storefront.config.ts",": ",[374,492,493],{},"enabled",[374,495,496],{},"policyVersion"," (bump it to ask every visitor again), ",[374,499,500],{},"privacyPolicyPath",[374,502,503],{},"blocking"," (a centred modal that requires a choice; rejecting stays as easy as accepting), ",[374,506,507],{},"position"," and ",[374,510,511],{},"texts",".",[514,515,516,531],"table",{},[517,518,519],"thead",{},[520,521,522,526,529],"tr",{},[523,524,525],"th",{},"Prop",[523,527,528],{},"Type",[523,530],{},[532,533,534,552,567,581],"tbody",{},[520,535,536,541,546],{},[537,538,539],"td",{},[374,540,511],{},[537,542,543],{},[374,544,545],{},"Record\u003Cstring, string>",[537,547,548,549,512],{},"Per-language texts. They take precedence over ",[374,550,551],{},"config.consent.texts",[520,553,554,559,564],{},[537,555,556],{},[374,557,558],{},"policyPath",[537,560,561],{},[374,562,563],{},"string",[537,565,566],{},"Link to the privacy policy, when you build the path yourself",[520,568,569,574,578],{},[537,570,571],{},[374,572,573],{},"policyInline",[537,575,576],{},[374,577,563],{},[537,579,580],{},"The policy as HTML inside the banner. Use only your own content (for example, rendered CMS rich text), never user input.",[520,582,583,588,593],{},[537,584,585],{},[374,586,587],{},"policy",[537,589,590],{},[374,591,592],{},"ReactNode",[537,594,595,596,512],{},"The policy as React content. Takes precedence over ",[374,597,573],{},[363,599,600],{},"A footer link to reopen the settings:",[367,602,604],{"className":419,"code":603,"language":421,"meta":372,"style":372},"const { reopen } = useConsent()\n\u003Cbutton onClick={reopen}>Cookie settings\u003C\u002Fbutton>\n",[374,605,606,611],{"__ignoreMap":372},[377,607,608],{"class":379,"line":380},[377,609,610],{},"const { reopen } = useConsent()\n",[377,612,613],{"class":379,"line":431},[377,614,615],{},"\u003Cbutton onClick={reopen}>Cookie settings\u003C\u002Fbutton>\n",[363,617,618,621,622,512],{},[374,619,620],{},"useConsent()"," returns ",[374,623,624],{},"{ enabled, policyVersion, decision, bannerVisible, save, acceptAll, rejectAll, reopen }",[626,627,629],"h3",{"id":628},"datalayer","dataLayer",[363,631,632,635,636,639,640,643],{},[374,633,634],{},"useDataLayer()"," pushes GA4 e-commerce events to ",[374,637,638],{},"window.dataLayer"," for any tag manager. The cart, auth, checkout confirmation and product listing hooks push their events automatically (",[374,641,642],{},"analytics.autoWire","). For your own pages:",[367,645,647],{"className":419,"code":646,"language":421,"meta":372,"style":372},"const dataLayer = useDataLayer()\nuseEffect(() => { if (product) dataLayer.viewItem(product) }, [product])\n",[374,648,649,654],{"__ignoreMap":372},[377,650,651],{"class":379,"line":380},[377,652,653],{},"const dataLayer = useDataLayer()\n",[377,655,656],{"class":379,"line":431},[377,657,658],{},"useEffect(() => { if (product) dataLayer.viewItem(product) }, [product])\n",[363,660,661,662,665,666,669,670,673,674,677,678,681,682,685],{},"Wrap product grids in ",[374,663,664],{},"\u003CDataLayerListProvider listId=\"…\" listName=\"…\">"," so that ",[374,667,668],{},"select_item"," knows which list a click came from. To forward every push to Segment, Tealium or similar, pass ",[374,671,672],{},"onDataLayer"," to the provider. It receives ",[374,675,676],{},"{ event, payload }"," before the push, can modify ",[374,679,680],{},"payload"," in place, and can return ",[374,683,684],{},"false"," to cancel the push.",[408,687,689],{"id":688},"avvyrassistant",[374,690,691],{},"\u003CAvvyrAssistant \u002F>",[363,693,694,695,699],{},"The customer assistant chat, the same widget as the ",[696,697,698],"a",{"href":336},"Nuxt layer's",": streamed answers, product, order and tracking cards, return proposals, photos, handover to staff, and sign-in gating. Add it once to the layout:",[367,701,703],{"className":419,"code":702,"language":421,"meta":372,"style":372},"import { AvvyrAssistant } from '@avvyr\u002Fstorefront-next'\n\n\u003CAvvyrAssistant \u002F>\n",[374,704,705,710,714],{"__ignoreMap":372},[377,706,707],{"class":379,"line":380},[377,708,709],{},"import { AvvyrAssistant } from '@avvyr\u002Fstorefront-next'\n",[377,711,712],{"class":379,"line":431},[377,713,435],{"emptyLinePlaceholder":434},[377,715,716],{"class":379,"line":438},[377,717,718],{},"\u003CAvvyrAssistant \u002F>\n",[363,720,721,722,725,726,729],{},"It renders nothing until the shop has the assistant enabled and the storefront key has the ",[374,723,724],{},"storefront:assistant"," scope, so it is safe to ship early. For how to enable it, the cards, photos, texts and the CSS variables, see the ",[696,727,728],{"href":336},"Nuxt assistant page",". They work the same way here.",[514,731,732,745],{},[517,733,734],{},[520,735,736,738,740,743],{},[523,737,525],{},[523,739,528],{},[523,741,742],{},"Default",[523,744],{},[532,746,747,767,785,810,828,850,868,887,906,935],{},[520,748,749,754,758,761],{},[537,750,751],{},[374,752,753],{},"locale",[537,755,756],{},[374,757,563],{},[537,759,760],{},"the market's",[537,762,763,766],{},[374,764,765],{},"sv*"," gives Swedish texts, anything else English",[520,768,769,773,777,779],{},[537,770,771],{},[374,772,511],{},[537,774,775],{},[374,776,545],{},[537,778],{},[537,780,781,782],{},"Overrides ",[374,783,784],{},"config.assistant.texts",[520,786,787,792,797,802],{},[537,788,789],{},[374,790,791],{},"launcher",[537,793,794],{},[374,795,796],{},"boolean",[537,798,799],{},[374,800,801],{},"true",[537,803,804,806,807],{},[374,805,684],{}," hides the floating button; open it with ",[374,808,809],{},"useAssistant().open()",[520,811,812,816,821,826],{},[537,813,814],{},[374,815,507],{},[537,817,818],{},[374,819,820],{},"'bottom-right' | 'bottom-left'",[537,822,823],{},[374,824,825],{},"'bottom-right'",[537,827],{},[520,829,830,841,845,847],{},[537,831,832,402,835,402,838],{},[374,833,834],{},"productSku",[374,836,837],{},"pageType",[374,839,840],{},"postalCode",[537,842,843],{},[374,844,563],{},[537,846],{},[537,848,849],{},"Page context (see below)",[520,851,852,857,862,865],{},[537,853,854],{},[374,855,856],{},"suggestions",[537,858,859],{},[374,860,861],{},"string[]",[537,863,864],{},"the shop's",[537,866,867],{},"Suggested questions for this page",[520,869,870,875,879,884],{},[537,871,872],{},[374,873,874],{},"loginUrl",[537,876,877],{},[374,878,563],{},[537,880,881],{},[374,882,883],{},"config.assistant.loginUrl",[537,885,886],{},"Where \"Sign in\" goes when only signed-in customers may chat",[520,888,889,894,898,903],{},[537,890,891],{},[374,892,893],{},"siteOrigins",[537,895,896],{},[374,897,861],{},[537,899,900],{},[374,901,902],{},"config.assistant.siteOrigins",[537,904,905],{},"Your other domains; links to them navigate in the app",[520,907,908,928,930,932],{},[537,909,910,402,913,402,916,402,919,402,922,402,925],{},[374,911,912],{},"onOpen",[374,914,915],{},"onClose",[374,917,918],{},"onSend(text)",[374,920,921],{},"onHandover",[374,923,924],{},"onProposal({ proposal, decision })",[374,926,927],{},"onSignIn",[537,929],{},[537,931],{},[537,933,934],{},"The Nuxt component's events",[520,936,937,942,944,946],{},[537,938,939],{},[374,940,941],{},"renderSignIn({ close, texts })",[537,943],{},[537,945],{},[537,947,948,949,952],{},"Replaces the \"Sign in to chat\" prompt (the Nuxt ",[374,950,951],{},"sign-in"," slot)",[363,954,955],{},"Set the page context from the page that knows the product, since the chat usually sits in the layout:",[367,957,959],{"className":419,"code":958,"language":421,"meta":372,"style":372},"'use client'\nconst assistant = useAssistant()\nuseEffect(() => {\n  assistant.setContext({ productSku: product.sku, pageType: 'product' })\n  return () => assistant.setContext(null)\n}, [product.sku])\n",[374,960,961,966,971,976,982,988],{"__ignoreMap":372},[377,962,963],{"class":379,"line":380},[377,964,965],{},"'use client'\n",[377,967,968],{"class":379,"line":431},[377,969,970],{},"const assistant = useAssistant()\n",[377,972,973],{"class":379,"line":438},[377,974,975],{},"useEffect(() => {\n",[377,977,979],{"class":379,"line":978},4,[377,980,981],{},"  assistant.setContext({ productSku: product.sku, pageType: 'product' })\n",[377,983,985],{"class":379,"line":984},5,[377,986,987],{},"  return () => assistant.setContext(null)\n",[377,989,991],{"class":379,"line":990},6,[377,992,993],{},"}, [product.sku])\n",[363,995,996,999,1000,402,1002,402,1005,402,1008,402,1011,402,1014,402,1017,402,1020,402,1023,402,1026,1029,1030,402,1033,402,1036,402,1039,402,1042,402,1045,402,1048,402,1051,402,1054,402,1057,402,1060,508,1063,1066,1067,402,1070,508,1073,1076],{},[374,997,998],{},"useAssistant()"," returns the chat's state as plain values (",[374,1001,493],{},[374,1003,1004],{},"isOpen",[374,1006,1007],{},"status",[374,1009,1010],{},"messages",[374,1012,1013],{},"proposals",[374,1015,1016],{},"streaming",[374,1018,1019],{},"activity",[374,1021,1022],{},"error",[374,1024,1025],{},"signInRequired",[374,1027,1028],{},"attachments"," and more) and the actions ",[374,1031,1032],{},"open",[374,1034,1035],{},"close",[374,1037,1038],{},"toggle",[374,1040,1041],{},"send",[374,1043,1044],{},"stop",[374,1046,1047],{},"requestHandover",[374,1049,1050],{},"confirmProposal",[374,1052,1053],{},"rejectProposal",[374,1055,1056],{},"addAttachments",[374,1058,1059],{},"setContext",[374,1061,1062],{},"setLocale",[374,1064,1065],{},"reset",". Use it for your own \"Chat with us\" button, or to build your own chat UI. ",[374,1068,1069],{},"AvvyrAssistantCard",[374,1071,1072],{},"AvvyrAssistantProposal",[374,1074,1075],{},"AvvyrAssistantText"," are exported too.",[408,1078,1080],{"id":1079},"avvyrpaymentwidget",[374,1081,1082],{},"\u003CAvvyrPaymentWidget \u002F>",[363,1084,1085,1086,1089],{},"The payment step. Give it the chosen payment method and it starts the session (",[374,1087,1088],{},"checkout.init",") and renders the provider's widget: the Kustom checkout snippet, Klarna Payments with an authorize button, a redirect button to a hosted payment page, or a button that places the order directly (invoice).",[367,1091,1093],{"className":419,"code":1092,"language":421,"meta":372,"style":372},"'use client'\nimport { AvvyrPaymentWidget } from '@avvyr\u002Fstorefront-next'\nimport { useRouter } from 'next\u002Fnavigation'\n\nexport function PaymentStep({ method, email }: { method: PaymentMethod; email: string }) {\n  const router = useRouter()\n  return (\n    \u003CAvvyrPaymentWidget\n      paymentMethod={method}\n      email={email}\n      onCompleted={({ orderId }) => router.push(`\u002Fcheckout\u002Fconfirmation\u002F${orderId}`)}\n      onError={(err) => console.error(err)}\n    \u002F>\n  )\n}\n",[374,1094,1095,1099,1104,1109,1113,1118,1123,1129,1135,1141,1147,1153,1159,1165,1171],{"__ignoreMap":372},[377,1096,1097],{"class":379,"line":380},[377,1098,965],{},[377,1100,1101],{"class":379,"line":431},[377,1102,1103],{},"import { AvvyrPaymentWidget } from '@avvyr\u002Fstorefront-next'\n",[377,1105,1106],{"class":379,"line":438},[377,1107,1108],{},"import { useRouter } from 'next\u002Fnavigation'\n",[377,1110,1111],{"class":379,"line":978},[377,1112,435],{"emptyLinePlaceholder":434},[377,1114,1115],{"class":379,"line":984},[377,1116,1117],{},"export function PaymentStep({ method, email }: { method: PaymentMethod; email: string }) {\n",[377,1119,1120],{"class":379,"line":990},[377,1121,1122],{},"  const router = useRouter()\n",[377,1124,1126],{"class":379,"line":1125},7,[377,1127,1128],{},"  return (\n",[377,1130,1132],{"class":379,"line":1131},8,[377,1133,1134],{},"    \u003CAvvyrPaymentWidget\n",[377,1136,1138],{"class":379,"line":1137},9,[377,1139,1140],{},"      paymentMethod={method}\n",[377,1142,1144],{"class":379,"line":1143},10,[377,1145,1146],{},"      email={email}\n",[377,1148,1150],{"class":379,"line":1149},11,[377,1151,1152],{},"      onCompleted={({ orderId }) => router.push(`\u002Fcheckout\u002Fconfirmation\u002F${orderId}`)}\n",[377,1154,1156],{"class":379,"line":1155},12,[377,1157,1158],{},"      onError={(err) => console.error(err)}\n",[377,1160,1162],{"class":379,"line":1161},13,[377,1163,1164],{},"    \u002F>\n",[377,1166,1168],{"class":379,"line":1167},14,[377,1169,1170],{},"  )\n",[377,1172,1174],{"class":379,"line":1173},15,[377,1175,1176],{},"}\n",[363,1178,1179,1180,512],{},"When the cart changes while the widget is open, the widget refreshes or restarts the session as needed. A changed price on the server is retried automatically and reported through ",[374,1181,1182],{},"onRepriced",[514,1184,1185,1193],{},[517,1186,1187],{},[520,1188,1189,1191],{},[523,1190,525],{},[523,1192],{},[532,1194,1195,1212,1232,1255,1268,1281,1293,1303,1319],{},[520,1196,1197,1202],{},[537,1198,1199],{},[374,1200,1201],{},"paymentMethod",[537,1203,1204,1205,1208,1209],{},"The ",[374,1206,1207],{},"PaymentMethod"," from ",[374,1210,1211],{},"usePaymentMethods()",[520,1213,1214,1227],{},[537,1215,1216,402,1219,402,1221,402,1224],{},[374,1217,1218],{},"email",[374,1220,840],{},[374,1222,1223],{},"customerType",[374,1225,1226],{},"companyId",[537,1228,1229,1230],{},"Passed to ",[374,1231,1088],{},[520,1233,1234,1238],{},[537,1235,1236],{},[374,1237,511],{},[537,1239,1240,402,1243,402,1246,402,1249,402,1252],{},[374,1241,1242],{},"placeOrder",[374,1244,1245],{},"pay",[374,1247,1248],{},"loading",[374,1250,1251],{},"failed",[374,1253,1254],{},"rejected",[520,1256,1257,1262],{},[537,1258,1259],{},[374,1260,1261],{},"onCompleted({ orderId, orderNumber })",[537,1263,1264,1265,512],{},"The order exists. Go to the confirmation with ",[374,1266,1267],{},"orderId",[520,1269,1270,1275],{},[537,1271,1272],{},[374,1273,1274],{},"onRedirect(url)",[537,1276,1277,1278,1280],{},"Hosted payment page. Return ",[374,1279,684],{}," to navigate yourself.",[520,1282,1283,1291],{},[537,1284,1285,402,1288],{},[374,1286,1287],{},"onError(error)",[374,1289,1290],{},"onRepriced(info)",[537,1292],{},[520,1294,1295,1300],{},[537,1296,1297],{},[374,1298,1299],{},"renderEmbedded({ session, kind })",[537,1301,1302],{},"Stripe and Nexi embedded: mount the provider's widget with your own keys",[520,1304,1305,1316],{},[537,1306,1307,402,1310,402,1313],{},[374,1308,1309],{},"renderAuthorize",[374,1311,1312],{},"renderRedirect",[374,1314,1315],{},"renderDirect",[537,1317,1318],{},"Replace the default buttons",[520,1320,1321,1326],{},[537,1322,1323],{},[374,1324,1325],{},"ref",[537,1327,1328],{},[374,1329,1330],{},"{ suspend, resume, restart }",[408,1332,1334],{"id":1333},"breadcrumbjsonld",[374,1335,1336],{},"\u003CBreadcrumbJsonLd \u002F>",[363,1338,1339,1340,1343],{},"Structured data for breadcrumbs. It renders a ",[374,1341,1342],{},"\u003Cscript type=\"application\u002Fld+json\">"," and can be used from a Server Component:",[367,1345,1347],{"className":419,"code":1346,"language":421,"meta":372,"style":372},"import { BreadcrumbJsonLd } from '@avvyr\u002Fstorefront-next'\n\n\u003CBreadcrumbJsonLd origin=\"https:\u002F\u002Fstore.se\" items={[{ name: 'Home', to: '\u002F' }, { name: 'Sofas', to: '\u002Fcategories\u002Fsofas' }, { name: product.name }]} \u002F>\n",[374,1348,1349,1354,1358],{"__ignoreMap":372},[377,1350,1351],{"class":379,"line":380},[377,1352,1353],{},"import { BreadcrumbJsonLd } from '@avvyr\u002Fstorefront-next'\n",[377,1355,1356],{"class":379,"line":431},[377,1357,435],{"emptyLinePlaceholder":434},[377,1359,1360],{"class":379,"line":438},[377,1361,1362],{},"\u003CBreadcrumbJsonLd origin=\"https:\u002F\u002Fstore.se\" items={[{ name: 'Home', to: '\u002F' }, { name: 'Sofas', to: '\u002Fcategories\u002Fsofas' }, { name: product.name }]} \u002F>\n",[363,1364,1365,1366,1369,1370,1373,1374,1208,1377,512],{},"Pass ",[374,1367,1368],{},"origin"," so the script is part of the server HTML. Without it, the component reads ",[374,1371,1372],{},"window.location.origin"," and renders only after hydration. To build the list in server code, use ",[374,1375,1376],{},"buildBreadcrumbList",[374,1378,1379],{},"@avvyr\u002Fstorefront-next\u002Futils",[408,1381,1383],{"id":1382},"pure-helpers-on-the-server","Pure helpers on the server",[363,1385,1386,1387,1390,1391,490,1393,402,1396,402,1398,402,1401,1404],{},"The package root is a client entry (",[374,1388,1389],{},"'use client'","), so a Server Component cannot call its functions. The helpers that server code also needs are exported from ",[374,1392,1379],{},[374,1394,1395],{},"buildCategoryTree",[374,1397,1376],{},[374,1399,1400],{},"marketPath",[374,1402,1403],{},"resolveMarket"," and the payment session helpers.",[1406,1407,1408],"style",{},"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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":372,"searchDepth":431,"depth":431,"links":1410},[1411,1414,1415,1416,1417],{"id":410,"depth":431,"text":413,"children":1412},[1413],{"id":628,"depth":438,"text":629},{"id":688,"depth":431,"text":691},{"id":1079,"depth":431,"text":1082},{"id":1333,"depth":431,"text":1336},{"id":1382,"depth":431,"text":1383},"The drop-in components in @avvyr\u002Fstorefront-next — cookie consent, customer assistant, payment widget and breadcrumb JSON-LD","md",null,{"questions":1422},{"en":1423},[1424,1425,1426,1427],"How do I add the cookie banner to a Next.js storefront?","How do I add the customer assistant chat in Next.js?","How do I render the payment step with AvvyrPaymentWidget?","How do I style the Avvyr components?",{"title":354,"description":1418},"mfwiqG2ypuLwNrYY4Y8B7C0F_7DXLFHgEgU1mMnIrAs",[1431,1420],{"title":350,"path":351,"stem":352,"description":1432,"children":-1},"Use the Storefront SDK in Server Components, Route Handlers and Server Actions, and what the storefront proxy does",1793388942257]