[{"data":1,"prerenderedAt":1263},["ShallowReactive",2],{"navigation_docs":3,"-docs-storefront-sdk-nextjs-server":357,"-docs-storefront-sdk-nextjs-server-surround":1258,"docs-site-config":1248},[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":350,"body":359,"description":1246,"extension":1247,"links":1248,"meta":1249,"navigation":446,"path":351,"seo":1256,"stem":352,"__hash__":1257},"docs\u002Fdocs\u002Fstorefront-sdk\u002F4.nextjs\u002F3.server.md",{"type":360,"value":361,"toc":1238},"minimark",[362,375,470,485,490,669,673,740,744,778,792,796,806,1007,1011,1021,1074,1077,1201,1212,1216,1234],[363,364,365,366,370,371,374],"p",{},"Import the server helpers from ",[367,368,369],"code",{},"@avvyr\u002Fstorefront-next\u002Fserver",". That entry point imports ",[367,372,373],{},"server-only",", so if client code imports it by mistake the build fails before the private key can leak.",[376,377,382],"pre",{"className":378,"code":379,"language":380,"meta":381,"style":381},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F lib\u002Fstorefront.ts\nimport { createStorefrontServer } from '@avvyr\u002Fstorefront-next\u002Fserver'\nimport config from '@\u002Fstorefront.config'\n\nexport const storefront = createStorefrontServer(config)\n","ts","",[367,383,384,393,423,441,448],{"__ignoreMap":381},[385,386,389],"span",{"class":387,"line":388},"line",1,[385,390,392],{"class":391},"sHwdD","\u002F\u002F lib\u002Fstorefront.ts\n",[385,394,396,400,404,408,411,414,417,420],{"class":387,"line":395},2,[385,397,399],{"class":398},"s7zQu","import",[385,401,403],{"class":402},"sMK4o"," {",[385,405,407],{"class":406},"sTEyZ"," createStorefrontServer",[385,409,410],{"class":402}," }",[385,412,413],{"class":398}," from",[385,415,416],{"class":402}," '",[385,418,369],{"class":419},"sfazB",[385,421,422],{"class":402},"'\n",[385,424,426,428,431,434,436,439],{"class":387,"line":425},3,[385,427,399],{"class":398},[385,429,430],{"class":406}," config ",[385,432,433],{"class":398},"from",[385,435,416],{"class":402},[385,437,438],{"class":419},"@\u002Fstorefront.config",[385,440,422],{"class":402},[385,442,444],{"class":387,"line":443},4,[385,445,447],{"emptyLinePlaceholder":446},true,"\n",[385,449,451,454,458,461,464,467],{"class":387,"line":450},5,[385,452,453],{"class":398},"export",[385,455,457],{"class":456},"spNyl"," const",[385,459,460],{"class":406}," storefront ",[385,462,463],{"class":402},"=",[385,465,407],{"class":466},"s2Zo4",[385,468,469],{"class":406},"(config)\n",[363,471,472,473,476,477,480,481,484],{},"Every helper reads the current request through ",[367,474,475],{},"next\u002Fheaders",", so pages that use them render dynamically, like a server-rendered Nuxt page. The helpers that touch the network are cached per request with React ",[367,478,479],{},"cache()",", so a layout and a page that both call ",[367,482,483],{},"storefront.session()"," share a single API call.",[486,487,489],"h2",{"id":488},"helpers","Helpers",[491,492,493,506],"table",{},[494,495,496],"thead",{},[497,498,499,503],"tr",{},[500,501,502],"th",{},"Helper",[500,504,505],{},"Returns",[507,508,509,532,546,560,578,590,603,616,632,642,655],"tbody",{},[497,510,511,517],{},[512,513,514],"td",{},[367,515,516],{},"storefront.client(options?)",[512,518,519,520,523,524,527,528,531],{},"SDK client for the request's market, with the private key. Options: ",[367,521,522],{},"market"," (another market), ",[367,525,526],{},"privateKey: false",", ",[367,529,530],{},"fetch"," (for example, to add Next cache options).",[497,533,534,539],{},[512,535,536],{},[367,537,538],{},"storefront.customerClient()",[512,540,541,542,545],{},"Client acting as the signed-in customer, or ",[367,543,544],{},"null"," without a session cookie",[497,547,548,552],{},[512,549,550],{},[367,551,483],{},[512,553,554,557,558],{},[367,555,556],{},"{ accessToken, customer }"," after verifying the session with the platform, or ",[367,559,544],{},[497,561,562,567],{},[512,563,564],{},[367,565,566],{},"storefront.requireSession()",[512,568,569,570,573,574,577],{},"Like ",[367,571,572],{},"session()",", but redirects to ",[367,575,576],{},"auth.loginPath?returnTo=…"," when there is no session",[497,579,580,585],{},[512,581,582],{},[367,583,584],{},"storefront.cart()",[512,586,587,588],{},"The visitor's cart from the cookies, or ",[367,589,544],{},[497,591,592,597],{},[512,593,594],{},[367,595,596],{},"storefront.cartClient()",[512,598,599,602],{},[367,600,601],{},"{ client, cartId }"," with the private key and the visitor's cart token, for server-only cart calls",[497,604,605,610],{},[512,606,607],{},[367,608,609],{},"storefront.market()",[512,611,612,613],{},"The active ",[367,614,615],{},"MarketConfig",[497,617,618,623],{},[512,619,620],{},[367,621,622],{},"storefront.marketInfo()",[512,624,625,626,629,630],{},"The market's settings from the API (delivery countries, ",[367,627,628],{},"pricesRequireLogin","), or ",[367,631,544],{},[497,633,634,639],{},[512,635,636],{},[367,637,638],{},"storefront.categories({ locale? })",[512,640,641],{},"Categories from the in-memory, stale-while-revalidate cache",[497,643,644,649],{},[512,645,646],{},[367,647,648],{},"storefront.initialState({ cart?, customer? })",[512,650,651,652],{},"The props for ",[367,653,654],{},"\u003CStorefrontProvider>",[497,656,657,662],{},[512,658,659],{},[367,660,661],{},"storefront.warmCategories()",[512,663,664,665,668],{},"Warms the category cache for every market (call it from ",[367,666,667],{},"instrumentation.ts",")",[486,670,672],{"id":671},"server-components","Server Components",[376,674,678],{"className":675,"code":676,"language":677,"meta":381,"style":381},"language-tsx shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F app\u002Fproducts\u002F[handle]\u002Fpage.tsx\nimport { notFound } from 'next\u002Fnavigation'\nimport { storefront } from '@\u002Flib\u002Fstorefront'\n\nexport default async function ProductPage({ params }: { params: Promise\u003C{ handle: string }> }) {\n  const { handle } = await params\n  const client = await storefront.client()\n  const product = await client.products.getByHandle(handle).catch(() => null)\n  if (!product) notFound()\n  return \u003CProductView product={product} \u002F>\n}\n","tsx",[367,679,680,685,690,695,699,704,710,716,722,728,734],{"__ignoreMap":381},[385,681,682],{"class":387,"line":388},[385,683,684],{},"\u002F\u002F app\u002Fproducts\u002F[handle]\u002Fpage.tsx\n",[385,686,687],{"class":387,"line":395},[385,688,689],{},"import { notFound } from 'next\u002Fnavigation'\n",[385,691,692],{"class":387,"line":425},[385,693,694],{},"import { storefront } from '@\u002Flib\u002Fstorefront'\n",[385,696,697],{"class":387,"line":443},[385,698,447],{"emptyLinePlaceholder":446},[385,700,701],{"class":387,"line":450},[385,702,703],{},"export default async function ProductPage({ params }: { params: Promise\u003C{ handle: string }> }) {\n",[385,705,707],{"class":387,"line":706},6,[385,708,709],{},"  const { handle } = await params\n",[385,711,713],{"class":387,"line":712},7,[385,714,715],{},"  const client = await storefront.client()\n",[385,717,719],{"class":387,"line":718},8,[385,720,721],{},"  const product = await client.products.getByHandle(handle).catch(() => null)\n",[385,723,725],{"class":387,"line":724},9,[385,726,727],{},"  if (!product) notFound()\n",[385,729,731],{"class":387,"line":730},10,[385,732,733],{},"  return \u003CProductView product={product} \u002F>\n",[385,735,737],{"class":387,"line":736},11,[385,738,739],{},"}\n",[486,741,743],{"id":742},"protected-pages","Protected pages",[376,745,747],{"className":675,"code":746,"language":677,"meta":381,"style":381},"\u002F\u002F app\u002Faccount\u002Fpage.tsx\nexport default async function AccountPage() {\n  const { customer } = await storefront.requireSession()\n  const orders = await (await storefront.customerClient())!.orders.list()\n  return \u003CAccount customer={customer} orders={orders} \u002F>\n}\n",[367,748,749,754,759,764,769,774],{"__ignoreMap":381},[385,750,751],{"class":387,"line":388},[385,752,753],{},"\u002F\u002F app\u002Faccount\u002Fpage.tsx\n",[385,755,756],{"class":387,"line":395},[385,757,758],{},"export default async function AccountPage() {\n",[385,760,761],{"class":387,"line":425},[385,762,763],{},"  const { customer } = await storefront.requireSession()\n",[385,765,766],{"class":387,"line":443},[385,767,768],{},"  const orders = await (await storefront.customerClient())!.orders.list()\n",[385,770,771],{"class":387,"line":450},[385,772,773],{},"  return \u003CAccount customer={customer} orders={orders} \u002F>\n",[385,775,776],{"class":387,"line":706},[385,777,739],{},[363,779,780,783,784,787,788,791],{},[367,781,782],{},"auth.protectedPaths"," in the config redirects signed-out visitors in the proxy before anything renders. It checks only that a session cookie exists, as the Nuxt ",[367,785,786],{},"auth"," middleware does. ",[367,789,790],{},"requireSession()"," also verifies the session with the platform.",[486,793,795],{"id":794},"server-actions","Server Actions",[363,797,798,801,802,805],{},[367,799,800],{},"cart.complete"," and other calls that need the private key are rejected from a browser (",[367,803,804],{},"403 SERVER_SIDE_KEY_REQUIRED","). Call them from a Server Action or a Route Handler:",[376,807,809],{"className":378,"code":808,"language":380,"meta":381,"style":381},"'use server'\nimport { storefront } from '@\u002Flib\u002Fstorefront'\n\nexport async function completeOrder(payment: { amount: number; currency: string }) {\n  const ctx = await storefront.cartClient()\n  if (!ctx) throw new Error('No cart')\n  return ctx.client.cart.complete(ctx.cartId, { payment })\n}\n",[367,810,811,821,841,845,897,922,960,1003],{"__ignoreMap":381},[385,812,813,816,819],{"class":387,"line":388},[385,814,815],{"class":402},"'",[385,817,818],{"class":419},"use server",[385,820,422],{"class":402},[385,822,823,825,827,830,832,834,836,839],{"class":387,"line":395},[385,824,399],{"class":398},[385,826,403],{"class":402},[385,828,829],{"class":406}," storefront",[385,831,410],{"class":402},[385,833,413],{"class":398},[385,835,416],{"class":402},[385,837,838],{"class":419},"@\u002Flib\u002Fstorefront",[385,840,422],{"class":402},[385,842,843],{"class":387,"line":425},[385,844,447],{"emptyLinePlaceholder":446},[385,846,847,849,852,855,858,861,865,868,870,874,876,880,883,886,888,891,894],{"class":387,"line":443},[385,848,453],{"class":398},[385,850,851],{"class":456}," async",[385,853,854],{"class":456}," function",[385,856,857],{"class":466}," completeOrder",[385,859,860],{"class":402},"(",[385,862,864],{"class":863},"sHdIc","payment",[385,866,867],{"class":402},":",[385,869,403],{"class":402},[385,871,873],{"class":872},"swJcz"," amount",[385,875,867],{"class":402},[385,877,879],{"class":878},"sBMFI"," number",[385,881,882],{"class":402},";",[385,884,885],{"class":872}," currency",[385,887,867],{"class":402},[385,889,890],{"class":878}," string",[385,892,893],{"class":402}," })",[385,895,896],{"class":402}," {\n",[385,898,899,902,905,908,911,913,916,919],{"class":387,"line":450},[385,900,901],{"class":456},"  const",[385,903,904],{"class":406}," ctx",[385,906,907],{"class":402}," =",[385,909,910],{"class":398}," await",[385,912,829],{"class":406},[385,914,915],{"class":402},".",[385,917,918],{"class":466},"cartClient",[385,920,921],{"class":872},"()\n",[385,923,924,927,930,933,936,939,942,945,948,950,952,955,957],{"class":387,"line":706},[385,925,926],{"class":398},"  if",[385,928,929],{"class":872}," (",[385,931,932],{"class":402},"!",[385,934,935],{"class":406},"ctx",[385,937,938],{"class":872},") ",[385,940,941],{"class":398},"throw",[385,943,944],{"class":402}," new",[385,946,947],{"class":466}," Error",[385,949,860],{"class":872},[385,951,815],{"class":402},[385,953,954],{"class":419},"No cart",[385,956,815],{"class":402},[385,958,959],{"class":872},")\n",[385,961,962,965,967,969,972,974,977,979,982,984,986,988,991,994,996,999,1001],{"class":387,"line":712},[385,963,964],{"class":398},"  return",[385,966,904],{"class":406},[385,968,915],{"class":402},[385,970,971],{"class":406},"client",[385,973,915],{"class":402},[385,975,976],{"class":406},"cart",[385,978,915],{"class":402},[385,980,981],{"class":466},"complete",[385,983,860],{"class":872},[385,985,935],{"class":406},[385,987,915],{"class":402},[385,989,990],{"class":406},"cartId",[385,992,993],{"class":402},",",[385,995,403],{"class":402},[385,997,998],{"class":406}," payment",[385,1000,410],{"class":402},[385,1002,959],{"class":872},[385,1004,1005],{"class":387,"line":718},[385,1006,739],{"class":402},[486,1008,1010],{"id":1009},"the-proxy","The proxy",[363,1012,1013,1016,1017,1020],{},[367,1014,1015],{},"createStorefrontProxy(config)"," from ",[367,1018,1019],{},"@avvyr\u002Fstorefront-next\u002Fproxy"," runs before every matched request:",[1022,1023,1024,1052,1062],"ol",{},[1025,1026,1027,1031,1032,1035,1036,1039,1040,1043,1044,1047,1048,1051],"li",{},[1028,1029,1030],"strong",{},"Market."," It resolves the market with the configured strategy and passes it to the server in the ",[367,1033,1034],{},"x-avvyr-market"," request header. With the ",[367,1037,1038],{},"path"," strategy it also rewrites the prefix away (",[367,1041,1042],{},"\u002Fno\u002Fproducts"," renders ",[367,1045,1046],{},"app\u002Fproducts\u002Fpage.tsx"," for the market ",[367,1049,1050],{},"no",").",[1025,1053,1054,1057,1058,1061],{},[1028,1055,1056],{},"Session."," If the access token has expired, or expires within ",[367,1059,1060],{},"auth.refreshSkewSeconds",", the proxy refreshes it and writes the new tokens to both the response and the request that the page renders with. Server Components cannot set cookies, and the platform ends a session when a rotated refresh token is used again, so this is the only safe place to refresh on the server. Concurrent requests that carry the same refresh token share one refresh. If no refresh token is still valid, the proxy deletes the session cookies in every scope where they may have been set.",[1025,1063,1064,1067,1068,1070,1071,915],{},[1028,1065,1066],{},"Protected paths."," Visitors without a session who request a path under ",[367,1069,782],{}," are redirected to the login page with ",[367,1072,1073],{},"returnTo",[363,1075,1076],{},"To run your own logic first (for example, a password gate for staging), wrap the proxy:",[376,1078,1080],{"className":378,"code":1079,"language":380,"meta":381,"style":381},"const storefrontProxy = createStorefrontProxy(storefrontConfig)\n\nexport async function proxy(request: NextRequest) {\n  if (needsPassword(request)) return NextResponse.redirect(new URL('\u002Fgate', request.url))\n  return storefrontProxy(request)\n}\n",[367,1081,1082,1098,1102,1127,1184,1197],{"__ignoreMap":381},[385,1083,1084,1087,1090,1092,1095],{"class":387,"line":388},[385,1085,1086],{"class":456},"const",[385,1088,1089],{"class":406}," storefrontProxy ",[385,1091,463],{"class":402},[385,1093,1094],{"class":466}," createStorefrontProxy",[385,1096,1097],{"class":406},"(storefrontConfig)\n",[385,1099,1100],{"class":387,"line":395},[385,1101,447],{"emptyLinePlaceholder":446},[385,1103,1104,1106,1108,1110,1113,1115,1118,1120,1123,1125],{"class":387,"line":425},[385,1105,453],{"class":398},[385,1107,851],{"class":456},[385,1109,854],{"class":456},[385,1111,1112],{"class":466}," proxy",[385,1114,860],{"class":402},[385,1116,1117],{"class":863},"request",[385,1119,867],{"class":402},[385,1121,1122],{"class":878}," NextRequest",[385,1124,668],{"class":402},[385,1126,896],{"class":402},[385,1128,1129,1131,1133,1136,1138,1140,1143,1146,1149,1151,1154,1156,1159,1162,1164,1166,1169,1171,1173,1176,1178,1181],{"class":387,"line":443},[385,1130,926],{"class":398},[385,1132,929],{"class":872},[385,1134,1135],{"class":466},"needsPassword",[385,1137,860],{"class":872},[385,1139,1117],{"class":406},[385,1141,1142],{"class":872},")) ",[385,1144,1145],{"class":398},"return",[385,1147,1148],{"class":406}," NextResponse",[385,1150,915],{"class":402},[385,1152,1153],{"class":466},"redirect",[385,1155,860],{"class":872},[385,1157,1158],{"class":402},"new",[385,1160,1161],{"class":466}," URL",[385,1163,860],{"class":872},[385,1165,815],{"class":402},[385,1167,1168],{"class":419},"\u002Fgate",[385,1170,815],{"class":402},[385,1172,993],{"class":402},[385,1174,1175],{"class":406}," request",[385,1177,915],{"class":402},[385,1179,1180],{"class":406},"url",[385,1182,1183],{"class":872},"))\n",[385,1185,1186,1188,1191,1193,1195],{"class":387,"line":450},[385,1187,964],{"class":398},[385,1189,1190],{"class":466}," storefrontProxy",[385,1192,860],{"class":872},[385,1194,1117],{"class":406},[385,1196,959],{"class":872},[385,1198,1199],{"class":387,"line":706},[385,1200,739],{"class":402},[363,1202,1203,1204,1207,1208,1211],{},"Without the proxy, the ",[367,1205,1206],{},"domain"," and ",[367,1209,1210],{},"cookie"," strategies still work and the browser still refreshes tokens on its own. However, the path strategy is not available, and a Server Component render after the access token expires sees the visitor as signed out until the browser has refreshed.",[486,1213,1215],{"id":1214},"head-scripts","Head scripts",[363,1217,1218,1221,1222,1225,1226,1229,1230,1233],{},[367,1219,1220],{},"\u003CStorefrontScripts config market \u002F>"," renders the dataLayer and Google Tag Manager bootstrap first in ",[367,1223,1224],{},"\u003Chead>",". It sets up the dataLayer, sets Consent Mode v2 to \"denied\", restores a choice already stored in the consent cookie, and only then loads the GTM container. It renders nothing when there is no GTM id and Consent Mode is off. ",[367,1227,1228],{},"NEXT_PUBLIC_GTM_ID"," takes precedence over ",[367,1231,1232],{},"config.analytics.gtm.id",", so you can set it in production only.",[1235,1236,1237],"style",{},"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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .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 .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":381,"searchDepth":395,"depth":395,"links":1239},[1240,1241,1242,1243,1244,1245],{"id":488,"depth":395,"text":489},{"id":671,"depth":395,"text":672},{"id":742,"depth":395,"text":743},{"id":794,"depth":395,"text":795},{"id":1009,"depth":395,"text":1010},{"id":1214,"depth":395,"text":1215},"Use the Storefront SDK in Server Components, Route Handlers and Server Actions, and what the storefront proxy does","md",null,{"questions":1250},{"en":1251},[1252,1253,1254,1255],"How do I fetch a product in a Next.js Server Component?","How do I complete a cart with the private key from a Server Action?","How do I read the signed-in customer on the server?","Why does the proxy refresh the access token?",{"title":350,"description":1246},"r7BFgEZ8FmWSymq74ZsmssgRFfqYRDM5b3GcSCD0U38",[1259,1261],{"title":346,"path":347,"stem":348,"description":1260,"children":-1},"All React hooks provided by @avvyr\u002Fstorefront-next",{"title":354,"path":355,"stem":356,"description":1262,"children":-1},"The drop-in components in @avvyr\u002Fstorefront-next — cookie consent, customer assistant, payment widget and breadcrumb JSON-LD",1793388942210]