# Rhino Inquisitor Full Corpus > Combined Markdown export of all indexable regular pages for large language model ingestion and retrieval. Use the canonical HTML URL for attribution. Markdown companion URLs are provided as machine-friendly alternates. --- ## Goodbye WordPress: Rebuilding This Blog With AI and No Database Canonical URL: https://rhino-inquisitor.com/goodbye-wordpress-rebuilding-this-blog-with-ai/ Markdown URL: https://rhino-inquisitor.com/goodbye-wordpress-rebuilding-this-blog-with-ai/index.md Content type: article Published: 2026-07-02T09:00:00Z Updated: 2026-07-02T09:00:00Z Summary: Why I moved Rhino Inquisitor off WordPress to a static Hugo site, how AI ran the migration, and the safeguards that kept every old URL alive. Categories: AI, Corporate Tags: ai, hugo, static site ## Key Takeaways - Explains why a blog with no dynamic content does not need a database, a server, or a stack of paid plugins - Walks through a real WordPress-to-Hugo migration run as 200 tickets across nine phases, with AI doing most of the typing - Details the safeguards - URL parity on 1,224 routes, redirect and canonical gates, a five-legged CI quality matrix - that made the cutover boring on purpose If you are reading this, you are looking at a blog that no longer has a database behind it. No MySQL. No admin login sitting on a public URL waiting to be brute-forced. No plugin update nagging me on a Sunday morning. The page you are on was built ahead of time, as a plain HTML file, and handed to you by a server that does nothing but pass files along. For years, Rhino Inquisitor ran on WordPress. WordPress is not a bad tool. It is a very good tool for a very specific problem: content that changes constantly, edited by people who should never touch a terminal, with comments and forms and user accounts. That is not this site. My content does not change while you read it. There are no contact forms, no logins, no shopping cart. It is articles and images. So I was paying - in money, in attention, and in risk - for a machine built to solve problems I do not have. This is the story of tearing that machine down and replacing it with something quieter. I will also be honest about the part that surprises people: I did not type most of it. AI did, under my direction, and I want to show you exactly where the line between the two of us sat. ## The bill I stopped wanting to pay A WordPress site is never just WordPress. Over time it becomes WordPress plus a caching plugin, plus a security plugin, plus an SEO plugin, plus whatever premium add-on you bought once and now cannot remove. Each one wants an update. Each update is a small bet that nothing will break. Underneath all of that sits the real cost: a database and a server that has to be alive every time someone visits. That server has to be patched. It has to be backed up. It has to be watched, because a public login page and a database are exactly what an attacker goes looking for. None of that work sells anything or teaches anyone anything. It is rent. Here is the reframe that started the whole project. My content is static. It sits still. So why serve it from a system designed to assemble every page, from scratch, on every single request? > A static site generator flips the timing. Instead of building each page when a visitor asks for it, it builds every page once, up front, into flat HTML. What ships is a folder of files. There is nothing to execute, nothing to query, and almost nothing to attack. I picked [Hugo](https://gohugo.io/) for the generator and GitHub Pages for hosting. The practical consequences are almost rude in how good they are: - **Hosting cost dropped to zero.** GitHub Pages serves the built site for free. There is no server invoice anymore. - **The attack surface mostly vanished.** No database means no database to breach. No PHP running on request means no runtime to exploit. The “admin panel” is now my own laptop and a git commit. - **There is nothing to monitor at 2 AM.** No uptime for a dynamic app, no plugin CVEs, no patch treadmill. The files are just there. There is a flip side to the security story that I want to name rather than hide. The whole site now lives in a public GitHub repository. That sounds alarming until you remember what is actually in it: no database, no credentials, no user data, nothing an attacker could turn against a visitor. The content is meant to be read by the world anyway. The one real consequence is that my drafts are visible before I publish them - if you go looking, you can read a half-finished post. That genuinely does not bother me. But it is the kind of thing you should choose on purpose, not trip over after the fact. The trade is real, and I will not pretend otherwise: I gave up the comfortable WordPress editor and took on more custom work. Writing is now Markdown in my editor. Publishing is a git push. Layout and features are templates I own. For a developer, that is a good trade. For someone who never wants to see a config file, it would be a terrible one. Know which one you are before you copy me. There is one more upside to plain Markdown that I did not fully appreciate until I was living in it. The old WordPress content was HTML - nested divs, wrapper classes, editor cruft. Markdown is just text with a little punctuation. That is easy for me to write, and it turns out to be even easier for a machine to read. Given how much of my workflow now runs through AI, that matters more than it used to: an agent parses a clean Markdown file far more reliably than it untangles rendered HTML. The thing I write and the thing the machine reads are now the same file. ## The honest part: who actually did the work Now the question I get asked most. How much of this did AI do? A lot. More than a lot. And I would rather tell you plainly than let you assume I hand-crafted every line. I ran the migration like a real project, not a weekend hack. There was a full ticketing system - 200 tickets in the end - grouped into nine phases, from URL inventory all the way to the go-live cutover. There were role-based AI agents: a business analyst to write requirements, a project manager to sequence tickets, a developer to implement, a QA engineer to try to break it, a docs researcher to check claims against official Salesforce and Hugo documentation. I directed. They typed. ![A migration project board showing nine phases and a long column of numbered tickets being worked through.](/goodbye-wordpress-rebuilding-this-blog-with-ai/migration-ticket-board_hu_82570619ec82068b.webp) Nine phases, two hundred tickets. The migration ran like a proper project - because a blog with four years of URLs behind it is not something you eyeball. That framing matters, so let me be exact about the division of labour. I made the decisions: static over dynamic, Hugo over the alternatives, which URLs live and which retire, what “done” meant. AI did the volume: parsing the old WordPress export, converting every post to Markdown, downloading and re-linking every image, drafting tickets, writing the redirect maps, building the quality gates that check its own output. The commit history is not shy about it either. Plenty of commits are co-authored with the model, in the open, on purpose. This is the same stance I took years ago in [AI as Architect and Content Creator](/ai-as-an-architect-and-content-creator/): the expertise and the judgement are mine, the speed is the machine’s. What changed since then is how much of the grunt work I am now willing to hand over. Migrating four years of posts by hand would have taken weeks and I would have made careless mistakes around post two hundred. The machine does not get bored on post two hundred. It does, however, get confidently wrong - which is exactly why the next section exists. ## The safeguards, or: how not to torch your search rankings Here is the part that separates a migration from a disaster. When you move a site that has been indexed by Google for years, the fastest way to destroy it is to change or drop URLs. Every old link, every search result, every bookmark points at an address. Break those addresses and the traffic evaporates. So the single hardest rule of the whole project was this: **every URL that mattered had to keep working.** An entire phase existed just for that. I inventoried the old routes, classified each one as _keep_, _merge_, or _retire_, and wrote a redirect map so that anything I moved still lands somewhere sensible in one hop - no chains, no dead ends. Then I made the machine prove it, over and over, automatically. The site cannot deploy unless it passes a matrix of quality gates running in parallel: 1. **URL parity** - checks that all 1,224 tracked routes still resolve correctly. On the last run before launch: 1,224 out of 1,224, zero blocking failures. 2. **SEO** - canonical tags, sitemaps, metadata, and structured data all have to line up. 3. **Security** - HTTPS, redirects, and headers on the live host. 4. **Accessibility** - real browser checks, not guesses. 5. **Performance** - Lighthouse budgets under throttled mobile conditions. > A gate is only useful if it can actually block you. These are wired as required checks: if any leg fails, the deploy does not happen. It is deliberately harder to ship a regression than to ship correctly. ![Five parallel deploy gates in a row, with one page held back at a red light while the others pass through.](/goodbye-wordpress-rebuilding-this-blog-with-ai/deploy-quality-gate_hu_68d41be23b77632c.webp) Five gates, all required. A single red light anywhere and nothing ships - which is exactly the point. That performance gate earned its keep. After a visual redesign - a warm, paper-and-ink look I built to replace the old theme - the site started failing its layout-stability score. Pages were visibly jumping as they loaded. The culprit was subtle: I inline a small “critical” stylesheet for fast first paint and load the full stylesheet afterwards, and after the redesign those two had quietly drifted apart. Seventy-three design tokens no longer matched. When the full stylesheet finally applied, it re-laid-out the top of the page - a search bar snapping from 399 pixels tall down to 44 - and that jump is exactly what the gate measures. The fix was to stop hand-maintaining the critical CSS and generate it directly from the real, rendered pages, so it can never silently drift from the full stylesheet again. Layout shift went from an ugly ~0.5 back down to essentially zero. I would not have caught that by eye across every page type. The gate did. ## Tearing down the scaffolding There is one more step people forget. The 200 tickets, the phase plans, the migration scripts that parsed WordPress exports, the role-based agents - all of that was scaffolding. It got the site up. It has no business living in the repository of a site that is now, simply, live. So once the cutover held, I deleted it. The migration tooling, the ticket archive, the WordPress-specific import code, the analysis folder - gone. I tagged the pre-cleanup state first, so the history is preserved if I ever want to look back, then stripped the repo down to what a running blog actually needs. What stayed is only the machinery that protects the live site: the URL data, the redirect maps, and the quality gates. A house does not keep the scaffolding after the walls are up. That is also why this post reads as a story rather than a manual. By the time you read it, the thing it describes has already been removed. What is left is the point of the whole exercise: a blog that is cheaper, safer, and calmer to run. ## Was it worth it? Yes, and it is not close. I traded a monthly hosting bill for nothing. I traded a database and a public admin panel - a genuine, ongoing security liability - for a folder of static files with almost no attack surface. I traded a patch-and-plugin treadmill for a system I forget is even running until I want to publish, at which point I write Markdown and push. The custom work is real and I own it now, but I would rather own a simple thing than rent a complicated one. And the AI question, one more time, because it is the honest core of this: the machine did most of the labour, I made every decision that mattered, and the guardrails I built to check its work are still watching the site right now, on every deploy. That is the arrangement I trust. Not “AI did it,” and not “I did it all by hand.” I decided, it built, and neither of us gets to ship anything the gates do not approve. Welcome to the new place. It is quieter here. --- ## Real-Time Inventory Checks in SFCC Canonical URL: https://rhino-inquisitor.com/real-time-inventory-checks-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/real-time-inventory-checks-in-sfcc/index.md Content type: article Published: 2026-02-09T11:11:31Z Updated: 2026-02-09T13:10:33Z Summary: Learn when real-time inventory checks improve the customer experience, where they add risk, and how to balance speed with accuracy. Categories: Architecture, Salesforce Commerce Cloud Tags: architect, sfcc, technical ## Key Takeaways - Explains why naive real-time inventory calls can destroy storefront performance even when the business wants perfect accuracy - Introduces practical patterns like threshold-based checks, caching, async updates, and event-driven integration - Frames Omnichannel Inventory as the strategic buy-versus-build answer for complex Salesforce-centric enterprises In the world of digital commerce, the “In Stock” button is more than a piece of data; it’s a promise to your customer. Break that promise with a follow-up “sorry, we oversold” email, and you’re not just losing a sale—you’re torching brand trust. This is the reality that keeps business stakeholders up at night. They demand absolute inventory certainty to protect the customer experience. However, for us, the architects and developers in the trenches of Salesforce B2C Commerce, this demand presents a significant technical challenge. The most straightforward path to real-time accuracy—a live, synchronous API call for every product view—is a direct declaration of war on your storefront’s performance. It’s a surefire way to cripple your Time to First Byte (TTFB), overload your backend systems, and cause your site to crash precisely during a high-stakes launch or sales event. This isn’t just a technical decision; it’s a high-stakes balancing act between the ideal of accuracy and the practical limits of performance. This is every architect’s nightmare. Successfully managing this balance distinguishes experienced professionals from those overwhelmed by the challenge. ## The Omnichannel Imperative: Why Your Inventory Is Lying Let’s be brutally honest: if you’re selling on more than one channel, your SFCC storefront’s native inventory is, by default, a snapshot of a moment in time. It’s a well-intentioned liar. Modern retail is no longer a set of isolated storefronts. It’s a fluid ecosystem where a single stock pool serves your SFCC site, your brick-and-mortar stores with BOPIS, third-party marketplaces, and every other channel you can imagine. This isn’t a trend; it’s the new standard operating procedure. The business demands a single source of truth for inventory, because without it, you’re not an omnichannel brand—you’re just multiple businesses fumbling under the same logo. This is where the problem begins. SFCC’s native inventory system is perfectly capable for a business that _only_ sells through SFCC. It tracks stock, manages pre-orders, and calculates Available-to-Sell (ATS) quantities based on the data it has. But that data typically arrives via periodic batch imports—often an XML feed dropped into Business Manager. This introduces latency. It’s a picture of what inventory _was_, not what it _is_. When a product sells out in a physical store, your SFCC site remains blissfully unaware for the next 15, 30, or 60 minutes, leaving a gaping window for overselling. This forces a critical architectural shift: the source of truth for inventory can no longer be SFCC. It must be a centralised master system, like an ERP or OMS. SFCC is demoted from master to consumer, and the need for real-time checks is born not from a flaw in the platform, but from the fundamental reality of a distributed commerce landscape. ## The Hammer Effect: How Real-Time Calls Kill Your Storefront So, you decide to implement a real-time inventory check on the Product Detail Page (PDP). Architecturally, this means every page load now triggers a blocking, outbound API call to your external inventory system. Congratulations, you’ve just handed a sledgehammer to every user on your site and pointed them at your backend. ### The Anatomy of a Slowdown Here’s what happens when you make that call: 1. A user requests a PDP. 2. The eCDN gets a cache miss because inventory is now dynamic. The request is passed to the SFCC application tier. 3. Your server-side controller logic initiates an outbound API call to the external ERP/OMS. 4. The entire page render process **stops and waits**. It waits for the network round-trip. It waits for the external system to process the query. It waits for the response to come back. 5. Only after the response is received can SFCC finish building the page and send the first byte back to the user’s browser. > **Asynchronous:** You can, of course, defer a part of your page to an asynchronous API call - but keep reading for some important considerations! ### TTFB Under Fire That wait time directly murders your Time to First Byte (TTFB). Salesforce has performance targets for a reason: 300ms for a PDP (`Product-Show`), 400ms for the cart. A single external API call can easily blow past those targets, turning a snappy user experience into a frustrating crawl. A slow TTFB isn’t just a bad metric; it’s a conversion killer. ### The Self-Inflicted Denial of Service ![Cartoon infographic showing SFCC storefront generating API calls that hammer a legacy ERP system, causing cascading failure with 504 Gateway Timeout](/real-time-inventory-checks-in-sfcc/self-inflicted-dos-f3485c24ab_hu_a22259e8b0afde6b.webp) Naive real-time inventory checks can overload the very systems they depend on. This cartoon illustrates how high traffic on an e-commerce storefront (SFCC) can overload a legacy backend system, creating a “self-inflicted denial of service.” The resulting timeouts and failures cascade, ultimately bringing the entire online store to a grinding halt. This gets exponentially worse under load. During a flash sale, thousands of simultaneous users on your PDPs translate into thousands of concurrent API calls hammering your external inventory system. This is the “Hammer Effect.” Many ERPs, especially legacy ones, weren’t built for this kind of web-scale abuse. They slow down, time out, or fall over completely. The consequences reverberate back to SFCC. The platform has a hard 10-second timeout on Shopper APIs; exceed it, and the user gets a 504 Gateway Timeout. The Service Framework’s circuit breakers will trip if the external system consistently fails to respond, causing subsequent calls to fail instantly. You risk exceeding your API quotas, which can lead to blocked functionality. You’ve created a cascading failure, where a slow dependency starves the platform of resources, grinding the entire storefront to a halt at the most critical moment. ## Your First Line of Defense: Caching the Uncacheable Given that naive real-time calls are a performance catastrophe, caching isn’t an optimisation—it’s a prerequisite for survival. SFCC provides multiple layers of caching, from the full Page Cache at the eCDN level down to fragment caching with remote includes. The problem with inventory is its volatility. If you have inventory data with a 60-second stale time on a page with product details, that can have an 8-hour caching lifetime. This is where the architect’s true weapon comes into play: [the SFCC caching armoury](/third-party-api-caching-in-commerce-cloud/). This knowledge unlocks more intelligent strategies. You’re not just caching data; you’re caching a _decision_ (e.g., `isOrderable = true`), which is far more powerful and efficient. ## The Pragmatist’s Playbook: The Hybrid Threshold Model ![Bar graph showing inventory threshold model with high stock using cached checks and low stock triggering real-time API calls](/real-time-inventory-checks-in-sfcc/inventory-threshold-model-dfa3d5bd0f_hu_e16a50f51c9d4511.webp) A threshold model balances fast answers with selective real-time verification. The playbook is simple and pragmatic. Above the threshold, you serve a cached ‘in-stock’ status for maximum speed. Once an item drops below that critical line, you switch tactics to precise, real-time API calls. This balances performance with accuracy. The Hybrid Threshold Model is a battle-tested, pragmatic pattern that allocates your performance budget where the business risk is highest. It accepts that not all inventory levels carry the same risk of overselling. ### The Core Logic The model is governed by a “low stock threshold”—a simple number (e.g., 5 units) that dictates the system’s behaviour. This concept is a common feature in e-commerce platforms, triggering urgency messaging. - **Path 1: Above the Threshold (The Fast Lane):** When SFCC’s internal inventory record shows stock is comfortably above the threshold, the risk of overselling is low. The system **does not** make a real-time call. It serves a generic, cached “In Stock” message. This response is lightweight and can be cached for a reasonable duration (e.g., 15-120 minutes). This path handles the vast majority of traffic, ensuring lightning-fast PDP loads. - **Path 2: At or Below the Threshold (The Accuracy Zone)** When stock drops to or below the threshold, the game changes. The cached status is invalidated. Now, every request for this product’s availability triggers a live, synchronous API call to the external master to get the _exact_ count. To prevent hammering the backend for a popular low-stock item, this live response is itself [cached](/third-party-api-caching-in-commerce-cloud/), but with a very aggressive TTL (e.g., 10-30 seconds). ### The Trade-Offs This is a powerful compromise, but it’s not a silver bullet. ### Pros - **Performance on a Massive Scale:** You eliminate costly external calls for the bulk of your catalog, dramatically improving average TTFB and site responsiveness. - **Backend System Shield:** The cache absorbs most of the load, protecting your often-fragile ERP or OMS from the “Hammer Effect.” - **Risk-Aligned Architecture:** You spend your performance budget only when the business risk of an oversell is tangible. ### Cons - **Custom Development Required:** This isn’t a checkbox in Business Manager. It requires custom logic to manage the dual paths, the custom cache, and the invalidation process. - **Minor Race Condition:** A small window of risk remains. If the threshold is 5 and SFCC shows 6, two customers could check out before the next batch feed runs. This is why a final, definitive real-time check during the final order submission is **non-negotiable**. The PDP check is for browsing performance; the checkout check is for transactional integrity. ## Leveling Up: Advanced Tactics for the Bold For those who want to push performance even further, two advanced patterns stand out. ### Asynchronous Front-End Checks (AJAX - React) This pattern decouples the inventory check from the initial page render entirely. 1. The server sends the PDP’s HTML to the browser _immediately_, without any inventory data, resulting in a stellar TTFB. The page appears with a placeholder like “Checking availability…” 2. Client-side JavaScript then makes an asynchronous (AJAX) call to a dedicated, lightweight SFCC API endpoint. 3. When the response arrives, the JavaScript updates the placeholder with the real stock status. The user-perceived performance is phenomenal. The core content loads instantly, and the secondary stock information fills in a moment later. This can be combined with the Hybrid Threshold Model on the backend API endpoint for maximum effect. This is also a perfect use case for client-side rendering in the PWA Kit. ### Event-Driven Architecture (EDA): The Paradigm Shift This is the enterprise-grade solution. Instead of SFCC _pulling_ data on demand, the master inventory system _pushes_ updates whenever a change occurs. 1. An **event broker** (like Kafka or RabbitMQ) sits at the heart of the architecture. 2. When a sale happens in a physical store, the POS system publishes an `InventoryDecremented` event to the broker. 3. A custom service subscribed to this event stream immediately [updates](https://developer.salesforce.com/docs/commerce/commerce-api/references/inventory-lists?meta=updateProductInventoryRecord) the inventory record within SFCC. This approach maintains SFCC’s native inventory in a near-real-time state, eliminating the need to block outbound calls during the shopper’s journey. It represents the pinnacle of performance and scalability, but it requires a significant architectural investment. But wait… an external system pushing inventory near real-time to SFCC inventory lists… that sounds familiar. ## The Salesforce Answer: Is Omnichannel Inventory (OCI) Your Silver Bullet Salesforce is acutely aware of this architectural nightmare. Their answer is Omnichannel Inventory (OCI), a headless, API-first, and highly scalable inventory service designed to be the single source of truth. I wrote [an extensive article](/what-is-oci-omnichannel-inventory/) on this topic a while ago, so I recommend reading it. ### The Build vs. Buy Decision For any retailer on the Salesforce platform, the choice becomes clear: do you build your own custom EDA, or do you buy Salesforce’s purpose-built one? #### OCI Benefits (“Buy”) - **Speed:** OCI significantly reduces the development time and complexity of building a custom eventing platform from scratch. - **Lower TCO:** While there’s a license cost, it pales in comparison to the expense of building, maintaining, and monitoring a custom, high-availability integration platform. One case study projected a 32% reduction in IT costs for a retailer that adopted a solution including OCI. - **Scalability & Cohesion:** It’s built by Salesforce, for Salesforce. It’s designed to scale and integrate seamlessly with the rest of the Customer 360 platform, powering a unified experience that can have a real top-line impact—the same study projected a 40% increase in sales. A custom solution only makes sense in the rarest of cases. For the vast majority of multi-channel retailers on Salesforce, OCI is the most logical, scalable, and cost-effective path to sanity. ## Your Architectural Mandate ![Decision tree showing three inventory strategy tiers for SFCC-only, pragmatic omnichannel, and Salesforce-centric enterprises](/real-time-inventory-checks-in-sfcc/the-inventory-architectural-decision-fc1b43abe0_hu_1457083d36f5bd43.webp) Inventory strategy should match the retailer's omnichannel maturity, not wishful thinking. The right inventory strategy is a direct reflection of your business’s omnichannel maturity. There is no one-size-fits-all answer, only a series of strategic trade-offs. Here is your mandate, based on your profile. - **Tier 1: The SFCC-Only Purist** - **Profile:** You sell only through your SFCC site from a dedicated stock pool. - **Mandate:** Stick with **native SFCC inventory** and reliable batch updates. Anything else is over-engineering. Focus on making your import jobs fast and frequent. - **Tier 2: The Pragmatic Omnichannel Player** - **Profile:** You sell across SFCC and physical stores from a shared inventory. You need to stop the bleeding from oversells and fix site performance _now_. - **Mandate:** Implement the **Hybrid Threshold Model with Asynchronous AJAX checks**. This is your sweet spot. It delivers the best balance of performance, accuracy, and implementation effort without requiring a complete overhaul of your architecture. - **Tier 3: The Salesforce-Centric Enterprise** - **Profile:** You’re a large, complex enterprise running multiple brands and channels, deeply invested in the Salesforce ecosystem. Unified commerce is a core strategic goal. - **Mandate:** Adopt **Salesforce Omnichannel Inventory (OCI)**. Don’t even think about building it yourself. The “buy” decision is a strategic imperative that will deliver faster time-to-market, lower TCO, and a future-proof foundation for true unified commerce. Choosing an inventory strategy is one of the most critical architectural decisions you will make. It dictates your site’s performance, your customers’ trust, and your operational sanity. Don’t just build for today’s traffic; architect a platform that can withstand tomorrow’s complexities. --- ## Developer's Guide to Combating Fraud in SFCC Canonical URL: https://rhino-inquisitor.com/a-dev-guide-to-combating-fraud-on-sfcc/ Markdown URL: https://rhino-inquisitor.com/a-dev-guide-to-combating-fraud-on-sfcc/index.md Content type: article Published: 2026-01-19T08:02:08Z Updated: 2026-01-19T08:02:08Z Summary: Enhance your security beyond the basics on Salesforce B2C Commerce Cloud with this comprehensive guide tailored for developers. Categories: Salesforce Commerce Cloud Tags: sfcc ## Key Takeaways - Breaks down major eCommerce fraud patterns SFCC developers need to recognize - Shows how native SFCC controls, custom rules, and scoring can work together - Compares third-party fraud tools by bot defense, analyst control, and guarantees Your checkout flow isn’t just a conversion funnel; it’s a battleground. Every order placed is a potential skirmish with bad actors looking to exploit your system for financial gain. For developers on the Salesforce B2C Commerce Cloud (SFCC) platform, preventing fraud is not merely a business concern—it’s a technical mandate. It falls squarely within our domain to architect defences that are both robust and intelligent. Under the Salesforce Shared Responsibility Model, Salesforce secures the core platform and infrastructure; however, the security of custom code, configurations, and data handling is the customer’s (or partner’s) responsibility. This is where we, the developers, step up. Effective fraud prevention is not a tool you install; it’s a multi-layered fortress you build. Each layer serves a specific purpose, from deterring obvious bots at the gate to conducting in-depth forensic analysis on suspicious transactions within the walls. This guide serves as your architectural blueprint for the fortress. We’ll begin by understanding the enemy, dissecting the modern fraud landscape to identify patterns we can target with code. Next, we’ll master the native toolkit, wielding SFCC’s built-in features to construct our foundational defences. Then, we’ll get our hands dirty, diving into server-side JavaScript to write custom validation rules and a bespoke risk-scoring engine. Finally, we’ll survey the professional mercenaries on the AppExchange, calling in specialised reinforcements when the fight demands it. This is the definitive guide for SFCC developers on fraud prevention, packed with actionable code, clear-headed analysis, and an unbiased look at the partner ecosystem. _Let’s build our fortress._ ![A cartoon illustration depicting a stone fortress labeled 'Checkout Flow'. Developers equipped with tools are building defensive machines labeled 'Fraud Prevention Layers' and 'Risk Scoring' to protect the castle from cartoon burglars, with a Salesforce shield hanging above the gate.](/a-dev-guide-to-combating-fraud-on-sfcc/the-sfcc-fortress-for-fraud-5d4d80990b_hu_5feb692f8877d4fe.webp) Fraud prevention works best as layers around the checkout, not as one last-minute rule. ## Know Your Enemy - A Developer’s Taxonomy of eCommerce Fraud To write effective defensive code, we must first understand the attack vectors. The modern fraud landscape is a far cry from the simple days of a stolen credit card number. It is now a sophisticated, often automated, criminal enterprise that costs merchants not only lost revenue and products but also incurs hefty chargeback fees and, most critically, erodes customer trust. ### Deconstructing the Threats Fraudulent activities are diverse, each with unique technical fingerprints. As developers, our job is to translate these abstract threats into concrete, detectable data patterns. #### Card-Not-Present (CNP) Fraud This is the foundational threat of all e-commerce. By its very nature, an online transaction is a [Card-Not-Present](https://stripe.com/resources/more/what-is-card-not-present-fraud-what-businesses-need-to-know) (CNP) transaction, meaning the physical card cannot be inspected. This lack of physical verification is the central vulnerability that fraudsters exploit. They acquire the necessary card details—card number, expiration date, CVV, and billing address—through a variety of illicit means, including phishing campaigns, malware that scrapes data from infected devices, and purchasing troves of stolen information from data breaches on the dark web. #### Account Takeover (ATO) Fraud A more advanced form of identity theft, [Account Takeover](https://www.ic3.gov/CrimeInfo/AccountTakeover) (ATO), occurs when a fraudster gains unauthorised access to a legitimate customer’s account. They achieve this through methods such as credential stuffing, where automated bots test lists of usernames and passwords stolen from other data breaches, exploiting the common user habit of reusing passwords. Once inside, the fraudster can make purchases using stored payment methods, change shipping addresses to intercept goods, drain loyalty points, or steal sensitive personal data for further attacks. #### “Friendly” Fraud (Chargeback Abuse) This is one of the most challenging types of fraud to combat because it originates from a seemingly legitimate customer. Friendly fraud occurs when a customer makes a valid purchase but then contacts their credit card issuer to dispute the charge, falsely claiming the item never arrived, was defective, or that the transaction was unauthorised. The merchant loses the product, the revenue, and is hit with a [chargeback](https://www.radial.com/types-of-ecommerce-fraud) fee from the bank. Because the initial transaction markers—IP address, billing information, device fingerprint—all appear perfectly normal, it bypasses many traditional fraud filters. #### Bot-Driven Attacks Automated bots are the force multipliers of the fraud world, enabling criminals to execute attacks at a scale and speed impossible for humans. - **Card Testing (Card Cracking):** Bots are used to make thousands of small, often $1, transactions to test the validity of massive lists of stolen credit card numbers. A successful small transaction confirms the card is active and can be used for larger fraudulent purchases later. - **Inventory Hoarding/Depletion Fraud:** During high-demand events like product launches or flash sales, bots can swamp a site to buy up all available limited-stock inventory. These items are then resold on secondary markets at inflated prices, denying legitimate customers the opportunity to purchase and damaging brand perception. #### Sophisticated Schemes ![A cartoon illustration depicting complex fraud schemes. One section illustrates 'Triangulation Fraud' showing a circular flow between a fraudster, a legitimate merchant, and an unsuspecting customer. Another section depicts 'Synthetic Identity Fraud' as a figure assembling a fake persona using puzzle pieces labeled with different personal data points like 'SSN' and 'Name'.](/a-dev-guide-to-combating-fraud-on-sfcc/advanced-fraud-schemes-81670fc67f_hu_e9bd5184bbdc226f.webp) Modern fraud is not one pattern, which is why the defense strategy cannot be one-dimensional. Beyond simple theft: A visual breakdown of how fraudsters manipulate supply chains through Triangulation and manufacture new personas via Synthetic Identity fraud. As merchants’ defences improve, fraudsters devise more complex schemes. - **Triangulation Fraud:** This is a cunning three-party scheme. A fraudster sets up a fake online store or an auction listing for a popular product at a low price. An unsuspecting customer buys the item and provides their payment and shipping details. The fraudster then uses that shipping information to access a legitimate merchant’s website (like yours) and purchases the same item with a different, stolen credit card, which is then shipped directly to the original customer. The fraudster pockets the customer’s initial payment, the legitimate merchant is hit with a chargeback from the card’s owner, and the customer receives the product, often unaware that their actions have fueled a fraudulent transaction. - **Synthetic Identity Fraud:** This is one of the fastest-growing and most dangerous forms of financial crime. Instead of stealing a single, complete identity, fraudsters combine pieces of real, stolen information (like a valid Social Security number) with fabricated details (a fake name and address) to create a brand-new, fictitious identity. This “synthetic” identity has no prior credit history, making it difficult for traditional systems to flag as fraudulent. The fraudster can then use this identity to open new lines of credit, make purchases, and commit fraud that is incredibly difficult to trace back to a real person. The evolution from simple CNP fraud to more complex schemes, such as synthetic identity and triangulation, marks a critical shift. Fraudsters are no longer just exploiting stolen data; they are creating fraudulent entities and manipulating entire supply chains. This progression means a static fraud detection strategy is doomed to fail. Defences must evolve from simple data point validation (e.g., “does the CVV match?”) to holistic, pattern-based analysis (“does this entire transaction _profile_ look legitimate?”). This reality underscores the need for a custom risk-scoring engine and machine learning-based third-party tools that will be discussed in later chapters. ## Translating Threats to Code: Actionable Red Flags For a developer, understanding these schemes is only half the battle. The crucial step is identifying the digital fingerprints they leave behind in the order data available within SFCC. These red flags are the triggers for our custom logic. ### Data Mismatches A classic indicator is a mismatch between the IP address geolocation and the billing or shipping address, especially across countries (e.g., an order placed from a Singaporean IP address with a US billing address). ### Velocity & Behavior Anomalies Watch for patterns that defy normal human behavior. This includes multiple orders placed from the same IP address using different credit cards but shipping to the same address, a high volume of transactions in a very short time, or a series of failed payment attempts followed by a successful one. ### Order Characteristics Be wary of unusually large orders, particularly from new or guest customers, as fraudsters try to maximize their payout before being caught. Another key indicator is a request for rushed or overnight shipping, as this minimizes the window for the merchant to detect the fraud and halt the shipment. ### Identity Indicators The quality of the data can be telling. The use of temporary or disposable email domains is a significant red flag. Inconsistencies in names, or names that are clearly gibberish, also warrant suspicion. Before writing a single line of custom fraud logic or evaluating a third-party cartridge, it’s critical to maximise the platform’s inherent capabilities. Salesforce provides a set of powerful, foundational tools that form the first layers of your defensive fortress. The platform’s philosophy is not to provide a single, monolithic fraud solution, but rather to offer secure, extensible building blocks that empower developers and partners to create tailored defences. This approach recognises that every merchant’s risk profile is unique and that a one-size-fits-all solution is often ineffective. ## The Native Toolkit - Wielding SFCC’s Built-in Defenses ### The First Line of Defense: The eCDN Every request to your storefront first passes through Salesforce’s embedded Content Delivery Network (eCDN). This is your outermost wall. The primary tool here for developers is eCDN Custom Rules, which have replaced the older, more rigid firewall rules. These rules give you granular control over incoming traffic based on a wide array of request parameters. Using the [eCDN API](https://developer.salesforce.com/docs/commerce/commerce-api/guide/cdn-zones-custom-rules.html), you can construct powerful expressions to filter traffic before it ever hits your application servers. For example, you can create a rule to block requests originating from known malicious IP ranges, countries where you don’t ship, or specific user agents associated with malicious bots. The flexibility of these rules, which can key off of URI paths, user agents, IP addresses, and more, makes the eCDN a formidable first line of defence against automated threats. ![A cartoon illustration showing SFCC's native defense toolkit. On the left, a developer uses eCDN Custom Rules and API to block malicious traffic and bots from entering a castle. In the middle, Payment Processing Fundamentals are depicted with AVS and CVV checks passing or failing a credit card. On the right, a Commerce Cloud Einstein robot states it's for merchandising and sales, not fraud prevention, debunking a myth.](/a-dev-guide-to-combating-fraud-on-sfcc/native-sfcc-features-15503da1e4_hu_cf8ec46dd3daf6c7.webp) SFCC has useful native controls, but they are only part of a serious fraud strategy. Leveraging SFCC’s built-in defenses: The eCDN as the first line against malicious traffic, fundamental payment processing checks (AVS/CVV), and clarifying the role of Commerce Cloud Einstein. ### Payment Processing Fundamentals SFCC is designed to be payment-agnostic, allowing seamless integration with major processors, such as Adyen, Braintree, Stripe, and Cybersource, through configuration in the Business Manager. When configuring these processors, enable and enforce payment processor features, such as **Address Verification System (AVS)** and **Card Verification Value (CVV)** checks. AVS compares the numeric parts of the billing address provided by the customer to the address on file with the card issuer, while the CVV check validates the 3- or 4-digit code on the card. While not foolproof against sophisticated fraudsters, these checks are a fundamental, non-negotiable first pass that can filter out a significant volume of low-effort fraud. ### Debunking a small Myth: The Role of Commerce Cloud Einstein The robust Einstein features in B2C Commerce are mainly merchandising tools aimed at improving the customer experience and increasing sales. However, they do not include any functions to prevent fraud. ### Debunking a larger Myth: Salesforce B2C protects against all types of bots Many customers and partners believe that Salesforce implements protections against bots, [but this is not the case](https://developer.salesforce.com/docs/commerce/commerce-solutions/guide/bot-management.html). Salesforce places this responsibility on the customer, as they do not want to be the gate that filters between “legitimate customers” and bots, as the risk of false positives is too high, especially since this varies by region and industry. Since the eCDN behind the scenes is Cloudflare, some protections are enabled by default, but more complex bots will require you to look elsewhere. > B2C Commerce doesn’t identify bots as good or bad, nor do we suggest whether certain traffic is allowed to make purchases on our commerce platform. Our customers have the flexibility to adopt the bot management strategy that aligns with their business needs. > > Salesforce Help ## Foundational Security Practices (The Developer’s Responsibility) According to the shared responsibility model, developers are responsible for the security of their custom code and configurations. Adhering to these best practices is non-negotiable. - **Authentication & Authorisation:** Enforce strict, server-side access control checks for all sensitive business functions. In SFRA, use the [userLoggedIn](https://help.salesforce.com/s/articleView?id=cc.b2c_developer_authentication_and_authorization.htm&type=5) middleware to protect controller endpoints that should only be accessible to authenticated users. Never trust that a request is legitimate just because it was sent; always validate on the server. - **Guest Shopper Security:** Guest checkouts are a major vector for fraud because they lack the historical context of a registered account. Implementing robust authorisation for guest order lookup is critical. Never grant access to an order solely based on the order number. At a minimum, require a combination of the order number, the email address used for the order, and the billing postal code to prevent unauthorised users from accessing order details. - **Data Validation:** Proper validation of all user-provided input is the bedrock of application security. This is your primary defence against a host of vulnerabilities, including Cross-Site Scripting (XSS) and server-side script injection. - **Bot Management:** Salesforce’s official stance is that it provides the tools for bot management (like eCDN rules and rate limiting), but **_the strategy and ongoing tuning are the customer’s responsibility_**. Salesforce does not classify bots as “good” or “bad,” as a bot that is desirable for one merchant (e.g., a search engine crawler) may be malicious for another (e.g., an inventory scraper). ## Getting Your Hands Dirty: The Custom Scoring Engine For the bold and the brave, relying solely on third-party scores isn’t the only option. It is entirely possible to roll up your sleeves and engineer your own custom risk-scoring engine directly on the platform. Using a combination of script hooks (`beforePOST` for headless or `fraudDetection.js` for SFRA), custom objects (watch the [quota](/why-circumventing-sfcc-quota-limits-is-a-bad-idea/)) to store historical data, and calls to external services, you can create a sophisticated system tailored precisely to the fraud patterns you observe. This gives you ultimate control over the logic and allows for a highly nuanced approach that a generic solution might miss. However, let’s be crystal clear: this is not a trivial task. Building a reliable fraud detection system is a complex challenge in software engineering. You are essentially building a stateful, data-driven application within your e-commerce platform. Some of the building blocks for such a system would include: - **Address Scoring:** Programmatically comparing billing and shipping addresses. Are they in the same country? Same city? Do they look like mail forwarders? - **IP Verification & Geolocation:** Integrating with an IP intelligence service to check if the customer’s IP is a known proxy or data centre, and comparing its location to the billing address country. - **Velocity Checks:** Tracking how many orders are placed by an IP, a customer email, or a device fingerprint within a certain timeframe. This requires diligent use of Custom Objects to maintain state. - **Email Domain Risk:** Analysing the customer’s email address. Is it from a disposable email provider? - **High-Risk Order Profiling:** Flagging orders that combine multiple risk factors, such as a new customer placing an unusually large, high-demand product order to be shipped to a different country. The most critical aspect of running your own custom solution is that its maintenance becomes your paramount responsibility. A poorly tuned algorithm is a double-edged sword; it might block fraudsters, but it can also create a torrent of “false positives,” blocking legitimate, high-value customers who then leave your site frustrated. **_You must commit to continually monitoring, logging, and analysing both blocked and successful transactions to refine your rules_**. Fraud prevention is not easy, and when you build it yourself, the responsibility falls entirely on you and your codebase. ## Calling in the Cavalry - A Guide to Third-Party Fraud Solutions ![A cartoon illustration depicting 'The Cavalry' of third-party fraud solutions. Armored knights ride cybernetic horses toward a castle labeled 'Salesforce Commerce Cloud.' Signposts highlight specific vendors like 'Riskified & Signifyd' (Peace of Mind), 'Kount' (Control), and 'DataDome' (Bot Defense), while knights carry banners representing 'Global Data' and 'Machine Learning.'](/a-dev-guide-to-combating-fraud-on-sfcc/calling-the-cavalry-fea1bcb812_hu_b40cd906ffbbd1f7.webp) Third-party tools earn their keep when scale or risk outgrows the native platform controls. When custom rules aren’t enough, it’s time to call in the cavalry. Third-party solutions bring global data networks, advanced AI, and financial guarantees to reinforce your Salesforce Commerce Cloud defense. While a custom-built rules engine is a powerful first line of defense, there comes a point where the scale and sophistication of fraud attacks demand more advanced weaponry. This is where third-party fraud prevention solutions from the Salesforce AppExchange become invaluable. These services offer three key advantages over an in-house solution: access to a massive, global network of shared transaction data; sophisticated machine learning (ML) models that are impossible to build and train independently; and, in many cases, the ability to offload financial liability through a chargeback guarantee. ### Vendor Deep Dives The third-party ecosystem is not monolithic; different vendors specialise in solving different parts of the fraud problem. The choice is not about which is “best,” but which is best for your specific pain point. These platforms dedicate all their resources to combating fraud and offer powerful tools that integrate directly with Salesforce Commerce Cloud. They typically handle the decision-making process for you and protect your revenue with sophisticated AI and massive data networks. Here’s a look at some leading providers and who they are best for: - **[Riskified](https://appexchange.salesforce.com/appxListingDetail?listingId=d719d10c-198a-4d46-9df8-c4a8920c023e)** & [Signifyd](https://www.signifyd.com/salesforce-commerce-cloud/)**:** Merchants who want a “set it and forget it” solution with financial peace of mind. Their key offering is a chargeback guarantee, making them ideal for businesses that want to maximize sales approvals while completely offloading the financial risk of fraudulent chargebacks. - **[Kount](https://kount.com/partners/salesforce-commerce-cloud-fraud-prevention/):** Businesses with in-house fraud teams that want control and deep insights. Kount provides a wealth of data and customizable rules, empowering merchants to actively manage their own fraud prevention strategy and fine-tune their risk tolerance. - **[DataDome](https://appexchange.salesforce.com/appxListingDetail?listingId=6dfa8305-611a-4752-8bd5-b51e0144a80a):** Retailers are heavily targeted by malicious bots and automated attacks. This is a foundational security layer, ideal for businesses that need to prevent credential stuffing, card testing, and scraper bots from reaching the checkout stage and causing damage. ## Architecting Your Fortress - A Layered and Evolving Strategy In the digital marketplace, trust is the ultimate currency, and as Salesforce B2C Commerce developers, we are its primary architects. Combating fraud is not a feature to be installed but a system to be architected—a dynamic, multi-layered fortress designed to protect both the business and its customers. The path to a resilient storefront is a clear, strategic progression. First, we build the **Foundation**. This involves mastering the native toolkit SFCC provides. We harden the perimeter with eCDN custom rules to filter malicious traffic, and we ensure our payment processing is secure by leveraging 3D Secure with Salesforce Payments or rigorously enforcing AVS and CVV checks with third-party gateways. We adhere to security best practices in our own code, implementing strict authentication and authorisation checks for every sensitive operation. Second, we deploy our own **Custom Rules**. Using the available information, we write server-side JavaScript to enforce business-specific logic, allowing us to build a simple risk engine that detects obvious fraud patterns tailored to our unique business context. Finally, when the threat landscape demands it, we call in the **Specialised Reinforcements**. We turn to the expert solutions on the AppExchange, making a strategic choice based on our specific needs. Whether it’s offloading chargeback liability to Riskified or Signifyd, mitigating bot attacks with DataDome, or empowering an in-house team with Kount, we leverage the partner ecosystem to bring world-class machine learning and global intelligence to our defence. Fraud prevention is an ongoing campaign, not a single battle. The threat is constantly evolving, and so too must our defences. By understanding the enemy, mastering the platform’s tools, writing intelligent custom code, and strategically leveraging the partner ecosystem, SFCC developers can build the secure, trustworthy, and resilient storefronts that define successful e-commerce. --- ## The Kickstart Guide for New Salesforce B2C Commerce Developers Canonical URL: https://rhino-inquisitor.com/kickstart-guide-for-new-sfcc-developers/ Markdown URL: https://rhino-inquisitor.com/kickstart-guide-for-new-sfcc-developers/index.md Content type: article Published: 2026-01-12T14:05:43Z Updated: 2026-01-12T14:05:43Z Summary: An interactive guide for new SFCC developers covering storefront patterns, platform concepts, and practical next steps for hands-on learning. Categories: Salesforce Commerce Cloud Tags: composable storefront, developer, sfcc, sfra, sitegenesis ## Key Takeaways - Provides a broad onboarding map for new SFCC developers from architecture to tooling and platform concepts - Explains the practical differences between SiteGenesis, SFRA, and composable storefront development - Connects performance, security, caching, and environment discipline into a realistic learning path So, you’ve decided to tame the beast that is Salesforce B2C Commerce Cloud (SFCC). Congratulations, and welcome to the jungle. If you’re feeling a bit overwhelmed by the sheer [scale](/sitegenesis-vs-sfra-vs-pwa/) of the platform, with its myriad features, acronyms, and unique architectural quirks, don’t worry – we’ve all been there. SFCC isn’t just an e-commerce platform you can master over a weekend; it’s an enterprise-grade ecosystem, forged over decades, designed for the world’s biggest brands. Its complexity is a direct reflection of its power. I’ve been in the commerce world for more than a decade, and I’ve dedicated a significant part of my career to mastering this platform. On this blog, I share my knowledge to help others succeed in the Ohana. [I’ve written before about where to start your journey](/where-to-start-when-you-are-new-to-salesforce-b2c-commerce-cloud-development/), but this post is different. This is the deep dive. This is the comprehensive guide I wish I had when I was starting out. We’re going to cut through the noise and build a foundational understanding from the ground up. We’ll cover the lay of the land, the tools of the trade, the core mechanics of [development](/getting-to-know-sfra-as-a-developer/), and the hard-won lessons from the trenches. So, roll up your sleeves, fire up your IDE, and let’s get started. This is your kickstart guide to becoming a formidable SFCC developer. ## The Lay of the Land: Your First 10,000-Foot View In this Kickstart Before you write a single line of code, you need to understand the map of the world you’re about to enter. SFCC has a specific structure and terminology that is fundamental to everything you’ll do. Getting this right from day one will save you countless hours of confusion. ### Understanding the Realm & Instance Structure At the highest level, your [SFCC environments](/understanding-sfcc-instances/) are organised into a **Realm**, which is a collection of instance groups allocated to your organisation. Within a realm, you have two primary types of instance groups: - **Primary Instance Group (PIG):** This is where the magic happens for your live site. It contains the three core environments that form the backbone of any project’s lifecycle: 1. **Development:** A shared environment for developers to integrate their work and for QA to test features. 2. **Staging:** A pre-production environment used for final testing, data replication, and client UAT. It’s meant to be a mirror of Production. 3. **Production:** The live storefront that serves your customers. - **Secondary Instance Group (SIG):** This group houses your **Sandboxes**. A [sandbox](/how-to-get-a-salesforce-b2c-commerce-cloud-sandbox/) is your personal development playground. It’s, when provisioned, an empty environment where you can test new ideas, develop features, and break things without any real-world consequences. The flow is critical: [developers](/understanding-sfcc-instances/) work on features in their individual sandboxes. Once complete, the code is pushed and integrated into the shared Development instance. From there, it moves to Staging for final validation, and finally, it’s deployed to Production. _**A word of warning**_: getting your hands on a sandbox is essential for learning. Watching webinars and reading documents can get tedious; you need to apply what you learn immediately. However, if you are not working for an official Salesforce partner or a customer, acquiring a sandbox can be extremely difficult (but not impossible). I explain the process in my article on [getting a sandbox as a developer](/how-to-get-a-salesforce-b2c-commerce-cloud-sandbox/), but be prepared for this potential roadblock. ### The Business Manager: Your Command Center ![A flat-style cartoon illustration of a high-tech command center featuring two operators monitoring multiple screens of analytics and storefront data, symbolizing the Salesforce B2C Commerce Cloud Business Manager interface for this kickstart guide.](/kickstart-guide-for-new-sfcc-developers/business-manager-sfcc-command-center-79bc109bf3_hu_672b694e33757594.webp) Figure 1: A flat-style cartoon illustration of a high-tech command center featuring two operators monitoring multiple screens of analytics and storefront data, symbolizing the Salesforce B2C Commerce Cloud Business Manager interface for this kickstart guide If the instance structure is the map, the **Business Manager (BM)** is your command centre. It’s a web-based tool that serves as the central nervous system for your entire storefront. It’s not just a simple “admin panel”; it’s a powerful interface where merchandising, administration, and development configurations converge. As a developer, you’ll find yourself wearing two hats within the Business Manager: 1. **The Merchant Hat:** You’ll need to understand the tools that [merchandisers](https://help.salesforce.com/s/articleView?id=cc.b2c_merchandising_your_site.htm&type=5) use daily to manage the site’s data. This includes managing product catalogues, creating promotions and campaigns, handling imagery, and setting up search preferences. You won’t be doing their job, but you need to know how the data they manage interacts with the code you write. 2. **The Administrator/Developer Hat:** This is your primary domain. Under the `Administration` tab, you’ll perform critical development tasks like managing code versions, [configuring](https://help.salesforce.com/s/articleView?id=cc.b2c_getting_started.htm&type=5) site cartridge paths, setting up data import/export jobs, managing API clients, and controlling the site cache. You’ll also work with powerful merchandising tools like **Page Designer** and **Content Slots**. While merchandisers use these [tools](/salesforce-b2c-commerce-cloud-content-erd/) to build pages visually, developers create the underlying custom components that power them. Understanding the Business Manager isn’t optional; it’s a core competency for any SFCC developer. ### The Great Architectural Divide: SFRA, Composable, and the Ghost of SiteGenesis This is one of the most critical and often confusing topics for newcomers. The architecture you build dictates everything about your development process. There are [three](/sitegenesis-vs-sfra-vs-pwa/) names you’ll hear constantly: SiteGenesis, SFRA, and Composable Storefront (or PWA Kit). Let’s clear this up once and for all. - **SiteGenesis (SG):** This is the legacy architecture. Let me be blunt: if anyone suggests you start a new project on SiteGenesis in this day and age, you should question their motives. It was built on an outdated technology called **pipelines** - a visual workflow tool for server-side logic that is no longer supported by modern development tools, and for which it is challenging to find experienced developers. Since 2020, third-party cartridge providers are no longer required to support SiteGenesis, signalling that Salesforce has firmly moved on. It is not mobile-first, and customising it often involves duplicating large amounts of code, leading to maintenance nightmares. - **Storefront Reference Architecture (SFRA):** The modern industry-standard architecture for most new SFCC projects. Introduced around 2016, SFRA was a complete paradigm shift away from SiteGenesis. It is built on a **mobile-first** philosophy and uses a familiar Model-View-Controller (MVC) pattern. Instead of proprietary Pipelines, it uses modern **JavaScript controllers** that will be comfortable to anyone with experience with Node.js or Express.js. Its key advantage is an extensible cartridge-based model that lets you layer customisations on top of a base template without modifying the core code, dramatically improving maintainability and making upgrades easier. For a deeper dive, I’ve written a detailed comparison in my article [**SiteGenesis vs SFRA vs PWA**](/sitegenesis-vs-sfra-vs-pwa/). - **Composable Storefront (PWA Kit & Managed Runtime):** This is the future-facing, **headless** architecture. Where SFRA is a “monolithic” application (the front-end and back-end are tightly coupled), the Composable Storefront decouples them completely. The front-end is typically a Progressive Web App (PWA) built with **React** and runs on a separate server environment called the **Managed Runtime**. This front-end communicates with the SFCC back-end (which still handles all the commerce logic) via REST APIs, specifically the Salesforce Commerce API (SCAPI) and the Open Commerce API (OCAPI). This approach provides maximum flexibility for the user experience but requires a more significant investment and a different skillset, including strong React expertise. It represents a major shift in the ecosystem, and I discuss the implications for developers in my article about [**the move from SiteGenesis and SFRA to the Composable Storefront**](/the-move-from-sitegenesis-and-sfra-to-the-composable-storefront-as-a-developer/). The evolution from SiteGenesis to SFRA and now to Composable isn’t just a series of technical upgrades; it’s a mirror of the entire e-commerce industry’s journey from tightly-coupled platforms to API-first, headless solutions. This progression has profound implications for you as a developer. In the SiteGenesis era, you needed a highly specialised, platform-specific skill set centred on Pipelines. SFRA opened the doors to a broader pool of web developers by adopting more standard technologies, such as JavaScript controllers. Today, the rise of the Composable Storefront means that a top-tier SFCC developer can’t just be an expert in the platform’s back-end; they must also be a competent modern front-end developer, proficient in frameworks like React and Node.js. To stay relevant and valuable, you must understand that your learning path doesn’t end with SFRA. This reality connects directly to the themes I explore in my articles about how [**AI won’t steal your job, but a developer using AI will**](/ai-wont-steal-your-sfcc-job-but-a-developer-using-ai-will/)—it’s about adapting and expanding your skill set. ## Gearing Up: Your Essential Developer Toolkit Now that you understand the landscape, it’s time to set up your digital workbench. Using the right tools from the start will make your development process faster, more efficient, and less prone to error. ### The Modern Workspace: VS Code While you might hear veterans talk about an old IDE called UX Studio, the modern standard for SFCC development is **Visual Studio Code (VS Code)** combined with your SFCC plugin of choice, such as [**Prophet**](https://marketplace.visualstudio.com/items?itemName=SqrTT.prophet). This setup provides the robust features you’d expect from a modern development environment. This setup is vastly superior to older methods because it integrates seamlessly with version control systems like Git and provides the powerful debugging and code navigation tools necessary for complex projects. ### Code Deployment and Versioning Once you have code written locally, you need to get it onto your sandbox. This is typically done via a command-line script that pushes your cartridges to the instance specified in a `dw.json` file in your project root. However, just pushing the code isn’t enough. You then need to go into the Business Manager and **activate** it. Navigate to `Administration > Site Development > Code Deployment`. Here you will see a list of all code versions that have been uploaded to the instance. You can have multiple versions on an instance, but only one can be active at a time. Activating a version tells the platform which set of code to execute. ### The Cartridge Path: Where Order Is Everything The **cartridge path** is arguably the most important and unique concept in SFCC development. It is the mechanism that allows for SFCC’s powerful extensibility. Think of it like layers of paint: the last layer you apply is the one you see. In Business Manager, under `Administration > Sites > Manage Sites > Settings`, you define a colon-separated list of cartridge names. A typical path looks like this: `app_custom_mybrand:plugin_payment:app_storefront_base` When a request comes in for a specific [controller](https://beeit.io/blog/getting-started-with-controllers-models-and-decorators-sfcc) or template (e.g., `Cart-Show`), the system searches for that resource from **left to right** in the cartridge path. 1. It first looks in `app_custom_mybrand`. If it finds a `Cart.js` controller, it uses that one and stops searching. 2. If not found, it looks in `plugin_payment`. 3. If it’s still not found, it finally looks in the base cartridge, `app_storefront_base`. This is how you customize the storefront. You never modify `app_storefront_base` directly. Instead, you create a new controller or template with the same name in your custom cartridge (`app_custom_mybrand`), and it will automatically override the base version. But what if you don’t want to completely replace a controller, but just add some logic before or after it runs? For this, [SFRA provides](https://developer.salesforce.com/docs/commerce/sfra/guide/b2c-sfra-modules.html) the `superModule`. By requiring `superModule` in your custom controller, you can use `server.prepend()` to execute code _before \_ the base controller’s route, `server.append()` to execute code \_ after_, or `server.replace()` to override it completely. This extensibility model is powerful, but it comes with a responsibility. A developer’s architectural choices here have massive long-term consequences for the site’s maintainability. The easy path is often to copy an entire base controller into your custom cartridge and make a small change. This is a `replace` by default. However, a year later, when Salesforce releases a critical security patch for that base controller, your site won’t receive it because you’ve completely overridden the original file. Your code is now brittle and carries significant technical debt. The more disciplined, correct approach is to use `prepend` or `append` whenever possible to inject only the logic you need, preserving the underlying base functionality and its future upgrade path. This discipline is a key differentiator between a junior and a senior SFCC developer. ### File Management with WebDAV For managing large volumes of files—like product images, data import/export feeds, and system logs—you’ll use a protocol called **WebDAV (Web Distributed Authoring and Versioning)**. Think of it as a network drive for your SFCC instance. You can connect to it using client applications like Cyberduck or FileZilla. As I cover in my [**Beginner’s Guide to WebDAV**](/a-beginners-guide-to-webdav-in-sfcc/), its primary uses for a developer are : - **Import/Export:** The `/impex` folder is the main hub for data transfer. You’ll upload your XML or CSV import files here for the Jobs Framework to process. - **Catalogs & Content Libraries:** You can manage static content assets and library files directly. - **Log Files:** The `/logs` directory contains all the system logs, including error logs and custom debug logs, which are indispensable for troubleshooting. Authentication can be handled via your Business Manager user account (using Basic Auth) or through dedicated [API clients](/your-definitive-mobile-app-checklist/) for automated processes. It’s vital to configure permissions correctly in the Business Manager to ensure that users and systems only have access to the directories they need. ### Data, Data, Everywhere: Custom Objects & Jobs SFCC provides a rich set of standard business objects (like Product, Order, Customer), but you’ll almost always need to store additional, business-specific data. You can achieve this in two ways: 1. **Extend System Objects:** You can add custom attributes to existing system objects. For example, you could add a `loyaltyTier` attribute to the `Profile` object. This is done in `Administration > Site Development > System Object Types`. I’ve written about using this technique to create **Custom Preferences** for site-wide settings. 2. **Create Custom Objects:** For data that doesn’t fit into a standard object, you can define entirely new custom object types with their own attributes. This is done in `Administration > Site Development > Custom Object Types`. For handling large-scale data operations—like importing a catalog with millions of products or exporting all orders from the last quarter—you’ll use the **Jobs Framework**. Jobs are processes that run asynchronously in the background, either on a schedule or on demand. They are essential for any task that would be too slow or memory-intensive to run in a storefront request. A common and powerful type of job step is the **chunk-oriented job step**. This is designed to process a large list of items by breaking it into manageable chunks, preventing you from hitting platform memory limits. To learn how to build these correctly, I highly recommend my deep-dive article, [**Mastering Chunk-Oriented Job Steps in Salesforce B2C Commerce Cloud**](/mastering-chunk-oriented-job-steps-in-salesforce-b2c-commerce-cloud/). For specialised cases involving large sets of static key-value data, you can also look into [**Leveraging Generic Mappings for Efficient Data Integration**](/leveraging-generic-mappings-in-sfcc/). ## Pro-Level Tips & Tricks from the Trenches The following advice is born from years of experience, project launches, and late-night troubleshooting sessions. Mastering the basics is one thing; internalising these principles is what will make you a truly effective developer. ### Performance is Not an Afterthought, It’s the First Thought In the multi-tenant SaaS world of SFCC, performance is non-negotiable. Your inefficient code doesn’t just slow down your site; it consumes shared resources and can theoretically impact the stability of the entire platform for other tenants. Every millisecond is money, and a slow e-commerce site is a silent killer of sales. - **Caching is King:** This is the single most important performance concept in SFCC. There are multiple layers of caching, and your goal is always to serve a request from the highest (fastest) layer possible. The layers are: 1. Shopper’s Browser 2. eCDN (Content Delivery Network) 3. Web Server (Page Cache) 4. Application Server (Custom Caches) 5. Database **I cover caching strategies for APIs in [Leveraging Server-Side Caching to Improve SFCC REST API Speed](/caching-rest-apis-in-sfcc/)** and for the modern stack in [**Caching in the Salesforce Composable Storefront**](/caching-in-the-sfcc-composable-storefront/). - **Image Optimization with DIS:** Huge, unoptimized images are a primary culprit for slow page loads. SFCC’s **Dynamic Image Service (DIS)** is your best friend here. It allows you to upload one high-resolution source image and then transform it on-the-fly via URL parameters—resizing, cropping, and changing quality—without ever touching the original. My guide, [**Image-ine: Salesforce B2C Commerce Cloud DIS for Developers**](/image-ine-sfcc-dis-for-developers/), is a must-read on this topic. - **Frontend Optimization:** Don’t forget the basics. Minify your JavaScript and CSS, reduce the number of HTTP requests, and place your CSS in the `` and your JavaScript just before the closing `` tag for better perceived performance. For a detailed look at how to manage this in SFRA, see my post on [**how to load client-side JavaScript and CSS**](/how-to-load-client-side-javascript-and-css-in-sfra/). And for the Composable world, the principles in [**From Lag to Riches: A PWA Kit Developer’s Guide to Storefront Speed**](/lag-to-riches-a-pwa-kit-developers-guide/) are essential. A fundamental challenge in SFCC development is the inherent tension between personalisation and performance. Every piece of dynamic, user-specific content (like “Welcome, Thomas!” or a personalised product recommendation) is a potential cache miss. A cache miss means the request has to travel all the way down to the application server, which is orders of magnitude slower and less scalable than serving from the page cache. A junior developer might tackle a personalised homepage banner by adding logic directly to the main homepage controller. This action makes the _entire_ homepage uncacheable, as its content now varies for every user. During a sales event, this would be catastrophic, as every single visitor would hit the application server directly, likely causing a site-wide slowdown. A senior developer, on the other hand, learns to “[think in cache layers](https://www.sfcclearning.com/blog/isml-template-best-practices/).” They would implement the generic homepage to be fully cacheable and then use a **remote include** (``) for just the small, personalised banner area. This way, the vast majority of the page is served instantly from the highly scalable page cache for all users. At the same time, only the tiny, dynamic component triggers a separate, uncached request to the application server. Mastering this technique of isolating dynamic content is a core architectural principle for building high-performance SFCC sites. ### Fort Knox Security: Your Responsibility Salesforce provides an incredibly secure platform, but this guarantee ends where your custom code begins. A single insecure line of code can create a vulnerability. You, the developer, are on the front lines of protecting your customers’ data and your clients’ businesses. I strongly urge you to read and implement the advice in my article, [**Three things you can do today to secure your SFCC environment**](/three-things-to-secure-sfcc/). The key takeaways are: 1. **Audit User Access:** Regularly review who has access to your Business Manager environments in Account Manager. Enforce the principle of least privilege. Does that old contractor still need production admin rights? Absolutely not. 2. **Secure Your Code:** Be vigilant about common web vulnerabilities. The most common in SFCC is Cross-Site Scripting (XSS), which occurs when you render user-provided input without properly encoding it. Always use functions that encode output, like ``, to sanitise data. 3. **Secure Third-Party Access:** Document every external system that integrates with your site via API keys (OCAPI, SCAPI, WebDAV). Ensure their API clients have the absolute minimum permissions required to do their job. An ERP that only needs to update orders should not have an API key that can also delete your entire product catalog. ## The Danger Zone: Warnings and Pitfalls to Avoid This section is about the landmines. These are the common, painful, and sometimes subtle mistakes that I’ve seen new developers make time and time again. Heed these warnings. ### Don’t Fight the Platform: Respect the Quotas SFCC imposes various **quotas**—limits on things like API calls per minute, the number of custom objects, and the size of arrays in memory. These are not arbitrary restrictions designed to make your life difficult. They are essential guardrails in a multi-tenant environment, designed to ensure that one tenant’s poorly written, resource-hungry code doesn’t degrade performance for everyone else on the same server. I once wrote an article, [**Why Circumventing Salesforce B2C Commerce Cloud Quota Limits Is a Bad Idea**](/why-circumventing-sfcc-quota-limits-is-a-bad-idea/), as a cautionary tale. In it, I built a custom “UnlimitedArray” to get around the platform’s array size limit. While technically possible, the resulting code was a performance and maintenance disaster. The lesson is critical: work _with_ the platform’s constraints, not against them. If you’re hitting a quota, it’s almost always a sign that your approach is flawed and you need to rethink your design to be more efficient, not to find a clever way to cheat the system. ### The Cache Invalidation Nightmare There’s a famous saying in computer science: “There are only two hard things: cache invalidation and naming things.” This is profoundly true in SFCC. Improperly managed cache clearing can cause more problems than it solves. Here are the cardinal sins of [cache](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-troubleshooting-platform-performance.html) management: - **Clearing the entire site cache for a minor change:** Need to update a single content asset? Don’t use the “Invalidate All” button. This forces every single page on your site to be regenerated by the application server, which can cause a massive performance spike. Investigate more granular options like Page Cache Partitions for targeted invalidation. - **Clearing cache during peak traffic:** This is the absolute worst time to do it. You are voluntarily taking down your site’s primary defense mechanism right when you need it most. - **Repeatedly clearing the cache:** Some systems have a “cool down” period after an invalidation request. Hammering the “clear cache” button can actually interfere with the process and prevent the cache from ever fully clearing, leaving you with maddeningly persistent stale data. ### Subtle Traps in Code and Configuration Finally, here are a few specific “gotchas” that bite new developers: - **The Remote Include Asset Trap:**You’ll find that including client-side assets using the standard `assets.js` helper doesn’t work inside a remote include (``). This is because the asset list is scoped to a single request, and a remote include is technically a separate, internal request. I explain this specific problem and how to work around it in my guide to**[loading client-side JavaScript and CSS in SFRA](/how-to-load-client-side-javascript-and-css-in-sfra/).** - **Massive Image Folders:** While WebDAV is great, dumping a million product images into a single folder is a recipe for terrible performance, both for file system listing and for your import/export jobs. Salesforce recommends a maximum of 100,000 files per folder. You must have a strategy for organizing images into a logical sub-folder structure. - **Orphaned Objects from Failed Imports:** If a large catalog import job fails midway through, it can leave your data in an inconsistent state, for example, with products created but not assigned to their categories. Always design your import jobs to be restartable and, where possible, use delta feeds that only contain changes rather than full replacements. Ultimately, most of these pitfalls stem from a single root cause: failing to understand and respect that SFCC is a shared, multi-tenant SaaS platform. The quotas, the aggressive caching, and the “dangerous” operations are all consequences of this architecture. When you internalize that you are a citizen in a shared environment, you will naturally start to code in a way that is performant, scalable, and stable. ## Conclusion: Your Journey Has Just Begun We’ve covered a tremendous amount of ground, from the high-level architecture of the platform to the nitty-gritty details of caching and security. If you’ve made it this far, you now have a solid foundation on which to build a successful career as a Salesforce B2C Commerce Cloud developer. But this is just the beginning. Mastering this platform is a marathon, not a sprint. The key is continuous learning and community engagement. The Salesforce ecosystem’s greatest strength is its people—the Ohana. For our specific niche, we have the **#CommerceCrew**, a global group of developers, architects, and merchants who are passionate about sharing knowledge. I highly encourage you to join the conversation in the unofficial SFCC Slack community; it is an invaluable resource for getting questions answered and learning from your peers. Remember that the path of a developer is one of constant growth. Today you’re learning the basics of SFRA; tomorrow you might be building a headless PWA Kit application, and the day after that, you could be on [**the journey from developer to architect**](/the-journey-from-developer-to-architect/). It’s a challenging but incredibly rewarding path. As I wrote when **[reflecting on my own journey with this blog](/reflecting-on-2-years-of-blogging/)**, the key is to stay curious, stay engaged, and never stop learning. Welcome to the community. Now go build something amazing. --- ## Mobile App Launch Checklist for Commerce Teams Canonical URL: https://rhino-inquisitor.com/your-definitive-mobile-app-checklist/ Markdown URL: https://rhino-inquisitor.com/your-definitive-mobile-app-checklist/index.md Content type: article Published: 2025-12-15T10:39:06Z Updated: 2025-12-19T09:56:27Z Summary: Use this mobile app launch checklist to review architecture, integrations, QA, and go-live readiness before an SFCC-backed app ships. Categories: Salesforce Commerce Cloud Tags: go-live, headless, sfcc ## Key Takeaways - Provides a headless mobile-app go-live checklist tailored to SCAPI and SLAS rather than a traditional SFRA launch model - Covers the main readiness areas across backend configuration, client-side caching and tracking, API performance, and final production operations - Highlights the app-store submission layer as an additional launch gate that commerce teams must plan for alongside platform readiness For years, the Salesforce B2C Commerce go-live process has been a well-trodden path. The Site Readiness Assessment (SRA) served as our trusted map, guiding us through the checkpoints of specification reviews, launch gates, and operational readiness. We knew the terrain of Storefront Reference Architecture (SFRA), its monolithic structure, and its performance quirks. We were comfortable. That comfort is now a liability. Launching a headless mobile application on the Salesforce Commerce API (SCAPI) and [Shopper Login and API Access Service](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas.html) (SLAS) is a fundamentally different expedition. The old SRA is still a valuable guide for platform best practices, but it’s a dangerously incomplete map for this new territory. The game has changed. The focus shifts from a tightly-coupled application to a decoupled architecture where the API is the product, the mobile client is an intelligent actor, and performance is a shared responsibility. This article provides the new checklist—a definitive guide that respects the wisdom of the SRA while charting the critical new domains of API-first development, client-side intelligence, and mobile-specific delivery. ## The Hostname Question—Demystifying Your Production Endpoints Let’s tackle the first and most common point of confusion for teams moving from SFRA to headless: “Do my SCAPI calls need a separate hostname?” The question stems from an SFRA world where everything—the storefront, Business Manager, and even OCAPI—seems to live under the same domain umbrella. The definitive answer is: **Yes, SCAPI and SLAS operate on a completely separate hostname infrastructure from your SFRA site’s vanity domain.** Your mobile app will not make API calls to `www.your-brand.com`. Instead, all SCAPI and SLAS interactions are routed through the dedicated, globally scaled Salesforce Commerce API gateway. The endpoint URL follows a standard format: `https://{{short-code}}.api.commercecloud.salesforce.com/...`. This is your single, secure, and performant entry point for all API traffic. This move is intentional and reinforced by Salesforce’s [deprecation](/the-importance-of-origin-shielding/) of older, hyphenated hostnames (e.g., `production-realm-customer.demandware.net`) for API access, pushing all traffic to this unified gateway. > **CORS** > > Don’t forget to [secure your API layer](https://developer.salesforce.com/docs/commerce/commerce-api/guide/cors.html)! This separation of hostnames is not an arbitrary technical detail; it reflects the fundamental architectural decoupling that is the core promise of headless commerce. - Your **vanity domain** (e.g., `www.your-brand.com`) is for the **presentation layer**. It’s what customers see. The DNS manages routing and hostname alias configuration within B2C Commerce, which directs traffic through the eCDN. - The **API gateway domain** (`{{short-code}}.api.commercecloud.salesforce.com`) is for the **data and service layer**. It is a purpose-built infrastructure designed for high-scale, secure API transactions. This separation allows for independent scaling, security policies, and evolution. You can completely redesign your mobile app (the “head”) without ever touching the API endpoint, and vice versa. SLAS, as the gatekeeper for Shopper APIs, runs on this same infrastructure, which is why its admin UI and authentication endpoints share the same base URL structure. The flow is simple: your mobile app calls SLAS to get a JSON Web Token (JWT), and then it includes that JWT in the `Authorization` header for all subsequent SCAPI calls. So, where does your SFRA site’s configuration fit in? While the vanity domain isn’t the API endpoint, the underlying site configuration is still critical. Every SCAPI request includes a `siteId` query parameter. This `siteId` tells B2C Commerce which site’s context to use for the request—which catalog, which price books, which promotions to apply. That site is, in turn, configured in Business Manager and linked to your hostnames via the alias file. The hostname alias configuration remains essential for defining the _context_ of your API calls, even though it’s not the _endpoint_ you call directly. ## The Headless Go-Live Checklist: From Backend to App Store ![Isometric illustration of a four-stage technical process pipeline. Part I: 'Backend Foundation' shows a server rack, a database, and a padlock. Part II: 'Headless Client' displays mobile phones with screens showing 'CACHING,' 'ANALYTICS,' and 'WIRELESS' icons. Part III: 'Performance Testing' features a speedometer and a target with arrows. Part IV: 'Go-Live & App Store' has a rocket launching from a platform towards the Apple App Store and Google Play store logos.](/your-definitive-mobile-app-checklist/headless-checklist-58fce03496_hu_a4c355a5116efaab.webp) Four-part headless launch checklist With the hostname question settled, we can proceed to the full checklist. It is divided into four parts, moving from the foundational backend configuration to the new frontiers of client-side logic and app store deployment. ### Part I: Backend & Architectural Readiness (The Foundation) This section adapts the SRA’s architectural principles to a headless context. The focus is on the solidity of the API contract and the backend configuration that will serve the mobile app. #### API & Data Model Finalization (Your Contract with the Client) - **Data Flow & Mapping:** All data flow diagrams must be updated to reflect a decoupled architecture where the mobile app (or Headless site) is a primary target system. This includes verifying the flows for customer, product, inventory, and order data. - **Custom Attributes & Objects:** Every custom attribute and object required by the app must be finalised and documented. An attribute that is acceptable in a rarely-used SFRA template might become a performance bottleneck when requested in every `/products` API call. Its performance impact must be understood. - **Media Strategy:** The strategy for serving images and video must be confirmed. Whether the app calls the B2C Commerce Dynamic Imaging Service (DIS) or an external provider like Amplience or Scene7 directly impacts implementation and performance. - **Localisation & Multi-Site:** The underlying site architecture (single vs. multi-site, locales, currencies) must be finalised. The mobile app will depend on this configuration to request the correct context for each user. - **API Quotas:** This is a **LAUNCH BLOCKER**. The development team must formally acknowledge and document all relevant API quotas. The mobile app’s design _must_ operate within these limits to prevent service disruptions. #### Authentication & Security Configuration (Locking the Gates) - **SLAS Client Configuration:** A final SLAS client for the production environment must be created and configured. If a customer facing system (in this case an app) is not able to securely store (and hide) a secret token, this must be a **Public Client**. The exact `redirectUri` used for the OAuth flow within the app must be defined and allow-listed in the client configuration. If using third-party social logins (e.g., Google, Facebook), the Identity Providers (IDPs) must be fully configured in SLAS for the production tenant. In most cases a native application [is able to store](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-private-client.html) this information securely, but an audit is mandatory. - **OAuth Scopes (Least Privilege Principle):** Granting overly permissive scopes is a common and dangerous oversight. A final audit of all scopes assigned to the production SLAS client is critical. This review should map every API endpoint the app uses to a specific, required scope and ensure no unnecessary permissions are granted. For example, if the app only reads basket data, it should not have the sfcc.shopper-baskets-orders.`rw` scope. This adherence to the principle of least privilege reduces the “blast radius” if a token is ever compromised. - **Custom API Security:** Every custom API endpoint must be adequately secured with a `ShopperToken` security scheme and a unique custom scope (prefixed with `c_`) in its OpenAPI Specification (OAS 3.0) definition. Unsecured custom endpoints are a critical vulnerability and will not be registered by the platform. - **CORS Policy:** While less critical for native mobile apps than for web apps, if any web-based technologies or views are used, the Cross-Origin Resource Sharing (CORS) headers configured on the platform should be as restrictive as possible to prevent unauthorised cross-domain requests. > **SLAS Private Key** > > If a secret was ever embedded in the mobile app, immediately rotate the secret in the SLAS Admin UI and release a hotfix to the app removing it. #### Infrastructure & eCDN (The Pipes) - **SSL Certificates:** Valid SSL certificates for all relevant domains must be in place and uploaded to the platform via Business Manager or the CDN-API. This is a launch blocker for secure communication. - **Firewall Rules:** All IP addresses for third-party integrations (payment, tax, OMS, etc.) must be allow-listed in the Commerce Cloud firewall. Forgetting this is a common go-live “gotcha” that can bring down critical services at the worst possible time. - **eCDN WAFv2:** Be aware of the Web Application Firewall (WAF) rules. While Salesforce manages the core OWASP ruleset, it is important to ensure that no legitimate traffic patterns from the mobile app are being inadvertently blocked. #### Integrations & Jobs (The Engine Room) - **Third-Party Services:** All third-party integrations must be pointing to their respective **production** endpoints and must have been tested end-to-end. - **Fault Tolerance:** Critical integrations must use the B2C Commerce Service Framework with aggressive timeouts and circuit-breaker patterns. The mobile app or headless site must be designed to handle a failure of a third-party service gracefully, without crashing or locking up. - **Backend Jobs:** The entire job schedule on the PIG (Primary Instance Group) instances must be reviewed. Data import jobs (inventory, pricing, …) and data replication schedules should be staggered, run during off-peak hours, and use delta feeds wherever possible to minimise performance impact on the live application. ### Part II: The Headless Client (The New Frontier) This entire section is new territory compared to the SFRA SRA. The mobile app, for example, is not just a “head”—it’s an intelligent client with its own responsibilities for performance, data management, and user engagement. #### Client-Side Caching Strategy (Your First Line of Defense) Effective client-side [caching](/caching-rest-apis-in-sfcc/) is the single most important factor for a snappy, responsive mobile app experience and for staying within API quotas. Network calls from a mobile device are inherently latent and unreliable. The app must not go to the network for data it already has. A comprehensive go-live requires verification of a robust, multi-layered caching strategy. - **HTTP Caching:** Verify the app correctly respects `Cache-Control` headers from SCAPI responses. This is the simplest level of caching, often handled by the mobile OS’s networking stack. - **In-Memory Cache:** For frequently accessed, short-lived data (e.g., data for the currently visible screen), confirm that an in-memory cache is used. This data is volatile and lost when the app closes. - **“Disk-Based” Cache (Persistence):** For data that must persist between app sessions (e.g., product catalog data, category structures, user preferences). - **Cache Invalidation:** Confirm that a clear strategy for cache invalidation is in place. Is it based on a Time-to-Live (TTL)? Is it cleared on specific user actions like logout? Stale data is as bad as no data. #### Analytics & Tracking Implementation - **Event Tracking:** A comprehensive analytics plan must be defined and implemented. Key user actions (e.g., product view, add to cart, checkout step, search performed) must be tracked. - **Tooling:** The chosen analytics SDK (e.g., Google Analytics for Firebase, Adobe Analytics) must be correctly integrated and configured to point to the production environment. - **Data Privacy & Consent:** Verify that no tracking events are fired until the user has given appropriate consent, in compliance with regulations like GDPR and CCPA. #### Push Notification Setup - **Service Integration:** The mobile app must be fully integrated with the chosen push notification provider, such as Salesforce Marketing Cloud MobilePush or Firebase Cloud Messaging. - **SDK & Configuration:** The provider’s SDK must be correctly configured within the app to handle device registration and the receipt of notifications. - **Opt-in/Opt-out:** The app must provide a clear and accessible UI for users to manage their push notification preferences. - **Audience & Segmentation:** In the backend system (e.g., Marketing Cloud), ensure that the necessary lists, data extensions, or audiences are created and populated to allow for targeted push campaigns immediately at launch. - **Test Plan:** A plan to send test notifications to specific test devices must be in place to verify the entire pipeline is working before go-live. ### Part III: Performance & Load Testing (The New Discipline) ![A cartoon infographic titled 'PART II: THE HEADLESS CLIENT (THE NEW FRONTIER)'. It has three panels. The left panel, 'CLIENT-SIDE CACHING', shows a smartphone with RAM ('IN-MEMORY') and a hard drive ('DISK-BASED') protected by a 'CACHE' shield from 'NETWORK LATENCY' arrows. A timer ('TTL') is connected, and a bubble says 'Snappy! No Network Needed'. The middle panel, 'ANALYTICS & TRACKING', shows a user icon with a magnifying glass, with arrows pointing to 'PRODUCT VIEW', 'ADD TO CART', and 'CHECKOUT' icons, leading to an 'ANALYTICS SDK' window with a 'CONSENT' checkbox. The right panel, 'PUSH NOTIFICATION SETUP', shows a smartphone with a 'NEW DEAL! OPT-IN?' notification and a 'YES/NO' toggle. A 'PUSH PROVIDER' cloud sends a signal to an 'AUDIENCE SEGMENTATION' target on a server rack. The background is a circuit board pattern.](/your-definitive-mobile-app-checklist/the-headless-client-d56f678d67_hu_8a3c77ff090fc3c4.webp) Headless client readiness map This section details another significant process change from an SFRA go-live. The focus shifts from testing the holistic performance of a web page to the granular, methodical testing of the API endpoints that power the app. #### The Paradigm Shift: From Pages to Endpoints Traditional SFRA performance testing relies on tools like WebPageTest or GTmetrix to measure the rendering time of a full page. In a headless world, this is largely irrelevant. The new discipline focuses on API performance testing tools (e.g., JMeter, Gatling, k6) that simulate concurrent users making direct API calls. The goal is no longer to measure “page load time” but to measure API-specific metrics: **response time (latency), error rate, and throughput (requests per second)** under various load conditions. #### API Load & Stress Testing - **Test Scenarios:** Define realistic test scenarios that mimic user behaviour in the app. This involves simulating thousands of users simultaneously performing searches, viewing products, adding to cart, and checking out. - **Identify Critical Endpoints:** Prioritise testing on the most critical and frequently called SCAPI endpoints, including `product-search`, `products/{id}`, `baskets`, `orders`, and any high-traffic custom APIs. - **Test Types:** - **Load Test:** Can the backend sustain the expected peak traffic (e.g., 500 concurrent API users for 2 hours) without performance degradation?. - **Stress Test:** At what point does the system break? Methodically ramp up the number of virtual users until response times become unacceptable or the error rate spikes. This identifies the system’s absolute ceiling. - **Spike Test:** Can the system handle a sudden, massive influx of traffic, such as the one generated by a major push notification campaign?. - **Environment:** All load tests must be conducted against a production-sized environment (a “loaner realm” or the production instance). The IP addresses of the load-generating machines must be communicated to Salesforce Support well in advance to ensure they are not blocked. #### The Shared Responsibility Model A headless app’s performance is a composite of the client, the network, and the backend API response. That backend response is itself a composite of out-of-the-box SCAPI code, your custom hook code, and the performance of your underlying data model. Teams cannot assume Salesforce is solely responsible for performance. A clear understanding of this [shared responsibility](/a-survival-guide-to-sfcc-platform-limits/) is crucial for de-risking the project. ### Part IV: The Final Countdown (Go-Live & Beyond) ![A cartoon illustration shows a team of four people in a control room celebrating as one presses a large red 'GO-LIVE' button. A digital timer reads 'T-MINUS 00:00:00' and confetti falls. On a large screen, a rocket with Apple App Store and Google Play logos launches. A checklist on the wall shows green ticks for 'DATA PURGE,' 'LEGACY IMPORT,' and 'CONFIG LOCK-DOWN.' A robot sweeps 'TEST DATA' into a bin. To the right, a gate labeled 'APP STORE SUBMISSION (2025 GATES)' is open, with 'Xcode 16' visible. A character in the foreground thinks, 'SDK Signatures & Privacy Manifests: CHECKED!'.](/your-definitive-mobile-app-checklist/app-launch-ac5253524a_hu_9a2f7ada0f0a1cb.webp) Go-live and app store readiness This section covers the final operational steps, including the crucial new gate: App Store submission. #### Data & Configuration Readiness - **Data Purge:** All test data, including customers and orders, must be purged from the production instance. - **Legacy Data Import:** If migrating data from a legacy system, the final import must be completed and verified. - **Production Configuration Lock-Down:** Final API keys, client IDs, and secrets must be configured in the app. All third-party integration endpoints must be switched to their production URLs. Business Manager settings (caching, feature switches, order preferences) must be set for production, and logging levels should be set to appropriate production levels (not verbose debug). Finally, alerting must be enabled and directed to the production support team. #### The Go/No-Go Review A final review of this entire checklist must be conducted with all stakeholders. This includes a review of any outstanding “No” items from the original SRA that are still relevant. This meeting concludes with a formal sign-off from technical architects, business owners, and operational teams. #### App Store Submission (The Final Gate) For an SFRA site, go-live is often a DNS change. For a mobile app, it is a submission and review process that can take days and is subject to the policies of Apple and Google. This external dependency must be factored into the timeline. The “submit and wait” era is over. In 2025, a successful submission requires proactive compliance with Apple’s supply chain and privacy mandates. Use this protocol to ensure your binary passes static analysis and manual review. - **Supply Chain Security (SDK Signatures):** As of February 2025, Apple strictly enforces manifest requirements for “Commonly Used Third-Party SDKs” (e.g., Firebase, Facebook, various ad networks). You must audit your `Podfile` or Swift Package Manager dependencies to ensure every SDK is updated to a version that includes a digital signature and its own Privacy Manifest. - **Packaging:** The final, production-signed app binary must be built and tested. Ensure your CI/CD pipeline is using **Xcode 16** (targeting the iOS 18 SDK). This became the mandatory baseline for all App Store submissions starting April 2025. - **Store Listings:** All required metadata must be prepared: app name, description, production-quality screenshots for all required device sizes, keywords, and a publicly accessible Privacy Policy URL. - **Reviewer Information:** Prepare test account credentials and any special instructions needed for the app store reviewer to fully test the app’s functionality (e.g., how to complete a purchase). - **Submission:** The app must be uploaded to App Store Connect and the Google Play Console and formally submitted for review. - **Contingency Planning:** A plan must be in place for a potential rejection. Have common rejection reasons (e.g., crashes, incomplete functionality, poor UI, issues with in-app purchases) been proactively mitigated?. Apps that are primarily websites wrapped in a native shell or are nearly identical to existing apps are aggressively rejected under [Guideline 4.2 and 4.3](https://developer.apple.com/app-store/review/guidelines/#design). > **A PWA Kit Wrapper App** > > Whilst you can easily “wrap” a PWA Kit site in a native app, there is the risk of rejection if the application does not provide any additional “value” to the user. ## Welcome to the Headless Era The transition from a monolithic SFRA architecture to a headless mobile application is more than a technical upgrade; it’s a shift in mindset. The go-live process is no longer a single, coordinated event but a dual-track operation ensuring both backend readiness and client-side excellence. Success in this new era hinges on embracing three core tenets: 1. **The API is the Product:** The API contract, its performance, and its security are paramount. It must be designed, tested, and documented with the same rigour as a physical product. 2. **Performance is a Shared Responsibility:** The speed of your application is a direct result of your custom code, your data model, and your client-side implementation, not just the underlying platform. You own a significant piece of the performance puzzle. 3. **The Client is Intelligent:** The mobile app is not a dumb renderer of HTML. It is a critical part of the architecture, with its own responsibilities for caching, state management, and providing a resilient user experience. By augmenting the proven wisdom of the SRA with this new, headless-specific checklist, teams can navigate the go-live gauntlet with confidence, prepared for the unique challenges and immense opportunities of the headless commerce landscape. --- ## Survival Guide to SFCC Platform Limits Canonical URL: https://rhino-inquisitor.com/a-survival-guide-to-sfcc-platform-limits/ Markdown URL: https://rhino-inquisitor.com/a-survival-guide-to-sfcc-platform-limits/index.md Content type: article Published: 2025-11-24T12:41:24Z Updated: 2025-12-01T08:10:09Z Summary: Guide to the SFCC quotas that break storefronts first, with failure patterns and design tactics to stay inside platform limits. Categories: Salesforce Commerce Cloud, Technical Tags: quota, sfcc, technical ## Key Takeaways - Explains the most important SFCC quotas and why they exist as platform guardrails - Shows common failure patterns across custom objects, timeouts, API calls, and sessions - Provides architectural strategies to stay within limits in monolith and headless builds It is a scenario that haunts every e-commerce developer: the 3 AM pager alert. The production site is down, shoppers are seeing the dreaded “general error page,” and sales have come to a standstill. After a frantic dive into the logs, the culprit is revealed: a cryptic message about an “enforced quota violation”. This is the moment every developer working on Salesforce B2C Commerce Cloud learns that, despite its power, the platform is a governed territory with strict rules. These laws are known as quotas. They are not arbitrary punishments designed to frustrate developers. Instead, they are the platform’s sophisticated immune system, a set of essential guardrails designed to ensure stability, performance, and fairness in a complex multi-tenant environment. Think of them as the zoning laws and building codes of a bustling digital metropolis. They prevent one tenant’s poorly designed skyscraper from blocking the sun for everyone else, ensuring the shared infrastructure—memory, CPU, database resources—remains healthy and responsive for all. For developers migrating from the Salesforce Core platform, it is tempting to equate these quotas with Apex Governor Limits. While the philosophy of resource protection is similar, the specifics are worlds apart. B2C Commerce has its own unique set of constraints—Object Quotas, API Quotas, and Script Timeouts—that demand a different mindset and a distinct set of architectural patterns. Understanding these is not optional; it is fundamental to survival. This guide serves as a definitive map through that governed territory. It moves beyond the official documentation to provide the “in-the-trenches” wisdom needed to build robust, scalable, and, most importantly, quota-proof applications on B2C Commerce. It serves as a survival guide for navigating the platform’s unspoken rules and leveraging constraints into a competitive advantage. ## The Monolith’s Mandates: Top 10 Quotas for Every SFCC Developer These are the foundational limits that every Salesforce B2C Commerce developer must internalize, whether they are maintaining a legacy SiteGenesis implementation, building on the modern Storefront Reference Architecture (SFRA), or managing the backend services for a headless storefront. These are the immutable laws of the land, and ignorance is no defense when an enforced quota brings a production instance to its knees. The following table provides a quick-reference cheat sheet for the most critical quotas to keep in mind during architecture, development, and code review. ## The Digital Hoarder’s Downfall: Custom Objects (400,000 Limit) **The Limit:** An instance can hold a maximum of 400,000 replicable (stageable) custom objects and a separate 400,000 non-replicable (non-stageable) custom objects. **The Danger Zone:** This limit, while seemingly vast, is often threatened by insidious data accumulation. Common culprits include using custom objects to store transactional data, such as detailed integration logs or granular user interaction events, which rightfully belong in an external system of record. Another frequent anti-pattern is the complete lack of data retention policies, allowing temporary data—such as tokens for password resets or abandoned cart information—to accumulate indefinitely until the limit is reached. **The Fallout:** Once this enforced quota is hit, the consequences are severe. Any call to `dw.object.CustomObjectMgr.create()` will fail with an uncatchable exception. This means any feature relying on the creation of new custom objects, from saving a user’s address preference to logging a critical integration failure, will cease to function. It is a systemic failure that can cripple significant portions of a site’s custom functionality. **The Pro Move:** The key to avoiding this downfall is architectural discipline and rigorous data hygiene. - **Be Ruthless with Data:** Before storing anything in a custom object, developers and architects must ask the critical question: “Is B2C Commerce the correct system of record for this data?”. If the data originates from or is primarily used by another platform (like a CRM or Marketing Cloud), it should reside there. - **Mandate Cleanup:** No custom object intended for temporary storage should be created without a corresponding, regularly scheduled purge job. A clear data retention period must be defined and enforced as part of the development lifecycle for that feature. - **Extend, Don’t Invent:** Before creating a new custom object type, developers should exhaust all possibilities of extending existing system objects with custom attributes. System objects are generally more performant and do not count against this specific quota. Beyond the hard limit, there is a more subtle performance drag to consider. The documentation and best practices repeatedly warn that custom objects are not optimised for high-performance database access. This means that even when an instance is well below the 400,000 object ceiling, heavy reliance on custom objects for frequent read/write operations (e.g., a custom inventory system or a real-time logging mechanism) creates significant database churn. This churn leads to a gradual degradation of site performance—slower page loads, longer job execution times—that does not trigger a hard quota violation but insidiously damages the user experience and erodes site stability. The limit is a hard stop, but the performance penalty begins long before the wall is hit. ## The Blueprint Boundary: Object Type Definitions (300 Limit) **The Limit:** An instance is [capped](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/quota/html/Object_Quotas.html) at a maximum of 300 total business object definitions. This count includes all the platform’s built-in system object types, as well as any custom object types created by developers. **The Danger Zone:** This limit is rarely a concern for typical, single-brand e-commerce sites. However, it can become a very real constraint for large, complex, multi-brand organisations operating on a single B2C Commerce instance. In such environments, numerous bespoke features, each potentially demanding its own custom data model, can quickly consume the available slots for new object types. **The Fallout:** The consequence is absolute: the inability to create new custom object types. This effectively halts the development of any new feature that requires a distinct data structure, putting the brakes on innovation and business agility. **The Pro Move:** This strategy is rooted in effective data modelling and long-term architectural planning. Developers should practice data consolidation, designing a single, well-structured custom object with multiple attributes to represent a feature’s data, rather than creating a constellation of small, single-purpose object types. It is also good practice to regularly audit development and staging environments to remove unused custom object types that may have been created for proofs-of-concept or abandoned features, freeing up slots in the blueprint. This limit imposes a hidden constraint on architectural freedom. While 300 types may seem generous, the platform’s system objects already occupy a significant portion of that budget. This creates a strategic tension. A developer might be tempted to create a new custom object type to keep a feature’s data cleanly isolated. However, in doing so, they consume a precious, non-renewable, instance-wide resource. This pressure forces architects to think about the long-term data model of the entire instance. A short-sighted decision to create a new object type for a minor feature today could prevent the development of a more critical, large-scale feature tomorrow. It encourages a pattern of extending existing objects, which, if not managed carefully, can lead to bloated objects with hundreds of attributes, creating their own set of maintenance challenges. ## The 5-Minute Fuse: Storefront Script Execution Timeout PWA Kit / Headless If you’re working with a Headless or Composable setup, refer to the official documentation, as different rules may apply to your situation! **The Limit:** Any script running within a storefront request context, such as a controller or a script module it calls, has a [maximum execution time](https://developer.salesforce.com/docs/commerce/commerce-api/guide/timeout-troubleshoot.html) of 5 minutes (300,000 milliseconds). **The Danger Zone:** This limit is typically breached by one of three culprits: highly complex, unoptimized calculations performed in real-time; synchronous calls to slow or unresponsive third-party services; or inefficient loops that iterate over massive datasets without proper optimisation. **The Fallout:** The platform shows no mercy. A non-catchable `ScriptingTimeoutError` is thrown, the script is immediately aborted, and the user is presented with an error page. There is no opportunity for graceful recovery; the transaction is dead. **The Pro Move:** Adhering to this limit requires a shift in thinking from synchronous to asynchronous processing. - **Offload to Jobs:** Any process that is not absolutely essential for the immediate, initial rendering of the page should be moved to an asynchronous job. This is the canonical pattern for tasks like order export, complex report generation, or large data synchronisations. - **Write Efficient Code:** This is a table-stakes requirement for any performance-conscious developer. Optimise loops by using efficient APIs like `seekable` iterators instead of loading entire large collections into memory. Cache the results of expensive or repeated operations within a single request. - **Use the Service Framework:** For all external API calls, the Service Framework is mandatory. It allows for the configuration of aggressive timeouts and circuit breakers, enabling the system to “fail fast” rather than waiting for a slow third-party service to consume the entire 5-minute budget. A critical nuance is the interplay of different timeout contexts. The [documentation](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-working-with-scripts.html) reveals a hierarchy of timeouts: 5 minutes for controllers, but a much stricter 30 seconds for contexts like OCAPI hooks or Page Designer scripts. The governing rule is that the timeout that ends earliest wins. This creates a crucial dependency chain. A controller might call a script module, which is then used within a hook. Even though the controller has a generous 5-minute budget, the hook’s 30-second budget becomes the real, effective constraint for that piece of the execution. Developers cannot think about the 5-minute limit in isolation; they must consider the entire potential call stack of a script and design for the most restrictive timeout it might encounter. ## The Party Line: API HTTPClient Calls Per Page (16 Limit) ![Cartoon of frustrated developers crowded around a party-line telephone labeled '16 API Calls Per Page.'](/a-survival-guide-to-sfcc-platform-limits/the-api-party-line-53588b75f5_hu_33c0aed3ad07c5b.webp) The HTTPClient limit pushes teams toward aggregation, caching, and feed-based integrations. Remember old party lines? B2C Commerce’s HTTPClient is similar. You only get 16 external API calls per request. If too many services try to “talk” at once, your page will throw an error. Plan your integrations wisely! **The Limit:** A single storefront page request is permitted to make a maximum of 16 outbound calls using dw.net.HTTPClient.send(). The platform will log a warning starting at 10 calls. **The Danger Zone:** This quota is a direct threat to “chatty” integrations. Pages that need to assemble data from numerous disparate microservices or third-party APIs are at high risk. A common scenario is a product detail page that attempts to fetch real-time shipping quotes, tax calculations, inventory levels from multiple warehouses, and personalised content, all through separate API calls. **The Fallout:** An enforced quota violation will abruptly terminate the request, sending the user to an error page. The page they were trying to load will simply fail. **The Pro Move:** Avoiding this limit requires a deliberate integration strategy that favours consolidation and caching over chattiness. - **API Aggregation:** When the external services are within the team’s control, the best practice is to create an aggregation layer or a Backend-for-Frontend (BFF) service. This service can receive a single request from B2C Commerce, make multiple downstream calls itself, and return a consolidated data payload in one response. - **Aggressive Caching:** Responses from external systems that do not change on every request should be aggressively cached using B2C Commerce’s custom cache framework. This avoids making a network call on every single page load for the same data. - **Switch to Data Feeds:** For data that does not require real-time updates (e.g., product specifications, warehouse inventory), the entire model should be transitioned from real-time API calls to scheduled data feed imports. Importing inventory levels every 15 minutes via a job is far more scalable and performant than hitting an inventory API on every product page view. This limit of 16 calls is more than just a technical constraint; it is a powerful driving force for better architecture. It actively discourages a naive, chatty integration pattern where the storefront directly communicates with a fleet of microservices. This quota, especially when combined with the 5-minute script timeout, compels architects to adopt more robust and performant patterns, such as the API Gateway. The limit is not just about preventing resource exhaustion on the B2C Commerce side; it is about enforcing a more resilient and scalable integration architecture for the entire solution. ## The Overstuffed Cart: Product Line Items Per Basket (400 Limit) **The Limit:** The total number of product line items that can be contained within a single basket is 400. This includes both independent products and any dependent items, such as those in a product bundle. A warning is logged when a basket reaches 200 items. **The Danger Zone:** While most B2C shoppers will never approach this limit, it is a significant and common hurdle in B2B commerce scenarios. A business customer placing a replenishment order might need to purchase hundreds of unique SKUs in a single transaction. It can also appear in B2C contexts, such as with features like “quick order” forms or when a user attempts to add a very large wishlist to their cart at once. **The Fallout:** The consequence is a direct blocker to conversion. The platform will prevent the user from adding any more items to their cart once the limit is reached. The API call to add the 401st item will fail, and without graceful error handling, the user will be left confused and unable to complete their purchase. **The Pro Move:** Handling this limit requires different strategies for B2B and B2C. - **B2B Solutions:** For B2B use cases, a custom solution is often required. One approach is to build logic that automatically splits a large order into multiple, smaller baskets behind the scenes, presenting it to the user as a single order confirmation. Another is to guide the user through the UI to create several smaller orders. - **B2C Graceful Handling:** For B2C, the focus is on clear user feedback. When the cart approaches the limit, the UI should display a non-intrusive message. When the limit is hit, a clear, helpful error message should explain the situation: “Your shopping cart is full. To add more items, please proceed to checkout with your current selection or save items to a wishlist for later.” ## The Promotion Paradox: Enabled Promotions (10,000 Limit) **The Limit:** An instance can have a maximum of 10,000 promotions in an “enabled” state.6 It is critical to note that there is an even stricter, more performance-relevant limit of 1,000 _active_ promotions (enabled, assigned to a campaign, and currently within their run dates) at any given time. **The Danger Zone:** This limit is typically threatened by large retailers with complex, overlapping, and long-running promotional strategies, compounded by a failure to perform basic data hygiene. Merchandising teams can create new promotions for every minor event without needing to revisit and clean up old or expired ones. **The Fallout:** The primary risk here is not a hard error but a slow, creeping death of performance. The B2C Commerce promotion engine must evaluate all potentially applicable promotions during basket calculation. As the number of enabled—and especially active—promotions grows, this calculation becomes exponentially more complex. The result is a slowdown in the basket and checkout pipelines, which impacts the checkout experience for _all_ users, even those not using a promotion. Hitting the hard limit is rare, but the performance degradation begins far sooner. **The Pro Move:** The solution is not technical but procedural: a strict “Promotion Lifecycle Management” process must be implemented. Business users and merchandisers must be trained and required to archive promotions as soon as their effective date range has passed. From a technical monitoring perspective, the “Number of Active Promotions” quota (1,000) should be treated as the more critical performance indicator. Any sustained approach toward this number should trigger an immediate review and cleanup of the active promotion landscape. ## The Unfurled Scroll: ISML Template Size (10MB Limit) ![Cartoon of a worried developer beside a giant unfurling scroll representing a bloated ISML template with a 10 MB warning sign.](/a-survival-guide-to-sfcc-platform-limits/isml-10-mb-limit-00017e3dfb_hu_6e9e19393b2119ba.webp) Crossing the 10 MB ISML limit breaks the page and forces better pagination and template discipline. Like an ancient, endless scroll, an ISML template can grow beyond its bounds. Keep an eye on that 10MB file size limit, or your beautifully crafted template might just refuse to render, leaving you with nothing but a blank page. **The Limit:** The final, rendered HTML output generated by an ISML template cannot exceed 10MB in size. **The Danger Zone:** This limit is most commonly encountered on pages that render huge loops of data, such as a “view all” category page that attempts to display thousands of product tiles without any form of pagination. Another culprit can be content slots that have been bloated with excessive, unoptimized, or copy-pasted HTML from a WYSIWYG editor. **The Fallout:** The platform throws a Page size limit of 10 MB exceeded exception, and the entire page processing request is cancelled. The user sees an error page. **The Pro Move:** This limit enforces fundamental web performance best practices. - **Pagination is Not Optional:** All product listing pages, search result pages, and any other page that displays a potentially large list of items must implement robust and user-friendly pagination. The “Infinite scroll” feature can be utilised, but it must be implemented intelligently with asynchronous calls to fetch subsequent pages of data. - **Lazy Loading:** For content that is “below the fold” (not immediately visible to the user), use lazy loading techniques to defer the loading of that content until the user scrolls down. **Keep Logic Out of ISML:** ISML templates should be used solely for presentation logic. All complex data preparation, filtering, and business logic should be handled in controller or script module files before being passed to the template. This keeps templates clean, small, and focused on rendering. ## The Tiny Backpack: Session Size (10KB Limit) **The Limit:** The total serialized size of all data stored in the dw.system.Session object is limited to 10KB. Furthermore, individual strings stored within the session are capped at 2,000 characters. **The Danger Zone:** The most common anti-pattern that leads to violating this quota is storing large, complex objects or entire collections of data in the session. A classic mistake is to perform a product search, store the entire result set of Product objects in the session, and then attempt to read from it on the next page for rendering. **The Fallout:** Exceeding the limit can lead to unpredictable behaviour, including data truncation or runtime exceptions. **The Pro Move:** The session should be treated as a tiny, temporary backpack, not a storage warehouse. - **Store Identifiers, Not Objects:** The correct pattern is to store only small, primitive identifiers in the session, such as productID, customerNo, or orderID. The full objects should be re-fetched from the database or, preferably, from a cache when they are needed on a subsequent page. - **Use session.privacy:** For data that is specific to a user’s logged-in session and should be cleared upon logout (like temporary preferences), use the session.privacy custom attributes. The platform automatically handles the cleanup of this data. ## The Ten Commandments of Creation: API Custom Object Creation Per Page (10 Limit) **The Limit:** A maximum of 10 custom objects can be created within a single storefront page request through the dw.object.CustomObjectMgr.create() API call. **The Danger Zone:** This quota is often hit by custom forms that create multiple, separate custom object records upon submission. For example, a complex user survey with ten questions where each answer is saved as an individual custom object record would hit the limit. Another common cause is a custom logging implementation that attempts to create a new custom object for every minor event that occurs during a single page view. **The Fallout:** This is an enforced quota. The 11th call to create() will fail, the request will be stopped, and the user will see an error. If they were submitting a form, all the data they entered would be lost, leading to a highly frustrating experience. **The Pro Move:** The key is to consolidate data. Instead of creating many small objects, developers should batch the data into a single, larger, and more structured custom object. For the survey example, all ten answers should be collected and stored as a single JSON string within a single attribute of a custom object. For logging, a third-party logging service should be used, or logs should be buffered and sent asynchronously to avoid impacting the user-facing request. ## The Read-Only Rule: File I/O in Storefront (0 Limit) **The Limit:** Nearly all file writing and manipulation methods in the dw.io.File and dw.io.FileWriter classes have a strict storefront limit of zero. This includes File.createNewFile(), FileWriter(), File.zip(), and others. **The Danger Zone:** This is a trap for developers new to the platform who might attempt to dynamically generate a file—such as a custom PDF invoice or a CSV export of user data—and serve it for download directly from a storefront controller request. **The Fallout:** This is a non-negotiable architectural constraint. The code will work perfectly in a sandbox job context but will fail with a hard, enforced quota violation in a production storefront request. It is a guaranteed failure. **The Pro Move:** Any form of dynamic file generation must happen in an asynchronous job context. The canonical pattern is as follows: 1. A user on a storefront page clicks a button to request a file (e.g., “Download My Order History”). 2. The storefront controller does not generate the file. Instead, it creates a “token” custom object with a status of “pending” and triggers a job, passing the ID of this token object as a parameter. 3. The user’s page receives a confirmation and begins to poll a separate, lightweight controller every few seconds, checking the status of the token object. The job executes in the background. It performs the heavy lifting of querying the data and generating the file, which it then saves to a temporary location in the WebDAV impex or temp directory. Once complete, the job updates the token custom object’s status to “complete” and adds the path to the generated file. 4. The polling mechanism on the user’s page sees the “complete” status, retrieves the file path, and presents the user with a direct download link to the file in WebDAV. 5. Clean up your custom objects! Remember 😇 ## The Headless Frontier: A PWA Kit & SCAPI Hit List Transitioning to a headless architecture with the PWA Kit and the Salesforce Commerce API (SCAPI) represents a fundamental paradigm shift. The performance battleground moves away from the server-side rendering of ISML templates and into the realm of API response times, network latency, and the efficiency of the client-side JavaScript application. In this world, the browser is no longer a thin client rendering HTML; it is a rich application responsible for its own state management, routing, and data fetching. The quotas and limits that matter most are less about single, monolithic server requests and more about the rate, size, and efficiency of the constant communication between the client and a constellation of API endpoints. ![Cartoon astronaut developer in digital space interacting with a headless UI, surrounded by API icons.](/a-survival-guide-to-sfcc-platform-limits/the-headless-frontier-ae21ed3f28_hu_dd9dc721b8baec43.webp) In headless builds, performance shifts from ISML rendering to API, network, and client-state costs. Welcome to the headless frontier. Here, developers are like astronauts, decoupling the front-end “head” to explore new user experiences, all powered by a universe of back-end APIs and services. ## The Bouncer at the Door: SCAPI & OCI Rate Limits (HTTP 429) **The Limit:** Unlike the hard-and-fast quotas of the monolith, SCAPI operates on a system of rate limiting and load shedding. There is not one single number to watch. Instead, when the platform determines that a client is making too many requests in a given timeframe, it will respond with an `HTTP 429 Too Many Requests` status code. Specific, high-volume API families, like Omnichannel Inventory (OCI), have very granular, published rate limits. For instance, the `get-availability` endpoint can handle a massive 10,000 requests every 10 seconds, while the `imports` endpoint is limited to just 2 requests per 10 seconds. **The Danger Zone:** The primary risk factor is a high-traffic site with poorly implemented or non-existent caching for API responses. A classic example is a product list page (PLP) in a PWA Kit application where, for every user, the browser makes individual, uncached calls to the Shopper Products and OCI Availability APIs for every single product tile visible on the page. During a sales event, this can quickly overwhelm the rate limits. **The Fallout:** The API client—the PWA Kit application running in the user’s browser—gets throttled. If the client-side code is not built to handle the 429 response gracefully, the UI will simply fail to load the required data. Users will see endless loading spinners, empty components, or jarring error messages, resulting in a broken and untrustworthy user experience. **The Pro Move:** Resilience is the name of the game. - **Honor `Retry-After`:** The 429 response is often accompanied by a `Retry-After` header, which specifies the number of seconds the client should wait before attempting to reconnect. Client-side code _must_ be built to respect this header. The best practice is to implement an exponential backoff strategy, where the delay between retries increases with each subsequent failure, thereby preventing a “thundering herd” of retries from exacerbating the problem. - **Embrace Client-Side Caching:** Modern libraries like React Query, which is a standard part of the PWA Kit, are essential. They provide sophisticated client-side caching, automatically preventing the application from making redundant API calls for data that it has recently fetched and that has not yet been invalidated. - **Leverage CDN Caching for APIs:** For API endpoints that return public, non-personalised data (e.g., product details for a guest user), the PWA Kit’s Managed Runtime proxy can be configured to cache the API JSON response at the CDN edge. This is achieved by changing the request path prefix from `/proxy/` to `/caching/`. This shift to rate-limiting signals a profound change in responsibility. In a traditional SFRA architecture, the server owns the execution and is responsible for handling errors that may occur. If a quota is hit, the server throws a fatal exception. In the headless SCAPI world, the platform simply puts its hand up and says “no more for now” with a 429 code. The responsibility for handling this rejection and maintaining a coherent, resilient user experience shifts almost entirely to the client-side application. Headless development is not just about a different frontend technology; it requires a more sophisticated level of client-side engineering, with a deep understanding of state management, asynchronous error handling, and fault-tolerance patterns. ## The Gatekeeper’s Toll: SLAS Rate Limits **The Limit:** The Shopper Login and API Access Service (SLAS), which governs all authentication and authorisation for Shopper APIs, has its own distinct, high-level rate limits: 24,000 requests per minute (RPM) for production tenants and 500 RPM for non-production tenants. **The Danger Zone:** The most common way to violate this limit is with a poorly configured client application that requests a new guest user token on every single API call, rather than caching and reusing the token it has already received. **The Fallout:** Authentication fails. Guest shoppers are unable to obtain the necessary JWT to perform actions such as adding items to a cart, and registered users are unable to log in or refresh their sessions. Essentially, all authenticated or basket-related e-commerce functionality grinds to a halt. **The Pro Move:** Token management is paramount. - **Token Caching is Mandatory:** A standard SLAS JWT is valid for 30 minutes. The client application must be designed to cache this token (e.g., in browser local storage) and include it in the `Authorization` header of all subsequent API calls. A new token should only be requested when the current one does not exist or is nearing its expiration time. - **Master the Refresh Token Flow:** For registered users, the client should use the provided refresh token to obtain a new access token in the background seamlessly, without requiring the user to re-authenticate. Developers should be aware of the latest security enhancements, such as mandatory refresh token rotation, which prohibits the reuse of a refresh token after it has been used once. ## The 30-Second Lifeline: PWA Kit Managed Runtime Proxy Timeout **The Limit:** Any request that is proxied through the PWA Kit’s Managed Runtime to an external, third-party API is subject to a hard, non-configurable timeout of 30 seconds. **The Danger Zone:** This becomes a problem when using the proxy to make a synchronous call to a system known for slow response times. This could be a legacy ERP system for a complex price lookup or a third-party service that provides real-time, computationally intensive freight shipping calculations. **The Fallout:** If the origin server does not respond within 30 seconds, the Managed Runtime will terminate the connection and return an `HTTP 504 Gateway Timeout` error to the client application. This happens regardless of whether the origin server is still processing the request. From the user’s perspective, the operation has failed. **The Pro Move:** This is a firm architectural boundary. If a service cannot guarantee a response in under 30 seconds, it cannot be called synchronously during a user-facing interaction that flows through the proxy. The solution is to adopt the same asynchronous, polling-based pattern used for file generation in the monolith: trigger a background process via a quick API call, and have the client poll a separate endpoint for the result. ## The Hook’s Handcuffs: OCAPI Hook Script Timeout Custom Timeouts Timeouts for STANDARD API endpoints can be [overridden](https://developer.salesforce.com/docs/commerce/commerce-api/references/timeouts?meta=Summary), but not for custom ones. **The Limit:** While SCAPI is the future, many implementations still use OCAPI, especially during a phased migration. Scripts executed within OCAPI hooks (e.g., `dw.ocapi.shop.basket.beforePOST`, `afterPOST`) are constrained by a very tight 30-second execution timeout. **The Danger Zone:** It is a common temptation for teams migrating from SFRA to lift heavy business logic from their old controllers and drop it directly into an OCAPI hook to modify API behaviour. This could include complex custom price adjustments, intricate promotion applications, or calls to multiple external systems. **The Fallout:** If the script in the hook exceeds the 30-second limit, the entire OCAPI API call fails, typically returning a generic 500 error to the client. The hook’s logic is aborted mid-execution, which carries the additional risk of leaving data in an inconsistent state. **The Pro Move:** Hooks must be treated with extreme prejudice. They should be kept as lightweight as possible, used only for minor data modifications, simple validations, or setting a value. Any process that involves significant computation, database lookups, or external network calls should be moved out of the hook and into a separate, dedicated custom API endpoint that can be called asynchronously by the client or handled by a backend job. ## The Two-Tier System: Custom API Constraints **The Limit:** The Custom APIs framework, which allows developers to extend SCAPI with their own endpoints, is built on a fundamental two-tier system: “Shopper” endpoints and “Admin” endpoints. Shopper endpoints are designed for high-scale, low-latency, user-facing interactions and are therefore subject to stricter, unpublished limits on execution runtime and request/response body size. They must be associated with a `siteId` and are secured using SLAS tokens. Admin endpoints, by contrast, are more permissive but require authentication via Account Manager OAuth and are intended for backend or administrative tasks. **The Danger Zone:** The primary mistake is attempting to perform a data-intensive or long-running operation through a Shopper-scoped Custom API. This might include a user-triggered request to generate a large, custom data export or a complex calculation over a customer’s entire order history. **The Fallout:** The request will likely encounter an uncatchable platform timeout or resource limit, resulting in the operation failing for the user. **The Pro Move:** The architecture of any custom API must be designed with this split in mind from day one. - **Shopper Endpoints:** Utilise for high-frequency, low-latency operations integral to the core user journey (e.g., retrieving a custom piece of data for the product page). - **Admin Endpoints:** Use for heavy, backend processes or administrative functions that might be called by a custom Business Manager module, an external system, or an asynchronous job (e.g., triggering a bulk data synchronisation). ## The Ghost in the Machine: dw.system.Session in a Headless World **The Limit:** This is not a formal quota but a critical architectural anti-pattern. The `dw.system.Session` object is a construct of the B2C Commerce server-side web tier. In a pure, stateless SCAPI architecture, there is no server session. However, in hybrid architectures or during a phased migration from SFRA, developers may be tempted to use OCAPI session bridging or pass the `dwsid` session cookie in custom headers to SCAPI calls to maintain a semblance of the old session-based state. **The Danger Zone:** Relying on the server-side session to manage state in an application that is supposed to be headless. This creates a tight, brittle coupling to the old monolithic architecture, negating many of the benefits of going headless, such as the independent scaling and deployment of the frontend. It is a recipe for bizarre and hard-to-debug caching and state management bugs. **The Fallout:** Unpredictable behaviour is the main outcome. A user’s state may seem to vanish and then reappear, as subsequent API requests are load-balanced to different server nodes in the B2C Commerce grid, some of which may not yet have the user’s session data replicated. Caching at the CDN level becomes nearly impossible, as every request is uniquely personalised by the presence of the `dwsid` cookie. **The Pro Move:** The server session must be avoided at all costs in a headless build. State management is the responsibility of the client application, utilising tools such as React’s built-in state and context APIs or more advanced libraries like Redux. State should be persisted by making explicit API calls, for example, saving the user’s cart contents via the Shopper Baskets API. For personalisation, the modern, stateless approach is to use the `Shopper Context API`, which allows context (like customer group or source code) to be passed directly in the API call itself, influencing the response without relying on a sticky server session. ## Conclusion: From Quota-Fearing to Quota-Fluent The extensive landscape of quotas and limits within Salesforce B2C Commerce Cloud should not be viewed as a field of landmines for developers. Instead, these constraints are a design partner, a set of rules that, when understood and respected, guide the development of applications that are inherently more performant, stable, and scalable. The most successful B2C Commerce developers are not those who discover clever workarounds to circumvent limits—a path that inevitably leads to performance bottlenecks, maintenance nightmares, and platform instability. The true experts are those who architect their solutions to thrive within these boundaries. A quota-fluent developer internalises these limits and uses them as a lens through which they evaluate every technical decision. They write efficient code, choose the right tool for the job (a real-time API versus an asynchronous job), cache intelligently at every layer, and have a deep understanding of the unique constraints of their chosen architecture, whether it’s a traditional monolith or a modern headless application. The path to this fluency begins with proactive monitoring. The Quota Status dashboard in Business Manager should be a regular destination, not just a reactive tool used during an outage. Every `WARN` level message in the quota logs should be treated as a valuable, early signal—an opportunity to refactor, optimise, and improve before a minor inefficiency becomes a major production incident. By embracing these limits as a core part of the development process, teams can transition from being quota-fearing to quota-fluent —a critical step in mastering the art of building elite e-commerce experiences on the Salesforce platform. --- ## Realm Split Guide for Migrating an SFCC Site Canonical URL: https://rhino-inquisitor.com/the-realm-split-field-guide-to-migrating-an-sfcc-site/ Markdown URL: https://rhino-inquisitor.com/the-realm-split-field-guide-to-migrating-an-sfcc-site/index.md Content type: article Published: 2025-09-08T09:14:15Z Updated: 2025-09-08T09:14:15Z Summary: Field guide to realm splits in SFCC, covering when the migration is justified, key delivery phases, and the operational risks teams inherit. Categories: Architecture, Salesforce Commerce Cloud Tags: sfcc, technical ## Key Takeaways - Explains what a realm split really is in SFCC and the business or technical pressures that justify it as a last-resort migration path - Provides a phased field guide covering scoping, Salesforce coordination, data migration, integration rebuilds, testing, cutover, and rollback awareness - Highlights the major operational risks around analytics loss, SEO preservation, sequence numbers, and post-split multi-realm complexity Have you ever found yourself in a deployment-day standoff? Your team is ready to push a critical feature for the US site, but it’s blocked because a seemingly unrelated change for the EU site, which shares your codebase, has failed QA. You’re stuck. This kind of organisational friction, where independent business units become entangled in a shared technical fate, is a clear signal that your single Salesforce B2C Commerce Cloud realm is cracking under pressure. The technical dependencies that once streamlined operations now create bottlenecks, and the shared codebase that once promised efficiency has become a source of risk and frustration. When this friction becomes unbearable, the business is faced with a monumental decision: a realm split. This is the architectural divorce of a site from its original family of instances, code, and data. It is a deliberate move to carve out a new, autonomous environment where a business unit can operate without being constrained by the priorities, schedules, and technical debt of its siblings. But like any divorce, it is complex, costly, and fraught with peril. A realm split is not a simple data replication or a POD move; it is a full-scale migration that touches every aspect of the platform, from the underlying infrastructure to third-party integrations and historical analytics. This field guide serves as a comprehensive, battle-tested [blueprint](https://help.salesforce.com/s/articleView?id=000391622&language=en_US&type=1) for SFCC developers and architects tasked with navigating this process. It provides a detailed plan of action that covers the strategic ‘why,’ the tactical ‘how,’ and the critical ‘what to watch out for.’ From justifying the immense cost and effort to executing a minute-by-minute cutover plan and managing the post-split reality, this document is designed to be the definitive resource for successfully cleaving a site into its own sovereign territory. ## Deconstructing the Monolith: The ‘Why’ and ‘When’ of a Realm Split Before embarking on such a significant undertaking, it is imperative to understand the foundational architecture and the specific pressures that lead to its fracture. A realm split is a solution to a problem that is often more organisational than technical, and its justification must be built on a solid understanding of both the platform’s structure and the business’s evolution. ### A Technical Primer on the SFCC Realm In the SFCC ecosystem, a realm is the fundamental organisational unit. It is not merely a collection of sites but the entire [infrastructure](/the-salesforce-b2c-commerce-cloud-environment/) stack provided by Salesforce to a customer. This stack contains all the necessary hardware and software components to develop, test, and deploy a storefront, including web servers, application servers, and database servers. For a developer, the realm is the entire world in which their sites live and operate. This world is rigidly structured into two distinct groups: - **Primary Instance Group (PIG):** This is the core operational group, and a realm can have only one. It consists of three instances: Production (the live storefront), Staging (for data setup and pre-deployment testing), and Development (for data enrichment and configuration). - **Secondary Instance Group (SIG):** This group contains the developer sandboxes. Like the PIG, a realm can only have one SIG. This architecture is designed for efficiency under a unified operational model. Sites within the same realm can share a master product catalog, a single codebase, and a standard set of administrative and development teams, creating significant economies of scale. However, this inherent sharing is also its greatest weakness when the business model diverges from its core. ### Analyzing the Breaking Points: When a Single Realm Becomes Untenable The decision to split a realm is a lagging indicator of a fundamental misalignment between a company’s organizational structure and its technical architecture. The initial choice of a single realm is often based on an assumption of a unified business strategy. The need for a split arises when that assumption is no longer valid. This manifests through several distinct business and technical drivers. ![Two global business teams clashing over divergent deployment workflows, representing the organisational friction that forces a realm split decision.](/the-realm-split-field-guide-to-migrating-an-sfcc-site/conflicts-across-the-world-on-processes-d64e01a143_hu_2179ba07b137156e.webp) When Workflows Clash: divergent P&L units, global scheduling conflicts, and incompatible business processes are the organisational tipping points that make a single SFCC realm unworkable. #### Business Drivers - **Divergent Business Processes:** The most compelling reason for a split is when different business units can no longer operate under a single set of rules. For example, a pharmaceutical site that requires doctor’s prescription validation has a fundamentally different checkout and order processing logic than a standard apparel site. Forcing both to coexist in a single realm with a shared codebase leads to immense complexity and risk. - **Independent P&L and Operational Autonomy:** When business units have separate Profit & Loss (P&L) responsibilities, they often need the authority to define, prioritise, and fund initiatives independently. If the European division needs to launch a feature to meet a local market demand, it cannot be blocked by the North American division’s development schedule. A shared realm creates a zero-sum game for resources and deployment windows, whereas separate realms provide the necessary autonomy. - **Global Teams and Conflicting Schedules:** A single realm has a unified maintenance and release schedule. This becomes untenable for global teams operating in different time zones. A release that requires downtime at 2 AM in the US might be prime shopping time in the Asia-Pacific region. Separate realms allow for independent operational schedules tailored to each market. #### Technical Drivers - **Data Residency and Compliance:** This is often a non-negotiable, legally mandated driver. Regulations like the GDPR may require that all personally identifiable information (PII) for European customers be stored in a data centre (or POD) located within the EU. If the existing realm is hosted on a US POD, a new, separate realm must be provisioned in the correct region to achieve compliance. - **Codebase Complexity and Deployment Risk:** As divergent business requirements are shoehorned into a single codebase, it inevitably becomes a tangled mess of site-specific conditional logic (if (site.ID === ‘US’) {… } else if (site.ID === ‘EU’) {… }). This increases the cognitive load for developers, slows down development, and dramatically increases the risk that a change for one site will have unintended, catastrophic consequences for another. A realm split allows the departing site to start with a clean, purpose-built codebase, free from the technical debt of its former siblings. - **Performance and Governor Limits:** While it should be the last option considered, severe performance degradation can be a driver for a split. If extensive code optimisation fails to resolve issues and distinct business units consistently create resource contention or hit governor limits, isolating the high-traffic or computationally intensive site in its own realm can restore stability for all parties. ## The Cardinal Rule: A Realm Split is the Last Resort It is crucial to understand that a realm split is a “complex and costly undertaking”. Before committing to this path, all other alternatives must be thoroughly investigated and exhausted. If the primary issue is storage, adopting a data archiving solution or purchasing additional storage from Salesforce is a far more straightforward and cost-effective option. If performance is the problem, a rigorous cycle of code optimisation and profiling should be the first course of action. A realm split introduces significant new overhead in terms of infrastructure costs and management complexity. **_It should only be pursued when the strategic benefits of autonomy and isolation unequivocally outweigh these substantial new burdens._** ## The Grand Blueprint: A Phased Plan of Attack Executing a realm split is a major re-platforming project disguised as a migration. Success depends on a meticulously detailed, phased [plan](https://help.salesforce.com/s/articleView?id=000391622&language=en_US&type=1) that accounts for every dependency, from stakeholder alignment to data integrity and third-party coordination. The following blueprint breaks the process down into six critical phases. ![Team collaborating around a holographic blueprint for a phased realm split migration.](/the-realm-split-field-guide-to-migrating-an-sfcc-site/the-grand-blueprint-v2-9c2bcca94a_hu_cf1ddb4852357f3.webp) A realm split only works with a phased plan covering scope, support, migration, integration, testing, and cutover. Success in a complex project like a realm split hinges on a meticulously detailed, phased plan. This image visualizes a team of experts collaborating on a holographic blueprint, representing the strategic and coordinated effort required to navigate the six critical phases of the migration. ### Phase 1: The Scoping & Justification Gauntlet This initial phase is about building the business case and creating a comprehensive map of the existing environment. Rushing this stage is a recipe for budget overruns and unforeseen complications. - **Define Clear Goals and Objectives:** Before any technical work begins, all stakeholders—business, marketing, development, and operations—must agree on what a successful split looks like. These goals should be specific and measurable (e.g., “The new EU site is live on the new realm with a 15% improvement in average page load time,” or “The EU development team can execute independent weekly deployments without impacting the US release schedule”). This provides a north star for the project and a clear definition of what is considered “done.” - **Conduct a Thorough Audit of the Source Realm:** A new realm is a clean slate; do not pollute it with the cruft of the old one. Conduct a deep audit of the source environment to identify and catalogue every component. This includes all custom cartridges, jobs, services, custom object definitions, site preferences, and integrations. Any stale, redundant, or unused metadata should be earmarked for cleanup _before_ the migration begins. This reduces the complexity of the new environment and prevents future headaches. - **Map Every Integration:** This is one of the most critical and frequently underestimated tasks. Create a definitive diagram and inventory of every single third-party system that communicates with the SFCC instance. For each integration (payment gateways, tax services, OMS, ERP, PIM, etc.), determine its fate: Will it connect to the new realm only? Does it need to connect to both? Will it require a completely new configuration or even a new contract? Answering these questions early is essential for planning and vendor coordination. ### Phase 2: Engaging the Gatekeepers - Navigating Salesforce Support Several key steps in a realm split can only be performed by Salesforce. Engaging with their support and provisioning teams early and clearly is a hard dependency for the entire project. - **Order the New Realm:** A new realm is a new commercial product. The process begins by working with your Salesforce account executive to submit a standard realm order form. This initiates the provisioning of the new PIG and SIG infrastructure. - **Data Migration Support:** Some pieces of data can only be migrated by Salesforce; keep this dependency in mind! - **Open the Go-Live Ticket:** If the site being moved will be the _first_ site in the new realm, you are required to go through the full, formal “Go Live” process. This is a structured engagement with Salesforce that has its own set of checklists, performance reviews, and timelines. This process must be initiated by opening a Go Live ticket well in advance of your target launch date. - **Establish Clear Communication Channels:** Use the Salesforce Help portal to log all cases related to the realm split. It is critical to ensure you select the correct B2C tenant/realm ID in the case details for both the source and destination environments. This ensures your requests are routed correctly and provides an official channel for coordinating the migration steps that require Salesforce intervention. ### Phase 3: The Great Data Exodus - A Migration Deep Dive The process of moving data is not a single “lift and shift” operation; it is a series of carefully orchestrated steps. The core strategy is to minimize downtime during the final cutover window by migrating the bulk of the data incrementally in the days or weeks leading up to the launch. Only the final “delta”—the data that has changed since the last sync—should be moved during the go-live event. This process reveals a critical truth about a realm split: it is not a simple copy. It is the construction of a new, parallel stack that must be made to perfectly mirror the relevant parts of the old one. Every piece of data, code, and configuration must be explicitly migrated and, more importantly, _validated_ in the new environment. The project plan must account for this re-validation effort, not just the migration itself. The most dangerous mindset a developer can have is “it worked in the old realm, so it will work in the new one.” #### The Realm Split Data Migration Checklist The complexity of data migration, with its varied methods and ownership, demands a single source of truth. The following table acts as a project management artifact, translating the plan into a clear, actionable checklist. Also, please review [this page](https://help.salesforce.com/s/articleView?id=000391622&language=en_US&type=1) carefully, as it contains a wealth of information on the migration plan you need to set up. Cross-check sync timing, operational risk, and ownership before the cutover runbook is locked. On smaller screens, each checklist row stacks into a card so every field stays readable. | Data object | When | Key considerations and risks | Primary owner | | --- | --- | --- | --- | | **Product Catalog** | Continuous in the old and new realms | Includes products, categories, assignments, and sorting rules. Relatively low risk. | Dev Team / Merchandising | | **Price Books** | Continuous in the old and new realms | Ensure all relevant price books are included. Test pricing thoroughly post-import. | Dev Team / Merchandising | | **Content Assets and Libraries** | Manual syncs at pre-defined moments | Includes content assets, folders, and library assignments. | Dev Team / Content Team | | **Slot Configurations** | Manual syncs at pre-defined moments | Verify slot configurations on all page types post-import. | Dev Team / Merchandising | | **Promotions and Campaigns** | Manual syncs at pre-defined moments | Includes promotion definitions, campaigns, and customer groups. | Dev Team / Marketing | | **Custom Objects** | Manual syncs at pre-defined moments | Export definitions via Site Export. Migrate data using custom jobs with dw.io classes. | Dev Team | | **Site Preferences and Metadata** | Manual syncs at pre-defined moments | Many settings are included in site export, but some (for example, sequence numbers) must be manually configured and verified. | Dev Team | | **Customer Profiles** | Complete migration 1-2 weeks before the go-live, delta during and after | Critical PII riskEnsure the Customer Sequence Number in the new realm is set higher than the highest customer number being imported to prevent duplicate IDs and data exposure. | Dev Team | | **Customer Passwords** | Part of the Customer Profiles | Passwords are encrypted, but can be exported and imported into different realms without any intervention from Salesforce. | Dev Team | | **Order History** | Complete migration 1-2 weeks before the go-live, delta during and after | You can export and import orders yourself as long as the site is not marked "live".

WarningComplete customer imports before order imports, otherwise order-to-customer linking will not occur in the background.

MandatoryFor a live site, order migration _must_ be performed by Salesforce Support with at least 10 working days' notice. | Dev Team / Salesforce Support | | **System-Generated Coupons** | Salesforce Support Ticket | MandatoryTo ensure existing coupons remain valid, the underlying "seeds" must be migrated by Salesforce Support.

Requires a separate, specific support ticket. | Salesforce Support | | **Active Data and Einstein** | Salesforce Support Ticket During go-live | For different realms, this requires a support ticket. | Dev Team / SF Support | ### Phase 4: Rebuilding the Engine - Code, Config, and Integrations With the new realm provisioned, the focus shifts to building out the application and its ecosystem. - **Establish a New CI/CD Pipeline:** Your existing deployment pipeline is tied to the old realm. A new, parallel pipeline must be created that targets the sandboxes and PIG instances of the new realm. The full codebase for the migrating site should be deployed and tested through this new pipeline. - **Replicate and Validate Configuration:** Although site import/export handles most of the configuration, several critical settings must be manually replicated and validated in the new realm’s Business Manager. This includes global preferences like sequence numbers, security settings, and any custom site preferences that are not part of the standard export package. - **Execute the Integration Plan:** This is where the audit from Phase 1 becomes an action plan. - **Create New API Clients:** An API client in Account Manager is tied to a specific realm and cannot be moved (although they can be used by a different realm). You must create entirely new API clients for the new realm, which will generate new Client IDs and secrets for every single integration. - **Coordinate with Third-Party Vendors:** Proactively contact every third-party vendor. Provide them with the new API credentials and the new hostnames for the Staging and Production instances. Update any IP allowlists on both sides. This process can take time and must be initiated well in advance of the planned cutover. ### Phase 5: The Crucible of Testing Rigorous, end-to-end testing is the only way to ensure a smooth launch. The new Staging instance is your battlefield for uncovering issues before they impact customers. - **User Acceptance Testing (UAT):** Business users and QA teams must conduct exhaustive testing of every user journey on the new Staging instance. This includes account creation, login, searching and browsing, adding to cart, applying promotions, and completing checkout with all supported payment methods. - **End-to-End Integration Validation:** It is not enough to test the SFCC functionality in isolation. Every single third-party integration must be tested end-to-end. Place test orders that flow through to your payment gateway, tax service, and Order Management System. Verify that inventory updates and shipping notifications are working correctly. - **Performance and Load Testing:** The new realm is a new set of infrastructure. Use the Business Manager Code Profiler to identify any server-side performance regressions. Conduct a full-scale load test against the new PIG (either on the pre-production environment or a dedicated “loaner realm”) to simulate peak traffic and ensure the new environment is appropriately scaled and configured to handle the production load. ### Phase 6: The Cutover - A Minute-by-Minute Runbook The go-live event should be a precisely choreographed execution of a pre-written script, not a series of improvisations. Create a hyper-detailed, time-stamped runbook that lists every action, its owner, and its expected duration. This runbook is law. The sequence, based on Salesforce’s official guidance, is as follows: 1. Final communications to all stakeholders. Freeze all administrative changes in the old realm’s Business Manager. 2. Place the old site into **Maintenance Mode**. Immediately update the primary Salesforce Support ticket with the exact timestamp. 3. **Go-Live:** The migration process can now begin. This 90-minute waiting period is a mandatory requirement from Salesforce. 4. Execute the final delta data migration jobs (new customers, new orders, etc.). Coordinate closely with Salesforce Support as they perform their required migration tasks (active data). 5. **Migration Complete:** Once all data is moved, perform a final smoke test on the new Production instance using internal hostnames (bypassing public DNS). 6. Update the public DNS records (e.g., the www CNAME) to point the storefront domain to the new realm’s Production instance endpoint. 7. Once DNS propagation is confirmed, set the new site’s status to **Online** in Business Manager. Update the Salesforce Support ticket again with the exact timestamp. 8. **Post-Launch Hypercare:** All hands on deck. Intensively monitor server logs, analytics dashboards, and order flow for any anomalies. The project team should be on standby to address any immediate issues. ## The SEO Minefield: Preserving Your Digital Ghost ![Illustration of a team navigating an SEO minefield during a high-stakes site migration.](/the-realm-split-field-guide-to-migrating-an-sfcc-site/seo-minefield-03b727d6da_hu_a782c9eb55c07499.webp) SEO survival starts with redirects, URL parity, a refreshed sitemap, and a new Search Console property. Underestimating the SEO impact of a realm split is a catastrophic error that can wipe out years of search equity. This image visualizes the high-stakes process of navigating this “SEO minefield,” where a single misstep can have explosive consequences. The illuminated path represents the meticulous, non-negotiable strategy—like a comprehensive 301 redirect map—required to safely migrate a site and preserve its valuable “digital ghost.” A realm split, from a search engine’s perspective, is essentially a complete site migration. Underestimating the SEO impact is a catastrophic error that can instantly wipe out years of accumulated search equity, traffic, and revenue. Google’s own representatives have stated that split and merge operations take “considerably longer for Google to process” than standard migrations because their algorithms must re-crawl and re-evaluate the entire structure of the new site (But if your site looks the same, has the same URL structure, etc, Google will not know anything changed at all - besides IP addresses). Patience and meticulous planning are paramount. - **The 301 Redirect Map is Non-Negotiable:** This is the single most critical SEO artefact for the migration. You must create a comprehensive map that pairs every single indexable URL on the old site with its corresponding URL on the new site. This includes the homepage, all category pages, all product detail pages, and any content or marketing pages. Use a site crawler to generate a comprehensive list of URLs from the old site, ensuring 100% coverage. These redirects must be implemented in Business Manager (Merchant Tools > SEO > URL Redirects) and be live the moment the new site is launched. _**Note:** This only applies if the URL structure changed._ - **Replicate URL Rules and Configuration:** The structure of your URLs is a key ranking signal. In the new realm’s Business Manager, you must meticulously replicate the URL Rules (Merchant Tools > SEO > URL Rules) from the old realm. Pay close attention to settings for forcing lowercase URLs and defining character replacements for spaces and special characters. This ensures that the URLs generated by the new site will match the old ones to the letter. - **Manage Sitemaps and Robots.txt:** The moment the new site is live and DNS has propagated, you must generate a new sitemap.xml file from the new realm’s Business Manager and submit it to Google Search Console (only if the location changed). This tells Google to begin crawling the new site structure. Simultaneously, ensure that the robots.txt file for the new site is correctly configured, allowing crawlers to access all important pages and blocking any non-public sections of the site (like internal search or cart pipelines). - **Coordinate with SEO and Marketing Teams:** SEO migration is not solely a technical task. The SEO and marketing teams must be integral members of the project team from day one. They are responsible for auditing the redirect map, setting up the new Google Search Console property, monitoring for crawl errors post-launch, and tracking keyword rankings and organic traffic to measure the impact of the migration. ## The Developer’s Survival Guide: Warnings, Pitfalls, and Pro-Tips The difference between a smooth migration and a career-limiting disaster often comes down to awareness of the hidden dangers and adoption of battle-tested best practices. This is the hard-won wisdom from the trenches. ### Red Alerts (Warnings) - **Irreversible Analytics Loss:** This cannot be overstated. Historical analytics data from Reports & Dashboards **does not transfer** to the new realm. The new realm begins with a zeroed-out dashboard. While you can still access the old data by selecting the old realm ID in the Reports & Dashboards interface, the data from the two realms is never combined into a single view **Actionable Advice:** Before the split, work with the business and analytics teams to identify and export all critical historical reports. This data must be preserved externally, as it will be inaccessible from the new realm’s reporting interface. - **The Data Corruption Gauntlet:** Heed the warnings from Salesforce Support. The cutover runbook is not a suggestion; it is a strict protocol. Changing the old site back to “Online” after the migration process has started, or failing to follow the instructions, can result in irreversible data corruption. There is no room for error in the cutover sequence. - **PII and the Sequence Number Bomb:** The warning about Customer Sequence Numbers is critical enough to repeat. Suppose you import customer profiles with customer numbers (e.g., cust\_no = 5000) into a new realm where the sequence number is still at its default (e.g., 1000). In that case, the system will eventually start creating new customers with numbers that conflict with your imported data. This can lead to a catastrophic PII breach where one customer logs in and sees another customer’s profile, address, and order history. (e.g. a customer wasn’t imported because of “whatever reason”, and their number is “taken over”.) **Actionable Advice:** Before importing any customer data, go to Administration > Global Preferences > Sequence Numbers in the new realm and manually set the Customer Number to a value safely above the highest customer number in your import file. ### Common Traps (Pitfalls) - **The Obscure Realm Setting:** A realm is more than what you see in Business Manager. There are underlying configurations that are only visible to Salesforce Support. **Lesson Learned:** Never assume the new realm is a perfect 1:1 clone of the old one. Suppose you encounter a bizarre, inexplicable bug that defies all logical debugging. In that case, your next step should be to open a high-priority support case and make sure that they perform a full comparison of all underlying realm configurations between the source and the destination. - **Forgetting the “Small” Data:** It is easy to focus on the big-ticket items like products and orders and completely forget smaller but equally critical data points. The migration of system-generated coupon seeds is a perfect example. If you use these types of coupons and forget to open the specific support ticket to have the seeds migrated, all previously issued coupons will become invalid the moment you go live, leading to failed promotions and customer frustration. - **Underestimating Integration Timelines:** A realm split is an integration project for every single system that connects to SFCC. Third-party vendors have their own change control processes, support SLAs, and technical resource availability. Assuming a vendor can instantly provide new credentials or update an IP allowlist on your go-live day is a recipe for failure. ### Veteran’s Wisdom (Pro-Tips) - **Rehearse, Rehearse, Rehearse:** Conduct at least one, and preferably several, full dry runs of the entire data migration and cutover process. This can be done by migrating data from a sandbox in the old realm to a sandbox in the new realm. A rehearsal will inevitably uncover flawed assumptions, broken scripts, or missing data in a low-stakes environment, allowing you to fix the process before the high-pressure production event. - **Script Everything Possible:** Any manual step in a cutover plan is a potential point of failure. Automate as much of the process as you can. Write scripts for exporting and transforming data, for replicating configurations via Business Manager APIs (where possible), and for post-launch validation checks. Automation reduces the risk of human error and speeds up the execution of the runbook. - **Benchmark Performance Before and After:** Do not rely on subjective feelings about site speed. Before the split, use the Code Profiler and external web performance tools (like WebPageTest) to establish a clear, quantitative performance baseline for the site on the old realm. After the new site is live, run the exact same tests. This provides concrete data to demonstrate that performance has not degraded, allowing you to quantify any improvements gained from the new, isolated infrastructure. - **Plan for a Rollback, but Work to Not Need It:** Your runbook must include a clear “point of no return” and a detailed rollback plan. A rollback is technically possible in the early stages of the cutover (primarily by reverting the DNS change), as the old realm and site will still exist. However, it becomes exponentially more difficult with every new order and customer registration that occurs on the new site. The rollback plan is a critical safety net, but the primary focus should be on meticulous planning and testing to ensure it is never needed. ## Conclusion: Life in the Multiverse The successful launch of the migrated site is not the end of the project; it is the beginning of a new, more complex operational reality. The realm split achieves its primary goal of technical and business autonomy, but it does so by trading the constraints of a monolith for the complexities of a distributed system. The new normal is a multi-realm architecture. On the positive side, the newly independent site now has the flexibility to develop and deploy on its own schedule, with a codebase tailored to its specific needs. The risk of a change for one brand impacting another is eliminated. However, this autonomy comes at a price. The business now bears the increased infrastructure costs of an additional PIG and SIG, along with the added maintenance overhead of managing two separate codebases, two deployment pipelines, and two sets of administrative processes. ![Illustration of a central SFCC realm splitting into multiple autonomous, interconnected realms.](/the-realm-split-field-guide-to-migrating-an-sfcc-site/realm-split-97dc1add29_hu_4d57602d2c729181.webp) Deployment autonomy is the prize, but a realm split also means duplicated pipelines and higher operating cost. An illustration of a realm split, where a single, monolithic system fractures into multiple autonomous realms. This transition unlocks business and technical flexibility but introduces the new operational complexity of managing a distributed system, including the critical need for data synchronization between the separate entities. One of the most significant new challenges is data synchronisation. If the business still requires a shared product catalog or consistent promotional data across realms, this can no longer be achieved through the platform’s native sharing capabilities. Sites in different realms cannot share a catalog directly. Instead, you must build and maintain a new operational process, likely a set of automated jobs and a CI/CD pipeline, to handle the export of data from a “master” realm and its import into the “subscriber” realm. **_This introduces a new potential point of failure and a new set of tasks for the operations team._** Ultimately, a realm split is an immense undertaking that fundamentally reshapes a company’s digital commerce architecture. It is the right decision—and often the only decision—when the organisational friction and technical limitations of a single realm become an insurmountable barrier to growth. The significant cost and complexity are justified only when the business and technical autonomy it unlocks is a strategic necessity. --- ## Deep Dive into SFCC Meta Tag Rules Canonical URL: https://rhino-inquisitor.com/taming-the-beast-a-developers-deep-dive-into-sfcc-meta-tag-rules/ Markdown URL: https://rhino-inquisitor.com/taming-the-beast-a-developers-deep-dive-into-sfcc-meta-tag-rules/index.md Content type: article Published: 2025-08-04T07:13:04Z Updated: 2025-08-04T12:14:46Z Summary: Most of us have glanced at the "Page Meta Tag Rules" section in Business Manager, shrugged, and moved on to what we consider 'real' code. Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, headless, sfcc, sfra, technical ## Key Takeaways - Explains SFCC page meta tag rules as a declarative SEO engine rather than a minor Business Manager configuration screen - Covers the syntax, inheritance model, hybrid fallback pattern, and practical troubleshooting approach developers need to use the feature safely - Highlights advanced use cases, common pitfalls, and how the same strategy can still support headless storefront architectures At some point in your Salesforce B2C Commerce Cloud career, you’ve been handed _The Spreadsheet_. It’s a glorious, terrifying document, often with 10,000+ rows, meticulously crafted by an SEO team. Each row represents a product, and each column contains the perfect, unique meta title and description destined to win the favour of the [Google](https://developers.google.com/search/case-studies) gods. Your heart sinks. You see visions of tedious data imports, endless validation, and the inevitable late-night fire drill when someone screams, “The staging data doesn’t match production!”. Most of us have glanced at the “Page Meta Tag Rules” section in Business Manager, shrugged, and moved on to what we consider ‘real’ code. That’s a mistake. This isn’t just another BM module for merchandisers to tinker with; it’s a declarative engine for automating one of the most tedious and error-prone parts of e-commerce SEO. It’s a strategic asset for developers to build scalable, maintainable, and SEO-friendly sites. This guide will dissect this powerful feature from a developer’s perspective. We’ll tame this beast by exploring its unique syntax, demystifying the “gotchas” of its inheritance model, and outlining advanced strategies for PDPs, PLPs, and even those tricky Page Designer pages. By the end, you’ll know how to leverage this tool to make your life easier and your SEO team happier, all without accidentally nuking their hard work. ## The Anatomy of a Rule: Beyond the Business Manager UI The first mental hurdle to clear is that Meta Tag Rules are not an imperative script. They are a declarative system. You are not writing code that executes line by line. Instead, you are defining a set of instructions—a recipe—that the platform’s engine interprets to generate a string of text. This distinction is fundamental because it dictates how these rules are built, tested, and debugged. It’s a specialised, declarative [Domain-Specific Language](https://en.wikipedia.org/wiki/Domain-specific_language) (DSL), not a general-purpose scripting environment like Demandware Script. This explains why you can’t just call arbitrary script APIs from within a rule and why the error feedback is limited. It’s about defining _what_ you want the output to be and letting the platform’s engine figure out _how_ to generate it. ### The Three Pillars of Rule Creation The process of creating a rule within Business Manager at `Merchant Tools > SEO > Page Meta Tag Rules` can be broken down into three logical steps : #### Meta Tag Definitions (The “What”) ![Meta tag definitions screen listing title, description, robots, and og:url entries.](/taming-the-beast-a-developers-deep-dive-into-sfcc-meta-tag-rules/meta-tag-rules-definitions-b886cc1425_hu_bc657e59aa4ff008.webp) Meta tag definitions are where you decide which HTML tags the rule engine will generate. This is where you define the _type_ of HTML tag you intend to create. Think of it as defining the schema for your output. You specify the `Meta Tag Type` (e.g., `name`, `property`, or `title` for the `` tag) and the `Meta Tag ID` (e.g., `description`, `keywords`, `og:title`). For a standard meta description, the `Type` would be `name` and the `ID` would be `description`, which corresponds to `<meta name="description"...>`. #### Rule Creation & Scopes (The “How” and “Where”) ![Create Entry modal for adding a Product Detail meta tag rule.](/taming-the-beast-a-developers-deep-dive-into-sfcc-meta-tag-rules/new-meta-tag-rule-sfcc-61609288f7_hu_5be2ddea30ed33f4.webp) Rule creation is where scope and logic come together for a specific page type. This is the core logic. You create a new rule, give it a name, and associate it with one of the `Meta Tag ID`s you just defined. Critically, you must select a `Scope`. The scope (e.g., Product, Category/PLP, Content Detail/CDP) is the context in which the rule is evaluated. It determines which platform objects and attributes are available to your rule’s syntax. For example, the `Product` object is available in the Product scope, but not in the Content Listing Page scope. #### Assignments (The “Who”) ![Assignments screen showing where a meta tag rule is attached in the catalog.](/taming-the-beast-a-developers-deep-dive-into-sfcc-meta-tag-rules/meta-tag-rule-assignments-sfcc-5de863b5b6_hu_485847b2f2e9947c.webp) Assignments determine which catalog or content tree actually receives the rule. Once a rule is defined, you must assign it to a part of your site. You can assign a rule to an entire catalog, a specific category and its children, or a content folder. This assignment triggers the platform to use your rule for the designated pages. ## The Syntax Cheat Sheet: Your Rosetta Stone ![A futuristic, glowing blue holographic Rosetta Stone displaying various code symbols and syntax, representing a cheat sheet for a complex language.](/taming-the-beast-a-developers-deep-dive-into-sfcc-meta-tag-rules/syntax-cheat-sheet-rosetta-stone-683e787325_hu_8711c35fd04d35a8.webp) The rule syntax looks arcane at first, but it is really a small declarative language. Don’t let the unique syntax of SFCC’s Meta Tag Rules intimidate you. Think of this cheat sheet as your Rosetta Stone, unlocking the ability to create powerful, dynamic, and SEO-friendly tags for your entire site. The rule engine has its own [unique syntax](https://help.salesforce.com/s/articleView?id=cc.b2c_meta_tag_rule_syntax.htm&language=en_US&type=5), which is essential to master. All dynamic logic must be wrapped in `${...}`. - **Accessing Object Attributes:** The most common action is pulling data directly from platform objects. The syntax is straightforward: `Product.name`, `Category.displayName`, `Content.ID`, or `Site.httpHostName`. You can access both system and custom attributes, though some data types like HTML, Date, and Image are not supported. - **Static Text with `Constant()`:** To include a fixed string within a dynamic expression, you must use the `Constant()` function, such as `Constant('Shop now at ')`. This is vital for constructing readable sentences. ### Mastering Conditional Logic The real power of the engine lies in its conditional logic. This is what allows for the creation of intelligent, fallback-driven rules. - **The IF/THEN/ELSE Structure:** This is the workhorse of the rule engine. It allows you to check for a condition and provide different outputs accordingly. - **The Mighty `ELSE` (The Hybrid Enabler):** The `ELSE` operator is the key to creating a “hybrid” approach that respects manual data entry. A rule like `${Product.pageTitle ELSE Product.name}` first checks for a value in the manually-entered `pageTitle` attribute. If, and only if, that field is empty, it falls back to using the product’s name. This single technique is the most important for preventing conflicts between automated rules and manual overrides by merchandisers. - **Combining with `AND` and `OR`:** These operators allow for more complex logic. `AND` requires both expressions to be true, while `OR` requires only one. They also support an optional delimiter, like `AND(' | ')`, which elegantly joins two strings with a separator, but only if both strings exist. This prevents stray separators in your output. - **Equality with `EQ`:** For direct value comparisons, use the `EQ` operator. This is particularly useful for logic involving pricing, for instance, to check if a product has a price range (`ProductPrice.min EQ ProductPrice.max`) or a single price. ### The Cascade: Understanding Inheritance, Precedence, and the Hybrid Approach The Meta Tag Rules engine was designed with the “Don’t Repeat Yourself” (DRY) principle in mind. The inheritance model, or cascade, allows you to define a rule once at a high level, such as the root of your storefront catalog, and have it automatically apply to all child categories and products. This is incredibly efficient, but only if you understand the strict, non-negotiable lookup order the platform uses to find the right rule for a given page. I’m not going to go into much detail here, as a complete fallback system is [documented](https://help.salesforce.com/s/articleView?id=cc.b2c_meta_tag_rules.htm&type=5). ## The Golden Rule: Building Hybrid-Ready Rules The most common and damaging pitfall is the “Accidental Override.” Imagine a merchandiser spends days crafting the perfect, keyword-rich `pageTitle` for a key product. A developer then deploys a seemingly helpful rule like `${Product.name}` assigned to the whole catalog. Because the rule is found and applied, it will silently overwrite the merchandiser’s manual work. This isn’t just a technical problem; it’s a failure of process and collaboration. The platform’s inheritance model and conditional syntax force a strategic decision about data governance: will SEO be managed centrally via rules, granularly via manual data entry, or a hybrid of both? The developer’s job is not just to write the rule but to implement the agreed-upon governance model. The solution is the **Hybrid Pattern**, which should be the default for almost every rule you create. **Example Hybrid PDP Title Rule:** `${Product.pageTitle ELSE Product.name} | ${Site.displayName}` Let’s break down how the engine processes this: 1. **`Product.pageTitle`:** The platform first checks the product object for a value in the `pageTitle` attribute. This is the field merchandisers use for manual entry in Business Manager (or hopefully imported from a third-party system). 2. **`ELSE`:** If, and only if, the `pageTitle` attribute is empty or null, the engine proceeds to the expression after the `ELSE` operator. If `pageTitle` has a value, the rule evaluation stops, and that value is used. This pattern provides the best of both worlds: automation and scalability for the thousands of products that don’t need special attention, and precise manual control for the high-priority pages that do. Adopting this pattern as a standard practice is the key to a harmonious relationship between development and business teams. ## Advanced Strategies and Best Practices Once you’ve mastered the fundamentals of syntax and inheritance, you can begin to craft mighty rules that go far beyond simple title generation. ### Crafting Killer Rules: Practical Examples #### The Perfect PDP Title (Hybrid) Combines the product’s manual title, or falls back to its name, brand, and the site name. `${Product.pageTitle ELSE Product.name AND Constant(' - ') AND Product.brand AND Constant(' | ') AND Site.displayName}` ### Scenario 1 (Manual `pageTitle` exists) Data: `Product.pageTitle` = “Best Trail Running Shoe for Rocky Terrain” Generated Output: `Best Trail Running Shoe for Rocky Terrain` Scenario 2 (No manual `pageTitle`, falls back to dynamic pattern): **Data:** `Product.name` = “SummitPro Runner” `Product.brand` = “Peak Performance” `Site.displayName` = “GoOutdoors” Generated Output: `SummitPro Runner - Peak Performance | GoOutdoors` #### The Engaging PLP Description (Hybrid) Checks for a manual category description, otherwise generates a compelling, dynamic sentence. `${Category.pageDescription ELSE Constant('Shop our wide selection of ') AND Category.displayName AND Constant(' at ') AND Site.displayName AND Constant('. Free shipping on orders over $50!')}` ### Scenario 1 (Manual `pageDescription` exists) Data: `Category.pageDescription` = “Explore our premium, all-weather tents. Designed for durability and easy setup, perfect for solo hikers or family camping trips.” Generated Output: `Explore our premium, all-weather tents. Designed for durability and easy setup, perfect for solo hikers or family camping trips.` Scenario 2 (No manual `pageDescription`, falls back to dynamic pattern): **Data:** `Category.displayName` = “Camping Tents” `Site.displayName` = “GoOutdoors” Generated Output: `Shop our wide selection of Camping Tents at GoOutdoors. Free shipping on orders over $50!` #### Dynamic OpenGraph Tags Create separate rules for `og:title` and `og:description` using the same hybrid patterns. For `og:image`, you can access the product’s image URL. `${ProductImageURL.viewType}` (Note: The specific `viewtype` is needed, e.g. `large`) - **Scenario:** A user shares a product page on a social platform. - **Data:** The system has an image assigned to the product in the “large” slot. - **Generated Output:** `<https://www.gooutdoors.com/images/products/large/PROD12345_1.jpg>` #### Dynamic OpenGraph Tags (Crafting Killer Rules: Practical Examples) This is a truly advanced use case that demonstrates how rules can implement sophisticated SEO strategy. This rule helps prevent crawl budget waste and duplicate content issues by telling search engines not to index faceted search pages. `${IF SearchRefinement.refinementColor OR SearchPhrase THEN Constant('noindex,nofollow') ELSE Constant('index,follow')}` Scenario 1 (User refines a category by color): A user is on the “Backpacks” category page and clicks the “Blue” color swatch to filter the results. - **Data:** `SearchRefinement.refinementColor` has a value (“Blue”). - **Generated Output:** `noindex, nofollow` - **Result:** This filtered page won’t be indexed by Google, saving crawl budget. Scenario 2 (User performs a site search): A user types “waterproof socks” into the search bar. - **Data:** `SearchPhrase` has a value (“waterproof socks”). - **Generated Output:** `noindex, nofollow` - **Result:** The search results page won’t be indexed. Scenario 3 (User lands on a standard category page): A user navigates directly to the “Backpacks” category page without any filters. - **Data:** `SearchRefinement.refinementColor` is empty AND `SearchPhrase` is empty. - **Generated Output:** `index, follow` - **Result:** The main category page will be indexed by Google as intended. ## The Page Designer Conundrum: The Unofficial Unofficial Workaround Here we encounter a significant limitation: out of the box, the Meta Tag Rules engine does not work with standard Page Designer pages. The underlying `Page` API object lacks the necessary `pageMetaTags`. This creates a significant gap for sites that rely on content marketing and campaign landing pages built in Page Designer. Luckily, an already complete working “workaround” example has been created by David Pereira [in the Page Designer meta tag workaround article](https://dev.to/bolt04/how-to-use-the-seo-meta-tag-rules-module-for-page-designer-in-sfcc-20i8). ## The Minefield: Warnings, Pitfalls, and Troubleshooting While powerful, the Meta Tag Rules engine is a minefield of potential “gotchas” that can frustrate developers and cause real business impact if not anticipated. - **Warning - The “Accidental Override”:** This cannot be overstated. A simple, non-hybrid rule (`${Product.name}`) deployed to production can instantly nullify months of careful, manual SEO work by the merchandising team. The Hybrid Pattern (`${Product.pageTitle ELSE...}`) is your shield. Always use it. This is fundamentally a process failure, not just a technical one, highlighting the need for a clear “contract” between development and business teams about who owns which data. - **Pitfall - The “30-Minute Wait of Despair”:** When you save or assign a rule in Business Manager, it can take up to [30 minutes](https://help.salesforce.com/s/articleView?id=cc.b2c_creating_page_meta_tag_rules.htm&type=5) for the change to appear on the storefront. This is due to platform-level caching. This delay is a classic initiation rite for new SFCC developers who are convinced their rule is broken. The solution is patience: save your rule, then go get a coffee before you start frantically debugging. (_**Note:** I personally have never had to wait this long_) - **Pitfall - The Empty Attribute Trap:** If your rule references an attribute (`Product.custom.seoKeywords`) that is empty for a particular product, the engine treats it as a null/false value. This can cause your conditional logic to fall through to an `ELSE` condition you didn’t expect. This underscores that the effectiveness of your rules is **directly dependent on the quality and completeness of your catalog** and content data. ## Troubleshooting the “Black Box” ![Category preview tab showing generated Page Meta Tag Rules output.](/taming-the-beast-a-developers-deep-dive-into-sfcc-meta-tag-rules/page-meta-tag-rules-sfcc-preview-8796961d9d_hu_9d586d11bbc896f0.webp) The preview tab is the safest place to test a rule before it reaches production data. You cannot attach the Script Debugger to the rule engine or step through its execution. Troubleshooting is a process of indirect observation. 1. **Step 1: Preview in Business Manager:** Your first and best line of defense. The SEO module has a preview function that lets you test a rule against a specific product, category, or content asset ID. This gives you instant feedback on the generated output without affecting the live site. 2. **Step 2: Inspect the Source:** The ultimate source of truth is the final rendered HTML. Load the page on your storefront, right-click, and select “View Page Source.” Search for `<title>` or `<meta name="description">` to see exactly what the engine produced. 3. **Step 3: The Code-Level Safety Net:** As a developer integrating the rules into templates, you have one final check. The `dw.web.PageMetaData` object, which is populated by the rules, is available in the `pdict`. You can use the `isPageMetaTagSet('description')` method within an `<isif>` statement in your ISML template; the [PageMetaData API reference](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_web_PageMetaData.html#dw_web_PageMetaData_isPageMetaTagSet_String_DetailAnchor) documents the call. This allows you to render a hardcoded, generic fallback meta tag directly in the template if, for some reason, the rule engine failed to generate one. ## The Performance Question: Debunking the Myth A common concern is that complex nested IF/ELSE rules might slow down page load times, but this is mostly a myth. The real performance issue relates to caching. For cached pages, the impact on performance is nearly nonexistent because the server evaluates the rule only once when generating the page’s HTML during the initial request. This HTML is then stored in the cache. Future visitors receive this pre-rendered static HTML directly from the cache, skipping re-evaluation. The small performance cost only occurs on cache misses. Thus, the focus shouldn’t be on creating overly simple rules but on maintaining a high cache hit rate. We can be confident that the Salesforce team has developed an effective feature to guarantee optimal performance. Keep in mind the platform cache with a 30-minute delay we previously mentioned. Within that “black box,” a separate system is likely also in place to protect performance. ## The Final Verdict: Meta Tag Rules vs. The Alternatives When deciding how to manage SEO metadata in SFCC, developers face three philosophical choices: ### Manual Entry Only (The Control Freak) - Manually populating the `pageTitle`, `pageDescription`, etc., for every item in Business Manager. - **Pros:** Absolute, granular control. Perfect for a small catalog or a handful of critical landing pages. - **Cons:** Completely unscalable. Highly prone to human error and data gaps. A maintenance and governance nightmare for any site of significant size. ### Custom ISML/Controller Logic (The Re-inventor) Ignoring the rule engine and writing your own logic in controllers and ISML templates to build meta tags. - **Pros:** Theoretically unlimited flexibility. You can call external services, perform complex calculations, etc.. - **Cons:** You are re-inventing a core platform feature, which introduces significant technical debt. The logic is completely hidden from business users, making it a black box that only developers can manage. It’s harder to maintain and creates upgrade path risks. ### Meta Tag Rules (The Pragmatist) Using the native feature as intended. - **Pros:** The standard, platform-supported, scalable, and maintainable solution. The logic is transparent and manageable by trained users in Business Manager. It fully supports the hybrid approach, offering the perfect balance of automation and control. - **Cons:** You are constrained by the built-in DSL. It has known limitations, like the Page Designer issue and syntax, that may require custom workarounds. ## What about the PWA Kit Yes, you can absolutely continue to leverage the power of **Page Meta Tag Rules** from the Business Manager in a **headless setup**. The key is understanding that your headless front end (like a PWA) communicates with the SFCC backend via APIs. While historically this might have required a development task to extend a standard API or create a new endpoint to expose the dynamically generated meta tag values, this is becoming increasingly unnecessary. Salesforce is actively expanding the **Shopper Commerce API ([SCAPI](/in-the-ring-ocapi-versus-scapi/))**, continuously adding new endpoints and enriching existing ones to expose more data directly. This ongoing expansion, as seen with enhancements to APIs like [Shopper Search](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-search?meta=productSearch) and [Shopper Products](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-products?meta=getProduct), means that the SEO-rich data generated by your rules is more likely to be available out of the box. Instead of building custom solutions, the task for developers is shifting towards simply querying the correct, updated SCAPI endpoint. This evolution makes it easier than ever to fetch the meta tags for these pages. It validates the headless approach, allowing you to maintain a robust, **centralised SEO strategy** in the Business Manager while fully embracing the flexibility and performance of a modern front-end architecture. ![SCAPI release update highlighting headless support for meta tag data.](/taming-the-beast-a-developers-deep-dive-into-sfcc-meta-tag-rules/sfcc-updates-headless-apis-for-meta-tag-rules-f61ced3d60_hu_890198a2cb816d2e.webp) Recent SCAPI changes matter because headless storefronts now rely on the same meta-rule data. ## Conclusion: Go Forth and Automate Salesforce B2C Commerce Cloud’s Page Meta Tag Rules are far more than a simple configuration screen. They are a strategic tool for building scalable, efficient, and collaborative e-commerce platforms. By mastering the hybrid pattern, understanding the inheritance cascade, knowing how to tackle limitations like the Page Designer gap, and—most importantly—communicating with your business teams, you can transform SEO from a manual chore into an automated powerhouse. So, the next time that dreaded SEO spreadsheet lands in your inbox, don’t sigh and start writing an importer. Crack open the Page Meta Tag Rules, build some smart, hybrid rules, and go grab a coffee. You’ve just saved your future self hundreds of hours of pain. You’re welcome. --- ## Field Guide to Custom Caches: Wielding a Double-Edged Sword Canonical URL: https://rhino-inquisitor.com/field-guide-to-custom-caches-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/field-guide-to-custom-caches-in-sfcc/index.md Content type: article Published: 2025-07-28T07:32:55Z Updated: 2025-07-28T07:37:24Z Summary: Learn when Custom Caches help in SFCC, where they create risk, and how to use them safely without hurting performance or maintainability. Categories: Salesforce Commerce Cloud, Technical Tags: performance, sfcc, technical ## Key Takeaways - Explains when custom caches are the right tool compared with page, request, or session storage - Shows safe patterns for cache keys, get-or-load usage, and lightweight cached objects - Warns that custom caches can hurt performance and correctness when used without discipline You think you know caching. You’ve enabled page caching, fiddled with content slot TTLs, and called it a day. And your Salesforce B2C Commerce Cloud site is still slower than a snail in molasses. Why? Because you’re ignoring the most potent weapon in your performance arsenal: the **Custom Cache**. [Custom Caches](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-custom-caches.html) are a double-edged sword, though. Wielded with discipline, precision, and a deep understanding of their limitations, they are one of the most potent performance-tuning instruments in your arsenal. Wielded carelessly, they will cut you, your application, and your customer’s experience to ribbons. The problem is that the platform’s API for [dw.system.CacheMgr](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/index.html?target=class_dw_system_CacheMgr.html) is deceptively simple, masking a minefield of architectural traps for the unwary developer. This is not a beginner’s tutorial. This is a field guide for the professional SFCC developer who needs to move beyond basic usage and master this powerful, perilous feature. We’re going to charge headfirst into the complexity, expose the sharp edges, and arm you with the patterns and discipline required to use Custom Caches safely, effectively, and with confidence. ## The Lay of the Land: Choosing Your Data Store Before you even think about writing `CacheMgr.getCache()`, you need to understand its purpose. Using the wrong tool for the job is the first step toward disaster. In SFCC, you have several options for storing temporary data, and choosing the correct [one](https://developer.salesforce.com/docs/commerce/commerce-solutions/guide/caching-strategies-sk.html) is a foundational architectural decision. ### Custom Cache vs. Page Cache: A Quick Primer Developers new to the platform frequently conflate Custom Caches and the Page Cache. They are fundamentally different beasts operating at different layers of the architecture. Mistaking one for the other is like using a hammer to turn a screw. - **Page Cache** is for caching **rendered output**. It operates at the **web server tier** and stores full HTTP responses—typically HTML fragments generated from ISML templates. You control it with the [`<iscache>`](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-content-cache.html) tag or the [`response.setExpires()`](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_Response.html#dw_system_Response_setExpires_Number_DetailAnchor) script API method. When a request hits a URL whose response is in the Page Cache, the [web server](/the-salesforce-b2c-commerce-cloud-environment/) serves it directly, never even bothering the application server. It is incredibly fast and is the primary defence against high traffic for storefront pages. - **Custom Cache** is for caching **application data**. It operates at the **application server tier** and stores JavaScript objects and primitives inside a script or controller’s execution context. You control it exclusively through the `dw.system.CacheMgr` script API. It’s designed to avoid recalculating expensive data or re-fetching it from an external source during the execution of a controller that will ultimately produce a response. The distinction is critical: **Cache the final, cooked meal with Page Cache, cache the raw ingredients with Custom Cache.** To avoid re-rendering a product tile’s HTML, use Page Cache with a remote include. If you need to avoid re-fetching the product’s third-party ratings data _before_ you render the tile, use a Custom Cache. Service Caching When discussing caching third-party services with custom caches, remember there’s another option I mentioned in a previous article: [using the ServiceRegistry for caching](/third-party-api-caching-in-commerce-cloud/). To keep this article straightforward, we’ll concentrate on caching third-party calls with custom caches. The choice of the best approach for your use case depends on the information you’ve collected. ## The Developer’s Dilemma: request vs. session vs. CacheMgr Within the application tier, you have three primary ways to store temporary, non-persistent data during script execution. Their scopes and lifetimes are vastly different, and choosing the wrong one can lead to performance degradation, security vulnerabilities, or bizarre bugs. - `request.custom`: This [object](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_Request.html#dw_system_Request_getCustom_DetailAnchor) lives for the duration of a **single HTTP request**. It is the most ephemeral of the scopes. Its primary purpose is to pass data between middleware steps in an SFRA controller chain or from a controller to the rendering template _within the same server call_. It’s a scratchpad for the current transaction and nothing more. - `session.custom` / `session.privacy`: These [objects](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_Session.html#dw_system_Session_getPrivacy_DetailAnchor) live for the duration of a **user’s session**. The platform defines this with a 30-minute soft timeout (which logs the user out and clears privacy data) and a six-hour hard timeout (after which the session ID is invalid). This scope is user-specific and sticky to a single application server. The critical difference is that writing to `session.custom` can trigger a re-evaluation of the user’s dynamic customer groups, while `session.privacy` does not. Data in `session.privacy` is also automatically cleared on logout. - `dw.system.CacheMgr`: [This](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_CacheMgr.html) is an **application-wide, server-specific cache**. The data is shared by _all users and all sessions_ that happen to land on the same application server. Its lifetime is determined either by a configured time-to-live (TTL) or until a major invalidation event occurs, such as a code activation or data replication. ## The Forge: Mechanics of a Custom Cache Once you’ve determined that a Custom Cache is the right tool, implementation requires a precise, methodical approach. There is no room for improvisation. Follow these steps as a mandatory checklist. ### The Blueprint: Defining Caches in caches.json ![Cartoon blueprint scene illustrating how a custom cache is assembled.](/field-guide-to-custom-caches-in-sfcc/salesforce-commerce-cloud-blueprinting-caches-c155ca3f8c_hu_ae547a419e8bd391.webp) Custom cache definition blueprint Your cache’s life begins with a simple declaration. This is done in a JSON file, conventionally named `caches.json`, which must reside within your cartridge. 1. **Create `caches.json`:** Inside your cartridge, create the file. For example: `int_mycartridge/caches.json`. 2. **Define Your Caches:** The file contains a single JSON object with a `caches` key, which is an array of cache definitions. Each definition requires an `id` and can optionally include an `expireAfterSeconds` property. ```json { "caches": [ { "id": "UnlimitedTestCache" }, { "id": "TestCacheWithExpiration", "expireAfterSeconds": 10 } ] } ``` The `id` must be **globally unique** across every single cartridge in your site’s cartridge path. A duplicate ID will cause the cache to silently fail to initialize, with the only evidence being an error in the logs. The `expireAfterSeconds` sets a TTL for entries in that cache. If omitted, entries have no time-based expiration and persist until the next global cache clear event. 3 **. Register in `package.json`:** The platform needs to know where to find your definition file. Reference it in your cartridge’s `package.json` using the `caches` key. The path is relative to the `package.json` file itself. ```json { "caches": "./caches.json" } ``` 1. **Enable in Business Manager:**Finally, you must globally enable the custom cache feature. Navigate to**Administration > Operations > Custom Caches** and check the “Enable Caching” box. Disabling this will clear all custom caches on the instance. This page will also become your primary tool for monitoring cache health. ![Custom Caches screen in Business Manager.](/field-guide-to-custom-caches-in-sfcc/ods-custom-caches-business-manager-c30167212b_hu_6111ee9c98aa8a4.webp) Business Manager custom caches panel ### The Core API Arsenal: CacheMgr and Cache The script API for interacting with your defined caches is straightforward, revolving around two classes: `dw.system.CacheMgr` and `dw.system.Cache`. - `CacheMgr.getCache(cacheID)`: [This](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_CacheMgr.html#dw_system_CacheMgr_getCache_String_DetailAnchor) is your entry point. It retrieves the cache object that you defined in `caches.json`. - `cache.put(key, value)`: Directly [places](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_Cache.html#dw_system_Cache_put_String_Object_DetailAnchor) an object into the cache under a specific key, overwriting any existing entry. - `cache.get(key)`: Directly [retrieves](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_Cache.html#dw_system_Cache_get_String_DetailAnchor) an object from the cache for a given key. It returns `undefined` if the key is not found. - `cache.invalidate(key)`: Manually [removes](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_Cache.html#dw_system_Cache_invalidate_String_DetailAnchor) a single entry from the cache. While these methods are simple, using them directly is a beginner’s trap. A typical but flawed pattern is `if (!cache.get(key)) { cache.put(key, loadData()); }`. This code is not atomic. On a busy server, two concurrent requests could both evaluate the `if` condition as true, both execute the expensive `loadData()` function, and one will wastefully overwrite the other’s result. This is inefficient and can lead to race conditions. ### The “Get-or-Load” Pattern: The Only Way to Populate Your Cache There is a [better way](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_Cache.html#dw_system_Cache_get_String_Function_DetailAnchor). It is the (in my opinion) **only** acceptable way to read from and write to a custom cache: the `cache.get(key, loader)` method. This method combines the get and put operations into a single, atomic action on the application server. It attempts to retrieve the value for a key. If it’s a miss, it executes the `loader` callback function, places the function’s return value into the cache, and then returns it. If the `loader` function returns `undefined` (not `null), t`he failure is not cached. This keeps your logic clean and concise. (And hopefully, behind that black box, the concurrency conundrum has been taken care of 😇) Here is the implementation for fetching data from a third-party API: ```js var CacheMgr = require('dw/system/CacheMgr'); var MyHTTPService = require('~/cartridge/scripts/services/myHTTPService'); var Site = require('dw/system/Site'); /** * Retrieves data for a given API endpoint, utilizing a custom cache. * @param {string} apiEndpoint - The specific API endpoint to call. * @returns {Object|null} - A plain JavaScript object with the API data, or null on failure. */ function getApiData(apiEndpoint) { // Retrieve the cache defined in caches.json var apiCache = CacheMgr.getCache('ExternalRatingsAPI'); // Construct a robust, unique cache key var cacheKey = Site.current.ID + '_api_data_' + apiEndpoint; // Use the get-or-load pattern. var result = apiCache.get(cacheKey, function() { // This loader function only executes on a cache miss for this specific key. var service = MyHTTPService.getService(); var serviceResult = service.call({ endpoint: apiEndpoint }); // Check for a successful result before caching if (serviceResult.ok && serviceResult.object) { // IMPORTANT: Return a simple JS object, not the full service result. // This prevents caching large, complex API objects. try { return JSON.parse(serviceResult.object.text); } catch (e) { // Failed to parse, don't cache the error. return undefined; } } // Returning undefined prevents caching a failure. return undefined; }); return result; } ``` ## The Art of the Key: Your Cache’s True Identity Developers often obsess over the value being cached, but this is a strategic error. The value is just data; the **key is the entire strategy**. A poorly designed key will lead to cache collisions (serving wrong data), or cache misses (negating any performance benefit). An anti-pattern, such as adding a dynamic and irrelevant product position parameter to a product tile’s cache key, can lead to a near-zero hit rate, rendering the cache completely useless. ### The Anatomy of a Perfect Key A robust cache key is not just a string; it’s a self-documenting, collision-proof identifier. Every key you create should be: 1. **Unique:** It must uniquely identify a single piece of cacheable data. 2. **Predictable:** You must be able to deterministically reconstruct the exact same key whenever you need to access the data. 3. **Scoped:** It must contain all the context necessary to distinguish it from similar data for other sites, locales, or conditions. A highly effective pattern is to build keys from concatenated, delimited parts: `PURPOSE::SCOPE::IDENTIFIER::CONTEXT`. - **Bad Key:** `'12345'` (What is it? A product? A category? For which site?) - **Good Key:** `'product _tile _ data::RefArch_US::12345 _ blue::en_US'` This structure prevents a product cache from colliding with a content cache, ensures data for the US site doesn’t leak into the EU site, and makes debugging from logs infinitely easier because the key itself tells you exactly what it’s for. Always include `Site.current.ID` and the current locale for any site- or language-specific data. ### The Complexity of Excess While it might seem clever to make your cache key highly specific and unique, this can backfire by reducing the chances of cache hits. **Striking the right balance is key.** (pun intended) I’ve also seen situations where the effort spent retrieving extensive data from the database to craft the key ends up cancelling out the performance benefits of custom caching. After all, if generating the key takes longer than the cache saves, it’s time to rethink the approach. ## The Serialization Conundrum: Caching API Objects vs. POJOs **You must not cache raw SFCC API objects.** Never put a `dw.catalog.Product`, `dw.order.Order`, or `dw.catalog.ProductInventoryList` object directly into the cache. While the [documentation](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-custom-caches.html) ambiguously states that “tree-like object structures” can be stored, this is a siren song leading to disaster. These API objects are heavyweight, carry live database connections, are not truly serializable, and can easily blow past the 128KB per-entry size limit, causing silent write failures that are only visible in the logs. The only performant and safe approach is to map the data you need from the heavy API object into a lightweight **Plain Old JavaScript Object (**[POJO](https://en.wikipedia.org/wiki/Plain_old_Java_object)**)** or Data Transfer Object ([DTO](https://en.wikipedia.org/wiki/Data_transfer_object)) before caching it. ### Anti-Pattern: Caching the Full API Object ```js // DO NOT DO THIS var ProductMgr = require('dw/catalog/ProductMgr'); var productCache = CacheMgr.getCache('ProductData'); productCache.get('some-product-id', function () { var product = ProductMgr.getProduct('some-product-id'); return product; // Caching the entire, heavy dw.catalog.Product object }); ``` ### Correct Pattern: Caching a Lightweight POJO ```js // THIS IS THE CORRECT WAY var ProductMgr = require('dw/catalog/ProductMgr'); var productCache = CacheMgr.getCache('ProductData'); productCache.get('some-product-id', function () { var product = ProductMgr.getProduct('some-product-id'); if (!product) { // We store null in the cache return null; } // Create a lightweight POJO with only the data you need var productPOJO = { id: product.ID, name: product.name, shortDescription: product.shortDescription? product.shortDescription.markup : '', price: product.priceModel.price.value }; return productPOJO; // Cache the small, clean object }); ``` This approach creates smaller, faster, and safer cache entries. It decouples your cached data from the live object model and respects the platform’s limitations. The [release notes](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_custom_cache_w10671394_je.htm&language=en_US&type=5) even mention that custom caches are intended to return _immutable objects_, reinforcing that you should be working with copies of data, not live API instances. ## In the Trenches: Real-World Battle Plans With the theory and mechanics established, let’s apply them to the most common scenarios where custom caches provide the biggest performance wins. ### Use Case 1: Taming External API Latency This is the poster child for custom caches. Your site needs to display real-time shipping estimates, user-generated reviews, or social media feeds from a third-party service. Making a live HTTP call on every page load is a recipe for a slow, unreliable site. By wrapping the service call in the “get-or-load” pattern, you can cache the response for a few minutes, drastically reducing latency and insulating your site from temporary blips in the third-party service’s availability. Remember, there’s _[another option](/third-party-api-caching-in-commerce-cloud/)_ I mentioned in a previous article: using the ServiceRegistry for caching. ### Use Case 2: Caching Expensive Computations Some business logic is just plain expensive. The classic example is determining if a main product should display an “On Sale” banner by iterating through all of its variation products to check their promotion status. On a product grid page with 24 products, each with 10 variants, this could mean hundreds of object inspections just to render the page. This is a perfect candidate for a custom cache. Calculate the result once, store the simple boolean result in a cache with a key like`'main _promo_ status::' + mainPid`, and set a reasonable TTL (e.g., 15 minutes) to align with promotion update frequencies. Key! Depending on your configuration, consider including the site ID or locale in your key! ### Use Case 3: “Configuration as Code” Instead of fetching site-level configurations or feature switches directly from the database through Site Preferences or Custom Objects, you can load these configurations into a custom cache helper function that loads this data into a long-lived custom cache on the first request; subsequent requests will retrieve the configuration directly from memory. This approach significantly reduces the load on the database while providing lightning-fast access to configuration data. ## The Minefield: Warnings, Anti-Patterns, and How to Survive Now for the most crucial section of this guide. Understanding these pitfalls is what separates a developer who uses caches effectively from one who creates production incidents. ### The Great Myth: Cross-Server Invalidation Let this be stated as clearly as possible: **There is no reliable, built-in mechanism to invalidate a single custom cache key across all application servers in a production environment.** The `cache.invalidate(key)` method is a \_trap _. It is functionally useless for ensuring data consistency on a multi-server POD. It only clears the key on the \_ single application server that happens to execute the code_. The other 2, 5, or 10 servers in the instance will continue to happily serve the stale data until their TTL expires or a global event occurs. The only ways to reliably clear a custom cache across an entire instance are these “sledgehammer” approaches : - **Data Replication:** A full or partial data replication will clear all custom caches. - **Code Activation:** Activating a new code version clears all custom caches. - **Manual Invalidation:**A Business Manager user navigating to**Administration > Operations > Custom Caches** and clicking the “Clear” button for a specific cache (for each app server). This limitation has profound architectural implications. It means you **must design your caching strategy around time-based expiration (`expireAfterSeconds`)**. You have to accept and plan for a window of potential data staleness. Do not attempt to build a complex, event-driven invalidation system (e.g., trying to have a job invalidate a key). It is doomed to fail in a multi-server environment. ### Caching User-Specific Data A cardinal sin. Never put Personally Identifiable Information (PII) or any user-specific data in a global custom cache. It is a massive security vulnerability and functionally incorrect, as the data will be shared across all users on that server. Use `session.privacy` for user-specific data. ### The Rogue’s Gallery: Other Common Pitfalls - **Ignoring the 20MB Total Limit:** This is a hard limit for _all_ custom caches on a single application server. One misbehaving cache that stores massive objects can pollute the entire 20MB space, causing the eviction of other, well-behaved caches. - **Ignoring the 128KB Entry Limit:** Trying to `put` an object larger than 128KB will result in a “write failure” that is only visible in the Business Manager cache statistics and custom logs. It does not throw an exception, so your code will appear to work while the cache remains empty. - **Assuming Cache is Persistent:** It is transient, in-memory storage. It is not a database. A server restart, code deployment, or random eviction can wipe your data at any time. Your code must _always_ be able to function correctly on a cache miss. ## The Watchtower: Monitoring Your Cache’s Health You cannot manage what you do not measure. A “set it and forget it” approach to caching is irresponsible. You must actively monitor the health and performance of your caches. ### Reading the Tea Leaves: The Business Manager Custom Caches Page Your primary dashboard is located at **Administration > Operations > Custom Caches**. This page lists all registered caches and provides statistics for the last 15 minutes on the current application server. The key metrics to watch are: - **Hits / Total:** This is your hit ratio. For a frequently accessed cache, this number should be very high (ideally 95%+). A low hit ratio means your cache is ineffective. This could be due to poorly designed keys, a TTL that is too short, or constant cache clearing. - **Write Failures:** This number must be **zero**. A non-zero value is a critical alert. It almost certainly means you are violating the 128KB per-entry size limit, likely by trying to cache a full API object instead of a POJO. - **Clear Button:** The manual override. Use it when you need to force a refresh of a specific cache’s data across all application servers. ### A Debugging Workflow: From Dashboard to Code When you identify a performance problem, follow this systematic process to diagnose cache-related issues : 1. **Observe (Production):**Start in**Reports & Dashboards > Technical**. Sort by “Percentage of Processing Time” or “Average Response Time” to find your slowest controllers and remote includes. These are your top suspects. Note their cache hit ratios in the report. A low hit ratio on a slow controller is a huge red flag. 2. **Hypothesize (Business Manager):**Go to the**Custom Caches** page. Does the slow controller use a custom cache? Is that cache showing a low hit rate or, worse, write failures? This helps correlate the storefront performance issue with a specific cache’s health. 3. **Reproduce & Pinpoint (Development):**Switch to a development instance. Use the**Pipeline Profiler** to get a high-level timing breakdown of the suspect controller. This tool confirms which parts of the request are slow, but it does not show cached requests. To dig deeper into the code itself, use the 4. **Code Profiler**. Run the uncached controller and look for the specific script lines or API calls that consume the most execution time. This will tell you exactly what expensive operation needs to be wrapped in a cache call. ## Wielding the Cache with Confidence Custom Caches are not inherently good or bad. They are powerful. And like any powerful tool, they demand respect, understanding, and discipline. The path to mastery is not through memorising API calls, but through internalising a set of non-negotiable principles. 1. **Cache Data, Not HTML:** Use Custom Cache for application data, Page Cache for rendered output. 2. **Choose the Right Scope:** Understand the difference between `request`, `session`, and `cache`. Misuse is costly. 3. **The Key is the Strategy:** Be deliberate and systematic in how you name things. A good key is self-documenting and collision-proof. 4. **Embrace “Get-or-Load”:** The `cache.get(key, loader)` pattern is the only safe and atomic way to populate a cache. Use it. Always. 5. **Cache POJOs, Not API Objects:** Map heavy API objects to lightweight POJOs before caching to save memory and avoid errors. 6. **Accept the Invalidation Myth:** Granular, cross-server invalidation is not a feature. Design around TTL and embrace a small window of potential staleness. 7. **Monitor Relentlessly:** Use the Business Manager dashboards and profilers to keep a constant watch on your cache’s health. By adhering to these rules, you transform the custom cache from a source of unpredictable bugs into a reliable, high-performance asset. --- ## SLAS Session Sync in SFRA and SiteGenesis Canonical URL: https://rhino-inquisitor.com/slas-in-sfra-or-sitegenesis/ Markdown URL: https://rhino-inquisitor.com/slas-in-sfra-or-sitegenesis/index.md Content type: article Published: 2025-07-24T20:52:39Z Updated: 2025-07-25T06:41:00Z Summary: SLAS (Shopper Login And API Access Service) is one of the headless APIs made available by Salesforce. But how can we use it in SFRA? Categories: Salesforce Commerce Cloud, Technical Tags: api, headless, sfcc ## Key Takeaways - Explains what SLAS is and why hybrid storefronts originally relied on plugin_slas to bridge monolithic sessions with headless authentication - Details the operational costs of the old cartridge approach, including performance overhead, API quota consumption, and maintenance burden - Argues that native Hybrid Authentication is the strategic replacement for session sync in modern SFRA or SiteGenesis plus composable setups Headless APIs have been available in Salesforce B2C Commerce Cloud for some time through [OCAPI (Open Commerce API)](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/b2c-commerce-ocapi/get-started-with-ocapi.html). In 2020, a new set of APIs, known as the SCAPI (Salesforce Commerce API), was introduced. Within that new set of APIs, a subset was focused on giving developers complete control of the login process of customers, called [SLAS](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-login?meta=Summary) (Shopper Login And API Access Service). In February 2022, Salesforce also released a [cartridge](https://github.com/SalesforceCommerceCloud/plugin_slas) for SFRA, enabling easy incorporation of SLAS within your current setup. But let’s cut to the chase. The `plugin_slas` cartridge (which we will discuss later in the article) was a necessary bridge for its time, but it also introduced performance bottlenecks, API quota concerns, and maintenance headaches. With the release of native [Hybrid Authentication](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/hybrid-auth.html), Salesforce has fundamentally changed the game for hybrid SFRA/Composable storefronts. This guide is your in-depth exploration of the “why” and “how”—we’ll dissect the architectural shift and equip you with the strategic insights you need. ## What is SLAS ![Diagram showing the different steps of the SLAS authentication process](/slas-in-sfra-or-sitegenesis/slas-diagram-9890f180b6_hu_8397ec166f828dc8.webp) SLAS authentication flow But what is SLAS, anywho? It is a set of APIs that allows secure access to Commerce Cloud shopper APIs for headless applications. Some use-cases: - **Single Sign-On:** Allow your customers to use a single set of log-ins across multiple environments (Commerce Cloud vs. a Community Portal) - **Third-Party Identity Providers:** Use third-party services that support [OpenID](https://openid.net/) like Facebook or Google. ## Why use SLAS Looking at the above, you might think: “But can’t I already do these things with SFRA and SiteGenesis?” In a way, you’re right. These login types are already supported in the current system. However, they can’t be used across other applications, such as Endless Aisle, kiosks, or mobile apps, without additional development. You will need to create custom solutions for each case. SLAS is a headless API that can be used by all your channels, whether they are Commerce Cloud or not. ### Longer log-in time People familiar with Salesforce B2C Commerce Cloud know that the storefront logs you out after 30 minutes of inactivity. Many projects have requested a longer session, especially during checkout, as this can be particularly frustrating. Previously, extending this timeout wasn’t possible. Now, with SLAS, you can increase it up to 90 days! Yes, you read correctly—a significant three-month extension compared to previous options! ## The Old Guard: A Necessary Evil Called plugin\_slas To understand where we’re going, we have to respect where we’ve been. When Salesforce B2C Commerce Cloud began its push into the headless and composable world with the [PWA Kit](/sitegenesis-vs-sfra-vs-pwa/), a significant architectural gap emerged. The traditional monoliths, Storefront Reference Architecture (SFRA) and SiteGenesis, managed user sessions using a dwsid cookie. The new headless paradigm, however, operates on a completely different authentication mechanism: the Shopper Login and API Access Service (SLAS), which utilises JSON Web Tokens (JWTs). For any business looking to adopt a hybrid model—keeping parts of their site on SFRA while building new experiences with the PWA Kit—this created a jarring disconnect. How could a shopper’s session possibly persist across these two disparate worlds? ### The Problem It Solved: A Bridge Over Troubled Waters Salesforce’s answer, released in February 2022, was the `plugin_slas` cartridge. It was designed as a plug-and-play solution for SFRA that intercepted the standard login process. Instead of relying on the traditional `dw.system.Session` script API calls for authentication, the cartridge rerouted these flows through SLAS. This clever maneuver effectively “bridged” the two authentication systems, allowing a shopper to navigate from a PWA Kit page to an SFRA checkout page without losing their session or their basket. For its time, the cartridge was a critical enabler. It unlocked the possibility of hybrid deployments and introduced powerful SLAS features to the monolithic SFRA world, such as integration with third-party Identity Providers (IDPs) like Google and Facebook, as well as the much-requested ability to extend shopper login times from a paltry 30 minutes to a substantial 90 days. ### The Scars It Left: The True Cost of the Cartridge While the `plugin_slas` cartridge solved an immediate and pressing problem, it came at a significant technical cost. Developers on the front lines quickly discovered the operational friction and performance penalties baked into its design. - **The Performance Tax:** The cartridge introduced three to four remote API calls during login and registration. These weren’t mere internal functions; they involved network-heavy SCAPI and OCAPI calls used for session bridging. This design resulted in noticeable latency during the crucial authentication phase. Every login, registration, and session refresh experienced this delay, impacting user experience. - **The API Quota Black Hole:** This was perhaps the most challenging issue for development teams, especially when the quota limit was still 8 - this is now 16, luckily. B2C Commerce enforces strict API quotas that cap the number of API calls per storefront request. The plugin\_slas cartridge could consume four, and in some registration cases, even five API calls just to log in a user. Using nearly half of the API limit for authentication alone was a risky strategy. This heavily restricted other vital operations, such as retrieving product information, checking inventory, or applying promotions, all within the same request. It led to constant stress and compelled developers to create complex, fragile workarounds. **The Maintenance Quagmire:** As a cartridge, `plugin_slas` was yet another piece of critical code that teams had to install, configure, update, and regression test. When Salesforce released bug fixes or security patches for the cartridge, it required a full deployment cycle to get them into production. This added operational overhead and introduced another potential point of failure in the authentication path, a path that demands maximum stability and security. The cartridge was a tactical patch on a strategic problem, and its very architecture—an external add-on making remote calls back to the platform—was the root cause of its limitations. ## The New Sheriff in Town: Platform-Native Hybrid Authentication ![Classic robot labeled plugin_slas cartridge handing a key to modern robot labeled Hybrid Authentication on a path from SFRA town to futuristic city](/slas-in-sfra-or-sitegenesis/plugin-slas-to-hybrid-authentication-359f0381b0_hu_6af0565cf08dd111.webp) plugin\_slas to Hybrid Authentication handoff The transition to the future of authentication, as the classic “plugin\_slas cartridge” passes the key to newest “Hybrid Authentication.” Recognising the limitations of the cartridge-based approach, Salesforce went back to the drawing board and engineered a proper, strategic solution. Released with B2C Commerce version [25.3](https://developer.salesforce.com/docs/commerce/commerce-api/references/about-commerce-api/about.html#03112025), Hybrid Authentication is not merely an update; it is a fundamental architectural evolution. ### What is Hybrid Auth, Really? It’s Not Just a Cartridge-ectomy **Feature Support Matrix:** When migrating to Hybrid Auth, be sure to check the [Hybrid Auth Feature Support Matrix](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/hybrid-auth.html#hybrid-auth-feature-support-matrix) to ensure that all required features for your project are supported at this time. Hybrid Authentication is best understood as a **platform-level session synchronisation engine**. It completely replaces the `plugin_slas` cartridge by moving the entire logic for keeping the SFRA/SiteGenesis `dwsid` and the headless SLAS JWT in sync directly into the core B2C Commerce platform. This isn’t a patch or a workaround; it’s a native feature. The complex dance of bridging sessions is no longer the responsibility of a fragile, API-hungry cartridge but is now handled automatically and efficiently by the platform itself. ### The Promised Land: Core Benefits of Going Native For developers and architects, migrating to Hybrid Auth translates into tangible, immediate benefits that directly address the pain points of the past. - **Platform-Native Data Synchronisation:** The session bridging process is now an intrinsic part of the platform’s authentication flow. This means no more writing, debugging, or maintaining custom session bridging code. It simply works out of the box, managed and maintained by Salesforce. - **A Seamless Shopper Experience:** By eliminating the clunky, multi-call process of the old cartridge, the platform ensures that session state is synchronised far more reliably and with significantly less latency. The nightmare scenario of a shopper losing their session or basket when moving between a PWA Kit page and an SFRA page is effectively neutralised. This seamlessness extends beyond just the session, automatically synchronising Shopper Context data and “Do Not Track” (DNT) preferences between the two environments. - **Full Support for All Templates:** Hybrid Authentication is a first-class citizen for both SFRA and, crucially, the older SiteGenesis architecture. This provides a fully supported, productized, and stable path toward a composable future for all B2C Commerce customers, regardless of their current storefront template. ### Is The Promised Land Free of Danger As with any new feature or solution, early adoption often means less community support initially, and you may encounter unique issues as one of the first partners or customers. Therefore, it’s essential to review all available documentation and thoroughly test various scenarios in testing environments, such as a sandbox or development environment, before deploying to production. ## Hardening Your Security Posture for 2025 and Beyond The security landscape for web authentication is constantly evolving. The migration to Hybrid Auth presents a perfect opportunity to not only simplify your architecture but also to modernise your security posture and ensure compliance with the latest standards. ### The 90-Day Session: A Convenience or a Liability While this extended duration is highly convenient for users on trusted personal devices, such as mobile apps, it remains a significant security liability on shared or public computers. If a user authenticates on a library computer, their account and personal data could be exposed for up to three months. The power to configure this timeout lies within your SLAS client’s token policy. It is strongly recommended that development, security, and legal teams collaborate to define a session duration that strikes an appropriate balance between user convenience and risk. For most web-based storefronts, a much shorter duration, such as 1 to 7 days, is a more prudent and secure choice. ### Modern SLAS Security Mandates You Can’t Ignore Since the `plugin_slas` cartridge was first introduced, Salesforce has [rolled out several security enhancements](https://developer.salesforce.com/docs/commerce/commerce-api/references/about-commerce-api/about.html) that are now effectively mandatory. Failing to address them during your migration will result in a broken or insecure implementation. - **Enforcing Refresh Token Rotation:** This is a major change, aligning with the OAuth 2.1 security specification. For public clients, which include most PWA Kit storefronts, SLAS now **prohibits the reuse of a refresh token**. When an application uses a refresh token to get a new access token, the response will contain a _new_ refresh token. The application must store and use this new refresh token for subsequent refreshes. Attempting to reuse an old refresh token will result in a `400 'Invalid Refresh Token'` error. The `plugin_slas` cartridge had to be updated to version 7.4.1 to support this, and any custom headless frontend must be updated to handle this rotation logic. - **Stricter Realm Validation:** To enhance security and prevent misconfiguration, SCAPI requests now undergo stricter validation to ensure the realm ID in the request matches the assigned short code for that realm. A mismatch will result in a `404 Not Found` error. - **Choosing the Right Client: Public vs. Private:** The fundamental rule of OAuth 2.0 remains paramount. If your application cannot guarantee the confidentiality of a client secret (e.g., a client-side single-page application or a native mobile app), you **must** use a public client. If the secret can be securely stored on a server (e.g., in a traditional web app or a Backend-for-Frontend architecture), you should use a private client. Because the migration to Hybrid Auth requires touching authentication code on both the SFCC backend and the headless frontend, it is the ideal and necessary time to conduct a full security audit. The migration project’s scope must include updating your implementation to meet these new, stricter standards. ## Conclusion: Be the Rhino, Not the Dodo Migrating from the `plugin_slas` cartridge to native Hybrid Authentication is not just a simple version bump or a minor refactor; it is a strategic architectural upgrade. It’s an opportunity to pay down significant technical debt, reclaim lost performance, eliminate API quota anxiety, and dramatically simplify your hybrid architecture. This shift is a clear signal of Salesforce’s commitment to making the composable and hybrid developer experience more robust, stable, and platform-native. By embracing foundational platform features, such as Hybrid Authentication, over temporary, bolt-on cartridges, you are actively future-proofing your implementation and aligning with the platform’s strategic direction. Don’t let your hybrid architecture become a relic held together by legacy code. Be the rhino: charge head-first through the complexity and build on the stronger foundation the platform now provides. --- ## The Ultimate SFCC Guide to Finding Your POD Number Canonical URL: https://rhino-inquisitor.com/the-sfcc-guide-to-finding-pod-numbers/ Markdown URL: https://rhino-inquisitor.com/the-sfcc-guide-to-finding-pod-numbers/index.md Content type: article Published: 2025-07-21T05:05:51Z Updated: 2025-07-21T05:42:08Z Summary: Learn how to find your SFCC POD number, why it matters for troubleshooting, and where to verify it across tools and environments. Categories: Salesforce Commerce Cloud, Technical Tags: security, sfcc, technical ## Key Takeaways - Explains what an SFCC POD is and why knowing it matters for integrations, troubleshooting, maintenance awareness, and performance planning - Covers practical ways to identify the current POD through UI clues, official references, and support channels - Places POD discovery in the broader context of Salesforce infrastructure evolution and the shift toward Hyperforce As a Salesforce B2C Commerce Cloud developer, you operate within a sophisticated, multi-tenant cloud architecture. While Salesforce masterfully handles the underlying infrastructure, there are times when you need to peek behind the curtain. One of the most common—and often surprisingly elusive—pieces of information you’ll need is your instance’s **POD number**. Knowing your POD number isn’t just trivia; it’s a critical piece of operational intelligence. It’s the key to configuring firewalls, anticipating maintenance, troubleshooting effectively, and optimising performance. This guide is your definitive resource for uncovering that number. We’ll explore every method available, through clever UI tricks, so you can master your environment. ## What is an SFCC POD, and Why Should You Care Before we dive into the “how,” let’s establish the “[what](/the-salesforce-b2c-commerce-cloud-environment/)” and “why.” In the Salesforce B2C Commerce ecosystem, a **POD (Point of Delivery)** is not just a single server. It is a complete, self-contained infrastructure cluster hosting the multi-tenant Software as a Service (SaaS) application. Think of it as a group of hardware—including firewalls, load balancers, application servers, and storage systems—that multiple customers share. Salesforce manages this grid, continually adding new PODs and refurbishing existing ones to balance loads, enhance performance, and improve disaster recovery capabilities. This SaaS model is a significant advantage, enabling your team to focus on building exceptional storefronts instead of managing hardware. Salesforce also frequently performs “POD moves,” migrating entire customer realms to new hardware to ensure performance and reliability. By treating the POD as a transient, infrastructure-level detail rather than a permanent, customer-facing setting, Salesforce maintains the flexibility to manage the grid without requiring constant configuration changes on your end. With the transition to the public cloud, the entire concept of “POD” will undergo substantial changes. This means that for developers, finding the POD number is an act of reconnaissance. We must learn how to query the system’s current state. Here’s why this knowledge is indispensable: - **Firewall & Integration Configuration:** This is the most frequent reason you’ll need your POD number. When setting up integrations with third-party systems, such as payment gateways, Order Management Systems (OMS), or tax providers, their security policies often require you to allowlist the outbound IP addresses from your SFCC instances. These IP addresses are specific to the POD on which your realm resides. For a seamless transition during a potential POD move, it is best practice to allowlist the IPs for both your current POD and its designated Disaster Recovery (DR) POD at all times. (We’ll explain where to find those later) - **Understanding Maintenance Schedules:** Salesforce announces maintenance windows and incidents on its [Trust site](https://status.salesforce.com/) on a per-POD basis. Knowing your POD number is the only way to accurately anticipate downtime for your Primary Instance Group (PIG), allowing you to plan releases and testing cycles effectively. - **Troubleshooting & Support:** When diagnosing elusive connectivity issues, performance degradation, or other strange behaviour, knowing the POD is a crucial data point. It’s one of the first things you should check, and it’s vital information to include when opening a support case with Salesforce to expedite a resolution. - **Performance Optimisation:** In the modern era of composable storefronts, performance is paramount. For sites built with the PWA Kit and Managed Runtime, deploying your Progressive Web App (PWA) to a Managed Runtime region that is geographically close to your data’s POD is critical for minimising latency and delivering the fast page loads that customers expect. ### The Shift to Hyperforce: What It Means for PODs Salesforce is fundamentally changing its infrastructure by migrating B2C Commerce Cloud to **Hyperforce**, its next-generation platform built on [public cloud technology](https://www.salesforce.com/platform/public-cloud-infrastructure/). This strategic move away from traditional Salesforce-managed data centres allows for greater scalability, enhanced security, and improved performance by leveraging the global reach of public cloud providers. For anyone working with SFCC, understanding this transition is crucial, as it marks a significant evolution in how the platform is architected and managed. The core takeaway is that the classic concept of a static, identifiable **POD** is becoming a thing of the past for realms on Hyperforce. With the adoption of Hyperforce, the architecture is far more dynamic. Your SFCC instance is no longer tied to a single, fixed data centre or a specific POD number that can be easily identified through a URL or IP address lookup. This means that many of the clever methods currently used to pinpoint your POD will no longer be reliable once your realm is migrated. Instead of a predictable POD, your instance operates within a more fluid public cloud environment. ## The UI Sleuth: Finding Your POD with a Few Clicks For those times when you need a quick answer, this browser-based method is your best option. ### Method 1: The Custom Maintenance Page Trick This is a clever, indirect method that leverages the way Business Manager generates preview links. It’s highly reliable for determining the POD of your PIG instances (Development, Staging, Production). 1. Log in to the Business Manager of the instance you want to investigate. 2. Navigate to **Administration > Site Development > Custom Maintenance Pages**. 3. In the `Preview` section, you will see links for your various storefronts. If you don’t have a maintenance page uploaded, you must upload one first. You can download a template from this same page and create a simple `.zip` file to enable the preview links. 4. Locate the **(Production)** link. 5. **Do not click the link.** Instead, hover your mouse cursor over it. 6. Look at your browser’s status bar (usually in the bottom-left corner). It will display the destination URL, and within that URL, you will find the POD number. For example, the URL might look something like `https://pod185.production.demandware.net/...`, clearly indicating you are on POD 185. ### Method 2: The (lightning) PIG instance footer By far the **_easiest and quickest_** option to explain. Go to your staging, development, or production instance, log in, and finally look at the bottom right of any page to see the POD number in the footer! This is a feature of the new Lightning UI, not the classic UI. ### The Account Manager Prerequisite While you cannot find the POD number directly in Account Manager, it is the source for prerequisite information you will need for other methods, particularly when contacting support. Users with the `Account Administrator` role are the only ones who can access this information. To find your Realm and Organization IDs: 1. Log in to Account Manager at `https://account.demandware.com`. 2. Navigate to the **Organization** tab. 3. Open your organization and in the **Assigned Realms** section, you can find your 4-letter `Group ID` and the alphanumeric `Realm ID`. Keep this information handy. It’s essential for identifying your environment when interacting with Salesforce systems and support teams. This approach is primarily intended for individuals who need to work with Salesforce Support. ### Method 3: The Legacy Log Center URL (A History Lesson) This method is now largely historical ([migrated in 2023](https://help.salesforce.com/s/articleView?id=000394842&language=en_US&type=1)), but it remains important for context, especially if you work on older projects or encounter references to it in internal documentation. Before the 2023 migration to a centralised logging platform, each POD had a dedicated Log Center application. The URL format explicitly included the POD number: `https://logcenter-<POD-No.><Cylinder>-hippo.demandware.net/logcenter` The `<Cylinder>` value was also significant: `00` for a SIG (your sandboxes) and `01` for a PIG (Dev, Staging, Prod). The platform’s evolution toward a more abstracted, public cloud infrastructure is evident in this instance. The old Log Center URL was tied directly to a specific hardware group (`hippo.demandware.net`), reflecting a more rigid infrastructure. The new, centralised Log Centre decouples logging from the specific POD where an instance runs, using regional endpoints instead (e.g., AMER, EU, APAC). This shift is a classic pattern in modern cloud services, favouring centralised, scalable functions over hardware-specific endpoints. Although this legacy URL is no longer a reliable method for active discovery, understanding its history offers insight into the platform’s architectural evolution. ## The Official Channels: Guaranteed but Less Immediate ![Friendly rhino in 2D flat cartoon style walks toward an official building with a cloud logo, representing trusted official channels](/the-sfcc-guide-to-finding-pod-numbers/going-to-salesforce-official-channels-b9f405d5e0_hu_f0f02a6d062bd01e.webp) Figure 1: Use official Salesforce channels to find reliable POD information On the right path: Getting information from the official source. When you need an officially sanctioned answer or want to monitor the health of your environment, these are the channels to use. ### Method 4: Consulting Salesforce Support (The Ultimate Fallback) This is your most authoritative source. Salesforce Support can provide all realm information, including the current POD number. This is the best route to take when other methods are inconclusive or when you need an official record for compliance or audit purposes. To make the process efficient, open a support case and provide your `Organization ID` and `Realm ID` from the outset. Support will also be the primary source of information during a planned POD move. ### Using the Salesforce Trust Site (For Monitoring, Not Discovery) A common misconception is that the Salesforce Trust site can be used to find your POD (Point of Delivery) number. This is incorrect. The Trust site is where you go to check the status of a POD you _already know_. Once you’ve identified your POD number using one of the methods above, you can visit [https://status.salesforce.com/products/B2C\_Commerce\_Cloud](https://status.salesforce.com/products/B2C_Commerce_Cloud), find your POD in the list, and subscribe to notifications for maintenance and incidents. ### The Official POD Lists Salesforce maintains official knowledge base articles that list all PODs, their general locations (e.g., USA East - VA, Japan, …), their DR (Disaster Recovery) POD counterparts, and their outgoing IP addresses. These are invaluable reference documents. - **[AMER PODS](https://help.salesforce.com/s/articleView?id=000391456&language=en_US&type=1)** - [EMEA/APAC PODS](https://help.salesforce.com/s/articleView?id=000391425&type=1) You should use these lists in conjunction with the other discovery methods. For example, once the maintenance page URL indicates that you are on POD 126, you can consult the AMER list to find that its location is Virginia, its DR POD is 127, and its primary outbound IP address is `136.146.57.33`. ## Mastering Your Environment Knowing how to find your POD number is more than a technical trick. It’s a sign of a developer who understands the platform on a deeper level. It empowers you to configure integrations with confidence, anticipate operational changes, and troubleshoot with precision. --- ## Image-ine: Salesforce B2C Commerce Cloud DIS for Developers Canonical URL: https://rhino-inquisitor.com/image-ine-sfcc-dis-for-developers/ Markdown URL: https://rhino-inquisitor.com/image-ine-sfcc-dis-for-developers/index.md Content type: article Published: 2025-07-14T06:44:24Z Updated: 2025-07-16T14:27:13Z Summary: Guide to SFCC Dynamic Image Service, how its transformations and caching work, and when external image tooling is still the better fit. Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, sfcc, sfra, technical ## Key Takeaways - Explains what SFCC Dynamic Image Service does and how its transformation model works - Shows why DIS improves image flexibility, caching, and storefront performance across SFRA and PWA projects - Highlights platform limits and situations where external image tooling may still be a better fit In the wild, wild west of e-commerce, images aren’t just pretty pictures. They’re your silent “sales force” (☺️), your conversion catalysts, and your SEO superheroes. Shoddy, slow-loading visuals? That’s a one-way ticket to “bounce rate hell” and a brand image that screams, “We tried.” But fear not. Salesforce B2C Commerce Cloud’s [Dynamic Image Service](https://help.salesforce.com/s/articleView?language=da&id=cc.b2c_image_transformation_service.htm) (DIS) is here to help. Keep in mind that this built-in tool has several tricks up its sleeve, but might not always be the best fit for your project, so keep reading! **DIS and eCDN notice:** Effective image delivery in B2C commerce depends on two key components: the Dynamic Image Service (DIS), which handles real-time processing, and the eCDN, responsible for scalable delivery. When an image is first requested, DIS transforms it, and then the eCDN caches it for all future views. This article focuses on the DIS layer, the main driver of the image manipulation process. ## So, what exactly is DIS magic Imagine a world where you upload one glorious, high-resolution image, and then, _poof!_—it magically transforms into every size, shape, and format your storefront could ever dream of, all on the fly. That, my friends, is the core enchantment of Salesforce B2C Commerce Cloud’s Dynamic Imaging Service (DIS). It’s designed to eliminate the nightmare of manually resizing, cropping, and uploading numerous image variants for every product view. Instead of a digital assembly line of pre-processed images, DIS acts like a master chef. You provide it with the finest ingredients (your single, high-res source image), and when a customer’s browser requests a specific dish—say, a tiny thumbnail for a search result or a sprawling, detailed shot for a product page—DIS delivers it instantly. No waiting, no fuss - just the right-sized image, served hot and fresh. And you, the developer, are the culinary artist! DIS hands you a robust toolkit of transformation parameters, giving you pixel-level control. Want to resize? `scaleWidth` or `scaleHeight` are your pals. Need to snip out a specific detail? `cropX`, `cropY`, `cropWidth`, and `cropHeight` are your precision scissors (remember, you need all four for the magic to happen!). Fancy a different file type? `format` lets you switch between `gif`, `jp2`, `jpg`, `jpeg`, `jxr`, and `png` from a smorgasbord of source formats, including `tif` and `tiff`. Ever wanted to add a “SALE!” image badge to an image without using Photoshop? `imageX`, `imageY`, and `imageURI` are your go-to options for the overlay. _Though honestly, why not just use CSS for this, right?_ And for that perfect balance between crispness and speed, `quality` lets you fine-tune compression for JPG(1-100, default 80) and PNGs. Even pesky transparent backgrounds can be tamed with `bgcolor`, and metadata stripped with `strip`. **Pro tip:** DIS has a very specific “recipe” for applying these transformations. It’s not a free-for-all. The order is always: Image Format, then Image Crop, then Image Scale, then Image Overlay, and finally Image Quality. Understanding this sequence is key to avoiding “oops, that’s not what I wanted” moments. Want to know precisely how all of these things work? Have a look at the [official documentation](https://help.salesforce.com/s/articleView?id=cc.b2c_creating_image_transformation_urls.htm&type=5). ## Why You Should Be Best Friends with DIS ![Cartoon illustration of developer and cloud mascot shaking hands to symbolize seamless integration with DIS](/image-ine-sfcc-dis-for-developers/developer-and-dis-are-friends-scaled-e1752256621645-8ebda34ef5_hu_24eb23f21633c329.webp) Figure 1: Best Friends with DIS—Seamless Image Optimization For developers navigating the Salesforce B2C Commerce Cloud universe, DIS isn’t just a nice-to-have; it’s a game-changer that simplifies your life and turbocharges your storefront. **Kiss Manual Image Management Goodbye:** Seriously, who has time to create 10 different versions of the same product shot? With DIS, you upload one glorious, high-resolution image to Commerce Cloud, and DIS handles the rest, generating every size and format on demand. This means your creative and merchandising teams can focus on crafting stunning visuals, not on tedious, repetitive image grunt work. More creativity, less clicking! **Speed Demon & Responsive Rockstar:** In the e-commerce race, speed wins. DIS helps you cross the finish line first by serving up images that are _just right_ for every scenario. No oversized behemoths slow down your product pages, and no pixelated thumbnails ruin your search results. This precision means faster page loads, which directly translates into happier customers, improved SEO, and ultimately, more conversions. Plus, DIS is your built-in responsive design partner, ensuring your storefront looks sharp and loads lightning-fast on any device, from desktops to smartphones. As I’ve discussed in my blog post, [From Lag to Riches: A PWA Kit Developer’s Guide to Storefront Speed](/lag-to-riches-a-pwa-kit-developers-guide/), performance is paramount. **Flexibility That’ll Make You Giddy:** Ever had a designer suddenly decide to change the entire product grid layout? From four items at 150x150 pixels to three at 250x250? Without DIS, that’s a full-blown panic attack. With DIS? You tweak a few parameters in your templates, and _bam!_—new layout, perfectly sized images, no re-processing, no re-uploading, no re-assigning. Do you need a new promotional banner with a custom image size for a flash sale? Generate it instantly! (Ok…Ok, I might be a bit too optimistic here, some foresight and extra editor fields in Page Designer are needed for use-cases like this.) This adaptability is pure gold. And here’s the cherry on top: by using the official Script API for URL generation, your image URLs are future-proofed. Salesforce can change its internal plumbing all it wants; your code remains rock-solid, reducing technical debt and maintenance headaches. ```text URLUtils.imageURL( '//image.png', { scaleWidth: 100, format: 'jpg' } ); ``` **Caching Like a Boss (and CDN’s Best Friend):** DIS isn’t just dynamic; it’s smart. It caches (limited) transformations to deliver images at warp speed. If your Commerce Cloud instance is hooked up to a Content Delivery Network (newsflash: it is -> the [eCDN](/lets-go-live-ecdn/)), the CDN helps optimise caching as well (through TTL headers). When you update an image, there’s no need for manual cache invalidation thanks to a [technique](https://help.salesforce.com/s/articleView?id=cc.b2c_clear_ecdn_cache_task.htm&type=5) known as **URL fingerprinting/asset fingerprinting**. Instead of just replacing the old file, the platform creates a new URL for the updated image, often by adding a unique identifier (a “fingerprint”). Because the URL has changed, it forces browsers and the eCDN to download the new version as if it were a completely new file, bypassing the old cached version. ```text /dw/image/v2/BCQR_PRD/on/demandware.static/-/Sites-master/default/dw515e574c/4.jpg ``` Do you notice that _dw515e574c_? It represents the unique “cache” ID managed by SFCC to ensure cached images are served. When the image updates, a new ID is generated so the customer _always_ sees the latest version. **Not “always” always:** The system behind this is somewhat of a black box to us, so there could still be delays before an image updates and becomes visible to customers. ## DIS Tips, Tricks, and How to Avoid Digital Disasters To truly master DIS and avoid any “why isn’t this working?!” moments, keep these developer commandments in mind. ### Embrace the Script API (Seriously, Do It!) We can’t stress this enough: use the [`URLUtils`](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/index.html?target=class_dw_web_URLUtils.html) and [MediaFile](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/index.html?target=class_dw_content_MediaFile.html) Script API classes for generating your DIS URLs. It’s the official, validated, and future-proof way to do it. Here’s a little snippet to get you started: ```js var product = // obtain your product object var thumbnailImage = product.getImage('thumbnail', 0); if (thumbnailImage) { var imageUrl = thumbnailImage.getImageURL({ scaleWidth: 100, format: 'jpg', quality: 85 }); // The 'imageUrl' variable now holds the dynamically generated URL } ``` ### Know Your Image Limits (and How to Work Around Them) Even superheroes have weaknesses. DIS has a few, and knowing them is half the battle: - **Source Image Quality:** Always upload the largest, most beautiful, and highest-quality images you’ve. DIS is a master at shrinking and optimising, but it can’t create pixels out of thin air (It’s not an AI solution)! - **Size Matters (A Lot):** This is a big one. Images over 6MB in file size or larger than 3000x3000 pixels? DIS will politely decline to transform them and serve them up in their original, unoptimized glory. The first time you request an oversized image, you may encounter an error; however, subsequent requests typically proceed without issue. The takeaway? Keep your source images just under these limits (think 5.9MB or 2999x2999 pixels) to ensure DIS always works its magic. **Note:** [One source](https://help.salesforce.com/s/articleView?id=000391251&type=1) states a 10MB limit in the documentation, but to be cautious, always follow the 6MB limit. - **Transformation Timeout:** DIS has a 29-second deadline. If a transformation is super complex (especially on animated GIFs, where every frame needs processing), it might time out, giving you a dreaded 408 error. If you hit this, simplify your transformations or pre-process those extra-fancy assets. - **Cropping’s Four Musketeers:** If you’re cropping, remember `cropX`, `cropY`, `cropWidth`, and `cropHeight` are a package deal. All four must be present, or no cropping happens! ### Transform DIS PNG to JPG When it comes to image formats, transforming **PNG** files to **JPEG** using the SFCC Dynamic Image Service can be a **game-changer**, especially when you don’t need those transparent backgrounds. This simple trick alone can significantly **reduce file sizes**, leading to faster page loads and a smoother user experience. Here’s how you might implement this in a **controller:** ```js 'use strict'; var server = require('server'); var ProductMgr = require('dw/catalog/ProductMgr'); var URLUtils = require('dw/web/URLUtils'); /** * @name Product-ImageExample * @function * @memberof Product * @description A controller endpoint that demonstrates the correct way to generate * a transformed image URL for a given product. */ server.get('ProductImageExample', function (req, res, next) { // 1. Retrieve the product object using the Product Manager. // The product ID should be passed as a query string parameter, e.g.,?pid=12345 var product = ProductMgr.getProduct(req.querystring.pid); var imageUrl = ''; // Initialize a default empty URL. // 2. Check if the product and its image exist before proceeding. if (product) { // 3. Get the MediaFile object for the 'large' view type. var productImage = product.getImage('large', 0); if (productImage) { // 4. Generate the transformed URL using getImageURL() on the MediaFile object. // Here, we convert a PNG to a JPG and specify a white background. imageUrl = productImage.getImageURL({ 'format': 'jpg', 'bgcolor': 'ffffff' // Use a 6-digit hex code for the color. }).toString(); // Convert the URL object to a string for the template. } } // 5. Render a template, passing the generated URL to be used in an tag. res.render('product/productimage', { productImageURL: imageUrl }); // It is standard practice to call next() at the end of a middleware function. next(); }); // Export the controller module. module.exports = server.exports(); ``` ### General Image Zen for Speed and Quality DIS is powerful, but don’t forget the fundamentals of image optimisation: - **Responsive Images (`srcset` & `sizes`):** These [attributes](https://developer.salesforce.com/docs/commerce/salesforce-commerce/guide/b2b-d2c-comm-image-optim.html) are your best friends for letting browsers pick the perfect image resolution for a user’s device and viewport. Less data, faster loads! - **Prevent Layout Jumps (CLS):** Always specify the `width` and `height` attributes for your images. This reserves space, preventing annoying layout shifts that make your site feel janky and hurt your Core Web Vitals. - **Pre-Compress (Gently):** While DIS handles quality, a little pre-compression on your source images (especially removing unnecessary metadata) can reduce file size by up to 30% without compromising visual quality. - **Leverage the CDN:** DIS already plays nicely with Salesforce’s [Content Delivery Network](/lets-go-live-ecdn/). This means your images are cached and delivered from servers closer to your global audience, making them appear almost instantly. ### Troubleshooting: When Things Go Sideways - **“My image isn’t transforming!”** First suspect: file size or dimensions. Check those 6MB and 3000x3000 pixel limits. - **“408 Timeout Error!”** If you’re seeing this, especially with animated GIFs or huge images that undergo numerous transformations, you’re approaching the 29-second limit. Simplify or pre-process. - **General Sluggishness:** Remember, images are just one piece of the performance puzzle. If your storefront is still slow, look for other potential culprits, such as poorly optimised custom code, complex reports, or inefficient API calls. Regular code audits are your friend! ## When Not to Use It (Or When to Be Extra Careful) ![A cartoon illustration depicting a massive traffic jam of oversized, unoptimized images attempting to enter a cloud icon, which appears overwhelmed and unable to process the volume. The images are backed up on a road leading to the cloud, symbolizing a system bottleneck or overload.](/image-ine-sfcc-dis-for-developers/dis-traffic-jam-b798844f63_hu_8f219f0f085e31ba.webp) Image Overload: When Your Service Gets Jammed While DIS is a superhero, even superheroes have their kryptonite. There are a few scenarios where DIS might not be your go-to, or where you need to tread with extra caution: - **When Your Images Are Absolute Giants:** Remember those 6MB file sizes and 3000x3000 pixel dimension limits? If your source images consistently blow past these thresholds, DIS won’t transform them. Instead, they’ll be served in their original, unoptimized glory. This results in slower load times and a subpar user experience, particularly on mobile devices. For truly massive, high-fidelity assets (think ultra-high-res hero banners or interactive 360-degree product views that require large file sizes), you may need to consider specialised external image services or alternative hosting solutions that can handle and optimise such large files, or simply serve the original if the performance impact is minimal. - **For Super Complex, “Expensive” Transformations:** DIS has a 29-second timeout for transformations. If you’re trying to perform multiple, intricate operations on a very large image, or especially on animated GIFs (where every single frame needs processing), you may encounter this wall and receive a 408 timeout error. If your use case demands such complex, real-time transformations, you might need to pre-process these assets offline or explore dedicated, more powerful image processing platforms designed for extreme computational demands. - **When Images Aren’t Hosted on Commerce Cloud Digital:** DIS only works its magic on images that are stored within your Commerce Cloud Digital environment. If your images are hosted externally (e.g., on a third-party DAM or a different CDN not integrated with Commerce Cloud’s asset management), DIS won’t be able to touch them. In such cases, you’d rely on the capabilities of your external hosting solution for image optimisation. - **For Very Simple, Static Images with No Transformation Needs:** If you have a tiny, static icon or a simple logo that never changes size, format, or quality, and you don’t anticipate any future dynamic needs, the overhead of routing it through DIS might be overkill. While DIS is designed for flexibility, for truly unchanging, small, and already optimised assets, direct static hosting might be marginally simpler, though the benefits of DIS’s caching and CDN integration often outweigh this. However, given the “future-proofing” aspect, it’s generally still a good idea to use DIS for consistency. - **You Need More Modern Features:** If you’ve been in the SFCC space for some time, you’ve likely noticed that little has changed regarding image resizing and format support over the years, although formats like WebP are managed by the eCDN. For those seeking the newest formats like [AVIF](https://en.wikipedia.org/wiki/AVIF), you’ll need to look elsewhere at this time. **Note:** The WebP transformation is handled by the [eCDN](/lets-go-live-ecdn/), specifically through its configuration feature known as “the image Polish options,” rather than by the DIS. ![Fork-in-the-road illustration comparing DIS with third-party CDN and DAM options.](/image-ine-sfcc-dis-for-developers/sfcc-when-not-to-use-dis-8b8b9ec0b1_hu_c0a949de27d30e12.webp) Deciding between Salesforce's native DIS and external CDN/DAM solutions often comes down to specific project needs and existing infrastructure. ## Is it still useful for PWA Kit projects? (Spoiler: YES, and here’s why!) **Absolutely, unequivocally, 100% YES!** DIS isn’t just relevant for PWA Kit projects; it’s arguably _more_ crucial. Modern headless storefronts, like those built with PWA Kit, thrive on speed, flexibility, and that buttery-smooth, app-like user experience. Dynamic image transformation is practically a prerequisite for achieving that. ### Page Designer’s Best Friend & Product Image Powerhouse DIS integrates beautifully with Page Designer within PWA Kit. Page Designer, for the uninitiated, is Business Manager’s visual editor, which allows marketers to build dynamic, responsive pages without writing a single line of code (well, at least once all the components are developed 😇). Where do your product images live? In Commerce Cloud, of course! Which means DIS is the star player for serving them up. Page Designer components can then tap into DIS to display product images, content assets, or any other visual element, ensuring they’re perfectly optimised for whatever device your customer is using. ### The DynamicImage Component: Your PWA Kit Sidekick PWA Kit even has a dedicated [DynamicImage](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/32763402f434b6b931ddce986372c9f0a386ee89/packages/template-retail-react-app/app/components/dynamic-image/index.jsx#L23) component that makes integrating with DIS a breeze. This component is designed to handle image transformations by mapping an array of widths to the correct `sizes` and `srcset` attributes, simplifying responsive image strategies directly within your React components. ```jsx <DynamicImage src={`${heroImage.disBaseLink || heroImage.link}[?sw={width}&q=60]`} widths={{ base: '100vw', lg: heroImageMaxWidth }} imageProps={{ alt: heroImage.alt, loading: loadingStrategy }} /> ``` ## Official Documentation Links - **Salesforce B2C Commerce Dynamic Imaging Service Overview:** [https://help.salesforce.com/s/articleView?id=cc.b2c\_image\_transformation\_service.htm&language=en\_US&type=5](https://help.salesforce.com/s/articleView?id=cc.b2c_image_transformation_service.htm&language=en_US&type=5) - **PWA Kit Page Designer Integration:** [https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/page-designer.html](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/page-designer.html) - **MediaFile Script API:** [https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class\_dw\_content\_MediaFile.html](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_content_MediaFile.html) - **URLUtils Script API:** [https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class\_dw\_web\_URLUtils.html](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_web_URLUtils.html) --- ## AI Won't Replace Your SFCC Job, but AI Users Might Canonical URL: https://rhino-inquisitor.com/ai-wont-steal-your-sfcc-job-but-a-developer-using-ai-will/ Markdown URL: https://rhino-inquisitor.com/ai-wont-steal-your-sfcc-job-but-a-developer-using-ai-will/index.md Content type: article Published: 2025-06-30T17:46:53Z Updated: 2025-07-02T21:37:51Z Summary: A practical look at how AI changes Salesforce Commerce Cloud work, where it improves delivery, and why developer judgment still matters most. Categories: Community Tags: ai, ohana, sfcc ## Key Takeaways - Argues AI will reward developers who adapt rather than replace platform expertise outright - Shows how AI shifts developer value toward architecture, judgment, and collaboration - Recommends hands-on adoption of AI coding tools instead of waiting for the market to settle The Rhino Inquisitor — I went all “Rhino” up in this place, be prepared for some analogies 😇. ## The Elephant (or Rhino) in the Room: Staring Down the AI Hype **Let’s cut to the chase. The whispers in every virtual stand-up, the subtext of every tech keynote, the existential dread creeping into your late-night coding sessions—it all boils down to one question: Is Artificial Intelligence coming for your job? As a Salesforce Commerce Cloud developer, you’re standing at the intersection of a specialised, high-stakes platform and the most disruptive technological wave of our generation.** **_The anxiety is palpable, and it’s not unfounded._** But the job of the Rhino Inquisitor is to charge head-first through the fog of fear and hype to uncover the hard, practical truth. So here it is: No, AI is not going to make you obsolete. However, it will, unequivocally, and without mercy, render developers who refuse to adapt obsolete. The threat isn’t the algorithm. It’s atrophy. This isn’t some far-off future. The shift is already here. The 2024 [DORA](https://dora.dev/research/2024/) Report reveals that 76% of developers are already using AI-powered tools in their daily work. A GitHub survey from the same year found that a staggering 97% of developers have used generative AI platforms. **_This is no longer an experimental niche… It’s a rapidly adopted standard._** Businesses are (or will go) all-in, with 78% of organisations reporting AI usage in 2024, a massive jump from 55% the previous year. The data is clear: AI is being integrated into the software development lifecycle at a breathtaking pace, promising boosts in productivity, code quality, and even developer focus. However, the most dangerous misconception is that simply using AI to write code faster automatically translates to greater value. This brings us to a critical, non-obvious threat that developers must understand: the “Vacuum Hypothesis.” Introduced in the [DORA](https://dora.dev/research/2024/) Report, this concept tells us that the time developers save by using AI is often immediately absorbed by lower-value activities, such as endless meetings, bureaucratic red tape, and context-switching between trivial tasks. Consider this scenario: you use GitHub Copilot to generate a controller with helpers and its test class in 30 minutes, a task that previously took you 90. You’ve just saved an hour. But what happens to that hour? In many organisations, it evaporates into a vacuum of inefficiency. It’s consumed by an extra status update meeting, a flurry of low-priority Slack messages, or simply waiting for a manual, bottlenecked deployment process to inch forward. The micro-level productivity gain is completely nullified by macro-level organisational drag. This reveals a more profound truth. The most successful developers in this new era won’t just be the ones who master AI tools. They will be the ones who leverage the productivity gains from those tools to focus on high-value work that AI _cannot_ do: architecting complex, scalable systems, mentoring junior developers, collaborating with business stakeholders to solve the _right_ problems, and championing the process improvements needed to ensure that saved time is reinvested, not wasted. The challenge is as much about changing your organisation’s culture as it is about changing your own code editor. ## Déjà Vu All Over Again: A Brief History of Developer “Extinction Events” The fear that a new technology will render developers obsolete is a story as old as the profession itself (and not just the developer profession). Every major technological leap has been met with predictions of our imminent demise. Yet, each time, the opposite has happened. These “extinction events” were actually elevation events. They were moments of abstraction that, rather than replacing developers, freed them from tedious, low-level tasks to tackle problems of ever-increasing complexity and scale. AI is simply the latest, and most powerful, chapter in this long-running story. ### The Compiler Revolution (1950s-1960s): From Machine Whisperer to System Architect In the pioneering days of computing, programming was a tedious and painstaking process. Developers wrote instructions directly in binary or low-level assembly code, a process that required an intimate, almost mystical, understanding of the machine’s hardware. Then came the [compiler](https://en.wikipedia.org/wiki/History_of_compiler_construction#:~:text=The%20first%20practical%20compiler%20was,awarded%20anywhere%20in%20the%20world.). Tools like FORTRAN and COBOL introduced high-level languages that allowed programmers to write in a more human-readable syntax. The compiler would then automate the translation of this code into the ones and zeros the machine understood. The “threat” was obvious: what would happen to the programmers who had spent years mastering the intricacies of machine code? Would this automation make them redundant? The reality was transformative. The compiler abstracted away the hardware, freeing developers from the tyranny of the machine. This single innovation gave birth to the entire discipline of software engineering. Instead of focusing on managing memory registers, developers could now focus on designing algorithms, data structures, and complex application logic. The scope of what was possible exploded. The programmer evolved from a machine whisperer into a system architect. ### The IDE Takeover (1990s-2000s): From Code Typist to Supercharged Problem-Solver For decades, a developer’s toolkit was a fragmented collection of disparate programs: a text editor, a separate compiler, a command-line debugger, and build scripts. Then came the [Integrated Development Environment](https://en.wikipedia.org/wiki/Integrated_development_environment) (IDE), which bundled all these tools into a single, cohesive application. The “threat” was one of deskilling. With features like syntax highlighting, intelligent code completion, one-click debugging, and integrated version control, the IDE automated dozens of small, manual tasks that were once the hallmark of a seasoned developer’s workflow. Would this “dumbing down” of the process reduce the value of experienced programmers? The reality was a massive leap in productivity. Studies have shown that IDEs can boost developer productivity by up to 30% and significantly reduce debugging time. By abstracting the _workflow_, the IDE allowed developers to navigate and manage enormous, complex codebases with unprecedented ease. This efficiency gain was essential for building the large-scale, distributed web applications that came to define the internet age. The developer was no longer just a code typist; they were a supercharged problem-solver, wielding a powerful, integrated toolset to build more, faster. [![A timeline showing the evolution of the software developer role in four stages. It starts in the 1950s with a developer and a mainframe, progresses to the 1990s with an IDE on a desktop, then to the 2000s with Agile team collaboration, and ends today with a rhino developer augmented by AI robot assistants.](/ai-wont-steal-your-sfcc-job-but-a-developer-using-ai-will/img-0132-7f6e8b78a7_hu_415ebe22ba71c053.webp)](img-0132-7f6e8b78a7.jpeg) The developer role keeps changing, and AI is simply the next serious shift in that timeline. And it’s not just developers who experience this - every industry has its own story. ### The Agile & DevOps Movement (2000s-2010s): From Siloed Coder to Value Stream Owner The final major shift came not from a tool, but from a philosophy. The Waterfall model, with its rigid, sequential phases, was too slow and inflexible for the fast-paced world of web software. The [Agile](https://en.wikipedia.org/wiki/Agile_software_development) and [DevOps](https://en.wikipedia.org/wiki/DevOps) movements proposed a new way of working, emphasising iterative development, cross-functional collaboration, and the automation of the entire release pipeline through practices like Continuous Integration and Continuous Delivery (CI/CD). The “threat” was a blurring of roles. If deployment and operations were automated, what was the primary function of the developer? The reality was an expansion of responsibility. The developer’s role grew to encompass the entire software lifecycle, from ideation and coding to deployment, monitoring, and maintenance. They were no longer just writing code in a silo; they were owners of a value stream, responsible for delivering tangible business outcomes quickly and reliably. This history reveals an undeniable pattern: every wave of automation and abstraction has elevated the role of the developer, pushing them to operate at a higher level of strategic thinking. _However, there is one crucial difference this time around._ The pace of change is accelerating at an exponential rate. The transition from machine code to high-level languages took the better part of a decade. The widespread adoption of generative AI coding assistants has occurred in less than three years. This compressed timeline means that the ability to learn and adapt is no longer just a valuable trait; it is the single most critical survival skill. A “wait and see” approach is a guaranteed strategy for obsolescence. The skill gap between those who adopt these tools and those who do not will widen more rapidly than in any previous technological shift. ## The AI-Augmented Rhino: Your SFCC Developer Arsenal in 2025 Theory and history are comforting, but survival requires a practical arsenal. For the SFCC developer, this means moving beyond abstract notions of “using AI” and mastering a specific set of tools and techniques. This is how you transform from a potential victim of disruption into an AI-augmented rhino, capable of charging through complexity and delivering value at an unprecedented speed. ### Your AI Pair Programmer: Code Generation and Assistance The most immediate and tangible application of AI in our profession as developers, is in the act of writing code. These tools are not just fancy autocompletes… They are context-aware partners that can drastically reduce the time spent on repetitive, boilerplate tasks. [![A cartoon rhino developer at a desk looks thoughtfully at a screen with code. Next to the keyboard, an AI assistant designed like a yellow rubber duck projects a holographic code snippet, illustrating the concept of AI pair programming.](/ai-wont-steal-your-sfcc-job-but-a-developer-using-ai-will/ai-rubber-duck-43fdcc864a_hu_339ba405cb00e386.webp)](ai-rubber-duck-43fdcc864a.jpeg) The better framing is AI as a rubber duck with leverage, not as a replacement developer. The classic ‘rubber duck debugging’ method gets a serious upgrade. Explain your problem to an AI that can actually talk back with a solution. (Well, not always - always verify and don’t trust blindly) #### GitHub Copilot for SFCC GitHub Copilot is the de facto (ok … this is debatable - but replace GitHub Copilot with your favourite) standard for AI-assisted coding, and its capabilities extend deep into the ecosystem. Because it was trained on countless public GitHub repositories, it has a surprisingly robust understanding of React.js, OCAPI and SCAPI structures. The top dog? The fight for the top LLM and editor for coding is a battle that is still going on. #### ChatGPT and LLMs for Strategic Development Large Language Models (LLMs) like ChatGPT, Claude, and Gemini are your strategic partners. Using them effectively requires a new core competency: [**Prompt Engineering**](https://en.wikipedia.org/wiki/Prompt_engineering). This is the art and science of crafting instructions that guide the AI to produce the desired output. Key principles include: - **Role Prompting:** Begin your prompt by assigning a persona. “Act as a senior SFCC technical architect with 15 years of experience in high-volume retail.” This frames the AI’s knowledge and response style. - **Providing Context:** Give the AI all the relevant background. Paste in existing code, business requirements, or error messages. - **Using Delimiters:** Clearly separate your instructions from the data you provide using markers like three backticks or XML tags. Armed with these techniques, you can use LLMs for high-level tasks that go far beyond simple code generation : - **Architectural Brainstorming:** “I need to build a custom ‘Quick Order’ feature on an SFCC PWA Kit store. Provide me with three different technical approaches for comparison: the use of a custom SCAPI endpoint, a server-side SFCC controller with a traditional form post, and a standard SCAPI endpoint. Analyse the pros and cons of each regarding performance, scalability, and development effort.” - **Legacy Code Archaeology:** “Here is a legacy SFCC pipelet script from a SiteGenesis implementation. Explain what it does, identify its inputs and outputs, and highlight potential points of failure or performance bottlenecks.” - **Documentation on Demand:** “Generate a JSDoc comment block for the following JavaScript method, explaining its parameters, return value, and purpose.” - **Test Plan Generation:** “Create a comprehensive test plan for an e-commerce checkout flow. Include test cases for different payment methods (credit card, PayPal), shipping options, guest vs. registered user checkout, and handling of invalid coupon codes. Here is a description of all the steps in our checkout process: …” #### Your AI QA Engineer: Smarter Testing & Debugging Debugging and testing are two of the most time-consuming aspects of development, especially within the complex, interconnected systems of SFCC. AI is poised to revolutionise this space, acting as a tireless QA engineer that can catch issues before they ever reach a human reviewer. Tools like [Qodo AI](https://www.qodo.ai/) (formerly CodiumAI) can analyse your code and automatically generate meaningful unit tests, covering edge cases you might have missed. For debugging, [Workik](https://workik.com/) offers context-aware analysis, allowing you to provide error messages and relevant code snippets to receive intelligent, plain-English explanations of the root cause. More advanced tools even allow you to have a conversation with your debugger, asking questions like, “Why is this orderTotal variable null at this point in the execution?” _For an SFCC developer, this means a future where the soul-crushing task of writing boilerplate test data setup is automated._ _It means pasting a cryptic `NullPointerException` stack trace into an AI tool and getting back a precise explanation and a suggested fix._ _It means integrating security scanners like [SnykCode](https://snyk.io/product/snyk-code/) directly into your IDE to flag vulnerabilities in your custom code in real-time, long before a pull request is ever created._ This isn’t about replacing QA. It’s about augmenting it, freeing up human testers to focus on complex user experience issues and business logic validation. ## The Evolved Developer: More Than a Coder, a Creator The rise of AI marks a fundamental shift in the value proposition of a software developer. When the act of writing code—the “how”—is increasingly automated, the most valuable professionals will be those who have mastered the “why.” Your worth will be measured not by your typing speed, but by the quality of your thinking. [![A friendly cartoon rhino developer acts as a strategic leader, presenting an architecture plan on a large screen to a diverse group of business stakeholders. In the background, AI robot assistants implement the plan by coding at their desks.](/ai-wont-steal-your-sfcc-job-but-a-developer-using-ai-will/the-architect-mindset-as-a-developer-with-ai-c8033b7990_hu_d8d6e693b54af539.webp)](the-architect-mindset-as-a-developer-with-ai-c8033b7990.jpeg) The higher-value developer role is increasingly about direction, judgment, and trade-offs. The AI-augmented developer: Spending less time on the keyboard and more time translating business strategy into a technical vision that AI can execute. ### The Architect’s Mindset: Your Most Valuable Asset As AI dramatically lowers the barrier to implementation, the relative importance of high-quality system design, clear interface definitions, and robust architectural boundaries skyrockets. A poorly architected system, even if coded flawlessly and instantly by an AI, is still a poorly architected system. It will be brittle, difficult to maintain, and unable to scale. The SFCC developer of the future adds value long before the first line of AI-generated code is produced. Your expertise is no longer demonstrated by your ability to write a perfect `for` loop in ISML script. It is shown in your ability to analyse a business requirement and make critical architectural decisions. _Can this new requirement be leveraged using out-of-the-box features, or should we write a custom controller that utilises the existing SFRA framework?_ _Should this feature use custom objects or custom caches?_ _Is it a candidate for a third-party API integration? Or can the business goal be met more effectively by leveraging a native feature?_ This is the architect’s mindset. It’s about understanding the entire ecosystem—the platform’s capabilities, the available APIs, the business goals, and the long-term maintenance implications—and charting the most effective course. This strategic thinking is a uniquely human skill that AI, in its current form, cannot replicate. ### “Soft” Skills are Now Hard, Non-Negotiable Technical Skills For too long, the industry has dismissed crucial human-centric abilities as “soft skills,” implying they are secondary to “hard” technical prowess. In the age of AI, this distinction is becoming dangerously obsolete. These skills are now core, non-negotiable competencies for any effective technical professional. The logic is straightforward. AI can generate code, but that code can be buggy, inefficient, or insecure. This phenomenon has been dubbed “[implementation amnesia](https://www.linkedin.com/pulse/ai-dilemma-digital-amnesia-vijay-alagarsamy-u1wjc/),” where developers become dependent on AI suggestions without building a deep mental model of the systems they create. Therefore, a developer needs **Critical Thinking** to rigorously evaluate, question, and refine the AI’s output. This is not a soft skill - it is a fundamental technical requirement for ensuring quality. Similarly, AI requires clear, unambiguous, and context-rich instructions to generate valuable results. Therefore, a developer needs exceptional **Communication and Prompting** skills to translate complex business requirements into instructions the AI can understand and execute. This is a technical skill of the highest order. Ultimately, AI addresses technical issues, but businesses tackle human-centric problems. AI cannot understand a user’s frustration with a clunky checkout process or empathise with a merchant’s need to hit a quarterly sales target. Therefore, a developer needs **Collaboration and Empathy** to work with stakeholders, understand their actual needs, and define the correct problems for the AI to solve in the first place. These are not optional niceties… they are business-critical technical skills that determine whether a project succeeds or fails. ## Conclusion: Be the Rhino, Not the Dodo When is this all happening? Adoption has been rapid, but past experience shows that changing a business and its people is not straightforward. We still have time, and AI is far from perfect for code completion and other tasks, particularly those involving multiple steps. However, if this rate of growth continues, it won’t take decades for these changes to become apparent. It’s possible that AI might encounter a roadblock within the next two years - a plateau that the current technology can’t yet overcome - but I don’t have a crystal ball, do you? The history of software development is a history of abstraction. Each new layer, from the compiler to the IDE to the cloud, has eliminated a class of manual labour and, in doing so, has empowered developers to build things that were previously unimaginable. Generative AI is the most profound abstraction layer we have ever witnessed. It is abstracting the very act of writing code itself. **_This is not a cause for fear! It is a cause for action._** It does not make you obsolete; it gives you unprecedented leverage. The developers who face extinction are those who cling to the past, defining their value by the tasks that AI can now do better and faster. They are the dodos of this new era, unable to adapt to a changing environment. The developers who thrive will be the ones who are like rhinos. They will see AI not as a competitor, but as a powerful partner that frees them from the mundane and empowers them to focus on the work that truly matters: creativity, strategic thinking, complex problem-solving, and human collaboration. The future of the SFCC developer is not that of a simple coder, but of a technical leader, a system architect, and a strategic problem solver. The path forward is clear, but the window of opportunity to adapt is closing faster than ever before. Please don’t wait. The time for passive observation is over. - **Get your hands dirty, now.** If you don’t have a GitHub Copilot license, buy one this week. The $10 per month is the single best investment you can make in your career. (For your projects, customer/company code is a bit trickier on the legalities) - **Experiment relentlessly with prompts.** Take a piece of your own code and ask Copilot to refactor it, explain it, or find bugs in it. Learn the language of AI. The future isn’t something that happens _to_ you; it’s something that you create. It’s something you build. Stop worrying about being replaced. Pick up the tools, sharpen your horn, and become the AI-augmented rhino that leads the charge. [![A cartoon rhino developer, dressed as a conductor, leads an orchestra of small robots. The robots sit in sections and use laptops and data interfaces instead of musical instruments, symbolizing a developer orchestrating various AI tools.](/ai-wont-steal-your-sfcc-job-but-a-developer-using-ai-will/the-ai-composer-48f0e91bb0_hu_d92a8c24b955cefe.webp)](the-ai-composer-48f0e91bb0.jpeg) The real skill is learning to orchestrate tools, not trying to compete with them one by one. our new podium awaits. The AI-augmented developer orchestrates a powerful ensemble of tools, where strategy is the sheet music and business impact is the masterpiece. --- ## PWA Kit Developer's Guide to Storefront Speed Canonical URL: https://rhino-inquisitor.com/lag-to-riches-a-pwa-kit-developers-guide/ Markdown URL: https://rhino-inquisitor.com/lag-to-riches-a-pwa-kit-developers-guide/index.md Content type: article Published: 2025-06-23T17:00:05Z Updated: 2025-06-24T18:21:36Z Summary: Let's be honest: a slow e-commerce site is a silent killer of sales. In the world of B2C Commerce, every millisecond is money. Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, sfcc, technical ## Key Takeaways - Frames storefront speed as a conversion problem and explains the Core Web Vitals that matter most - Connects PWA Kit architecture to its distinct LCP, INP, caching, and JavaScript performance trade-offs - Provides a concrete optimization playbook for data fetching, images, caching, and third-party scripts Truth be told: a slow e-commerce site is a silent killer of sales. In the world of B2C Commerce, every millisecond is money. As a PWA Kit developer, you’re on the front lines of a battle where the prize is customer loyalty and the cost of defeat is a lost shopping cart. Today’s shoppers have zero patience for lag. They expect buttery-smooth, app-like experiences, and they’ll bounce if you don’t deliver. The numbers don’t lie. A one-second delay can reduce conversions by as much as 7%. But flip that around: a tiny 0.1-second improvement can boost conversion rates by a whopping 8% and keep shoppers from abandoning their carts. When you consider that more than half of mobile users will leave a site that takes over three seconds to load, the mission is crystal clear: speed is everything. So, how do we win this battle? We need the proper intel and the right weapons. That’s where Google’s Core Web Vitals (CWV) and the Chrome User Experience Report (CrUX) come in. These aren’t just abstract numbers; they’re a direct line into how _real people_ experience your storefront. This post is your new playbook. We’re going to break down why every millisecond matters and provide you with an actionable roadmap for taking the Composable Storefront to the next level. ## Step 1: Know Your Numbers - Getting Real with CrUX and Core Web Vitals Before you can optimise anything, you need to understand what you’re measuring. Let’s demystify the data that both your users and Google care about, starting with the difference between what happens in a controlled lab and what happens in the messy real world. ### Meet CrUX: Your Real-World Report Card The Chrome User Experience Report (CrUX) is a massive public dataset from Google, packed with real-world metrics from actual Chrome users. It’s the official source for Google’s Web Vitals program and the ultimate ground truth for how your site performs for your visitors. This data comes from Chrome users who have opted in to syncing their browsing history and have usage statistic reporting enabled, without a Sync passphrase. For your site to appear in the public dataset, it must be discoverable and have sufficient traffic to ensure that all data is anonymous and statistically significant. Here are two things you absolutely must know about CrUX: 1. **It’s a 28-Day Rolling Average:** CrUX data isn’t live. It’s a trailing 28-day snapshot of user experiences. This means when you push a brilliant performance fix, you won’t see its full impact on your CrUX scores for up to a month. It’s a marathon, not a sprint. 2. **It’s All About the 75th Percentile:** To evaluate your site’s performance, CrUX focuses on the 75th percentile. This means that to achieve a “Good” score for a metric, at least 75% of your (hard navigation) pageviews must have an experience that meets the “Good” mark. This focuses on the majority experience while ignoring the wild outliers on terrible connections. You can also slice and dice CrUX data, such as device type, providing a powerful lens into your specific audience’s experience. Hard vs Soft Navigation It is crucial for you to understand the distinction between a hard and a soft navigation, particularly for Single-Page Applications (SPAs), as this difference significantly impacts how performance is measured by the Chrome User Experience Report (CrUX). A hard navigation refers to the traditional, full loading of a webpage, which occurs when a user first lands on a site. In contrast, a soft navigation happens within an SPA when new content is loaded dynamically without a full page refresh, a process managed by JavaScript. **The critical point to recognize is that CrUX data, which is vital for assessing real-user web performance and Core Web Vitals, is primarily based on hard navigations. Consequently, for an SPA, only the initial page load is typically recorded by CrUX, while all subsequent, faster soft navigations are not taken into account, potentially leading to a skewed and incomplete understanding of the application’s overall user experience**. Here is an [official article on the matter](https://developer.chrome.com/docs/web-platform/soft-navigations-experiment)! ### Lab Coats vs. The Real World: Why Field Data is King This is one of the most common points of confusion, so let’s clarify it. **Field Data (The “What”)** is what we’ve been talking about—data from real users on their own devices and networks. It’s also known as Real User Monitoring (RUM), and CrUX is the largest public source of it. It captures the beautiful chaos of the real world: slow phones, spotty Wi-Fi, and everything in between. It tells you _what_ is happening. **Lab Data (The “Why”)** is what you get from a controlled test, like running Google Lighthouse. It simulates a specific device and network to provide you with a performance report. Lab data is your diagnostic tool. It helps you understand why you’re seeing the numbers in your field data. Here’s the million-dollar takeaway: **Google uses field data from CrUX for its page experience ranking signal, NOT your lab-based Lighthouse score.** Google wants to reward sites that are genuinely fast for real people, not just in a perfect lab setting. Your goal isn’t to achieve a 100% score on Lighthouse; your goal is to ensure at least 75% of your real users pass the Core Web Vitals thresholds. Lighthouse is the tool that helps you get there. ### The Big Three: LCP, INP, and CLS Explained ![Three-panel illustration showing Slow LCP with blank screen, High INP with frozen controls, High CLS with jumping content](/lag-to-riches-a-pwa-kit-developers-guide/core-web-vitals-visualised-e1750704059141-9cbbc8c421_hu_b51ff3b4686033bc.webp) A visual guide to Core Web Vital problems: How poor LCP, INP, and CLS create a frustrating user experience. Core Web Vitals are the metrics that matter most. They measure three key aspects of user experience: loading, interactivity, and visual stability. Largest Contentful Paint (LCP): Are We There Yet? - **What it is:** LCP measures how long it takes for the largest image or block of text to appear on the screen. It’s an excellent proxy for when a user _Feels_ like the page’s main content has loaded. - **The goal is to achieve a** “Good” result, which is defined as 2.5 seconds or less. “Poor” is over four seconds. - **Why it Matters for E-commerce:** A slow LCP means your customer is staring at a loading screen instead of your product. This initial frustration is a one-way ticket to a high bounce rate. Interaction to Next Paint (INP): Did That Click Do Anything? - **What it is:** INP measures how responsive your page is to user input. It tracks the delay for _all_ clicks, taps, and key presses during a visit and reports a single value representing the system’s overall responsiveness. A high INP is what users refer to as “janky” or “unresponsive.” It replaced First Input Delay (FID) in March 2024 because it’s a much better measure of the entire user journey. - **The Goal:** “Good” is 200 milliseconds or less. “Poor” is over 500ms. - **Why It Matters for E-commerce:** High INP Kills Conversions. When a user clicks “Add to Cart” and nothing happens instantly, they lose trust and get frustrated. This leads to “rage clicks” and, ultimately, abandoned carts. Cumulative Layout Shift (CLS): Stop Moving! - **What it is:** CLS measures how much your page’s content unexpectedly jumps around as it loads. It calculates a score based on how much things move and how far they move without the user doing anything - **The Goal:** “Good” is a score of 0.1 or less. “Poor” is over 0.25. - **Why it Matters for E-commerce:** Have you ever tried to click a button, only to have an ad load and push it down, making you click the wrong thing? That’s high CLS. It’s infuriating for users and makes your site feel broken and untrustworthy. ## Step 2: Understand Your Architecture - The PWA Kit’s Double-Edged Sword The Salesforce PWA Kit is engineered for speed, but its modern architecture creates two distinct performance battlegrounds. To win, you need to understand how to fight on both fronts. ### The First Impression: Server-Side Rendering (SSR) to the Rescue ![Two-panel cartoon: stressed user assembling JavaScript on left, happy user receiving complete webpage from heroic robot on right](/lag-to-riches-a-pwa-kit-developers-guide/server-side-rendering-client-side-e72f226d1b_hu_c0d6421b7abc15ed.webp) SSR improves perceived speed by delivering useful HTML before the whole app hydrates. When a user first lands on your site, the PWA Kit uses Server-Side Rendering (SSR) to make a great first impression. Here’s the play-by-play: 1. A user requests a page. 2. The request hits an Express.js app server running in the Salesforce Managed Runtime (MRT). 3. On the server, your React components are rendered into a complete HTML document, with all necessary data fetched directly from the Commerce APIs. 4. This fully baked HTML page is sent directly to the user’s browser. The huge win here is for your **Largest Contentful Paint (LCP)**. The browser gets a meaningful page instantly, instead of a blank screen and a giant JavaScript file it has to figure out. The **Managed Runtime** then takes this to the next level. It has a built-in Content Delivery Network (CDN) that can cache these server-rendered pages. If another user requests the same page, the CDN can serve the cached version instantly, completely bypassing the server. A cached SSR response is the fastest you can get, leading to stellar LCP and Time to First Byte (TTFB) scores. ### The Main Event: Hydration and Client-Side Interactivity Once that initial HTML page loads, the magic of **hydration** happens. The client-side JavaScript bundle downloads, runs, and brings the static HTML to life by attaching all the event handlers and state. From this moment on, your storefront is a Single-Page Application (SPA). All navigation and UI changes are handled by **Client-Side Rendering (CSR)**. When a user clicks a link, JavaScript takes over, fetches new data, and renders only the parts of the page that need to change, all without a full page reload. This is the “double-edged sword.” CSR provides that fluid, app-like feel, but it’s also where you’ll find the bottlenecks that hurt your **Interaction to Next Paint (INP)**. This creates a clear divide: LCP optimisation is a server-side game of efficient rendering and aggressive caching. INP optimisation is a client-side battle against bloated, inefficient JavaScript. You can have a fantastic LCP score but still have a terrible user experience due to high INP from clunky client-side code. PWA Kit projects are powerful React apps, and they can get JavaScript-heavy if you’re not careful. And the built-in libraries used, such as Chakra, are not making it easy for you to win this battle. You need to wear two hats: a backend/DevOps hat for the initial load, and a frontend performance specialist hat for everything after. ### The Usual Suspects: Common PWA Kit Performance Bottlenecks Every PWA Kit developer will eventually face these common performance villains. Here’s your wanted list: - **Bloated JavaScript Bundles:** The Retail React App template is excellent, but if you don’t manage it properly, your JS bundle can become huge. Every new feature adds weight, slowing down hydration and hurting INP. - **Clumsy Data Fetching:** Whether you’re using the old getProps or the new withReactQuery, you can still make mistakes. Fetching data sequentially instead of in parallel, grabbing significantly more data than needed, or re-fetching data on the client that the server has already provided are all common ways to slow down TTFB and LCP. - **Unruly Third-Party Scripts:** These are public enemy #1. Scripts for analytics, ads, A/B testing, and support chats can be performance nightmares. They block the main thread, tank your INP, and can even mess with your service worker caching. - **Poorly Built Custom Components:** A single custom React component that isn’t optimised for performance can significantly impact your INP. This typically occurs through expensive calculations on every render or by triggering a chain reaction of unnecessary re-renders in its children. - **Messed-Up Caching:** The MRT’s CDN is powerful, but it’s not magic. If you don’t set your Cache-Control headers correctly, fail to filter out unnecessary query parameters, or misconfigure your [API](https://developer.salesforce.com/docs/commerce/commerce-api/guide/server-side-web-tier-caching.html) proxies, you’ll experience a poor cache-hit ratio, and all the benefits of Server-Side Rendering (SSR) will be lost. ![Cartoon factory scene showing four performance bottlenecks: large truck blocking entrance, pipes slowly filling tank, complex machine for simple task, workers slipping on puddles](/lag-to-riches-a-pwa-kit-developers-guide/spa-performance-bottlenecks-6d6a3a6a62_hu_28d8f72694557498.webp) Large bundles and client-side churn are the usual reasons a PWA feels slow. ## Step 3: The Performance Playbook - Your Guide to a Faster Storefront Now that you know the what and the why, let’s get to the how. Here are the specific, actionable plays you can run to build a high-performance storefront. ### Master Your Data Fetching How you fetch data is critical for a fast LCP and a snappy experience. - **Use withReactQuery for New Projects:** If you’re on PWA Kit v3+, withReactQuery is your best friend. It utilises the popular React Query library to make fetching data on both the server and client a breeze. It smartly avoids re-fetching data on the client that the server has already retrieved, which means cleaner code and improved performance. - **Optimise getProps for Legacy Projects:** Stuck on an older project? No problem. Optimise your getProps calls: - **Be a Minimalist:** Return only the exact data your component needs for its initial render. Don’t send the whole API response object. This keeps your HTML payload small. - **Go Parallel:** If a page needs data from multiple APIs, use Promise.all to fire off those requests at the same time. This is way faster than waiting for them one by one. - **Handle Errors with Finesse:** For critical errors (such as a product not found), throw an HTTPError to display a proper error page. For non-critical stuff, pass an error flag in props so the component can handle it without crashing. - **Fetch Non-Essential Data on the Client:** Anything that’s not needed for the initial, above-the-fold view (such as reviews or related products) should be fetched on the client side within an useEffect hook. This enables your initial page to load faster, improving TTFB and LCP. ### Whip Your JavaScript and Components into Shape Your client-side React code is the most significant factor for INP. Time to optimise. - **Split Your Code:** The PWA Kit is already set up for code splitting with Webpack, so use it! Load your page-level components dynamically with the [loadable](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/970a3343ba05b321f66ae62192172ea3a42380a7/packages/template-retail-react-app/app/routes.jsx#L16) utility. This means the code for the product detail page is only downloaded when a user visits it, thereby shrinking your initial bundle size. - **Lazy Load Below-the-Fold:** For heavy components that are “below the fold” or in modals, use lazy loading. - **Stop Wasting Renders:** Unnecessary re-renders are a top cause of poor INP. Use React’s memoisation hooks like a pro: - **React.memo:** Wrap components in React.memo to stop them from re-rendering if their props haven’t changed. Perfect for simple, presentational components. - **useCallback:** When you pass functions as props to memoised children, wrap them in useCallback. This maintains the function’s reference stability, preventing the child from re-rendering unnecessarily. - **useMemo:** Use useMemo for expensive calculations. This caches the result so it’s not recalculated on every single render. - **Be Smart with State:** The Context API is great, but be careful. Any update to a context re-renders _all_ components that use it. For complex states, break your contexts into smaller, logical pieces (like a UserContext and a CartContext) to keep re-renders contained. ### Become a Caching Ninja with Managed Runtime Getting your CDN cache hit ratio as high as possible is the single most effective way to boost LCP for most of your users. - **Set Granular Cache-Control Headers:** - **Per-Page:** Inside a page’s getProps function, you can set a custom cache time. A static “About Us” page can be cached for days (res.set(‘Cache-Control’, ‘public, max-age=86400’)), while a product page might be cached for 15-30 minutes. - **Use stale-while-revalidate:** This header is pure magic. Cache-Control: s-maxage=600, stale-while-revalidate=3600 tells the CDN to serve a cached version for 10 minutes. If a request comes in after that, it serves the _stale_ content instantly (so the user gets a fast response) and then fetches a fresh version in the background. It’s the perfect balance of speed and freshness. - **Build Cache-Friendly Components:** To be [cached](/caching-in-the-sfcc-composable-storefront/), your server-rendered HTML needs to be generic for all users. Any personalised content (like the user’s name or cart count) must _only_ be rendered on the client. A simple trick is to wrap it in a check: {typeof window!== ‘undefined’ && `<MyPersonalizedComponent />`}. This ensures it only renders in the browser. - **Filter Useless Query Parameters:** Marketing URLs often contain “unnecessary” parameters, such as gclid and utm\_tags, which make every URL unique and prevent your cache from being effective. Edit the [processRequest](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/maximizing-your-cache-hit-ratio.html#filter-query-strings) function in app/request-processor.js to strip these parameters _before_ checking the cache. This allows thousands of different URLs to access the same cached page. - **Cache Your APIs:** By default, proxied requests aren’t cached by the CDN. This setting lets you use proxy requests in your code without worrying about accidentally caching responses. If you want a proxied request to be cached by the CDN, simply change the path prefix from proxy to caching. Proxy Caching Caching proxies aren’t suitable for use with the B2C Commerce API. Instead use its Server-Side Web-Tier Caching feature. ### Tame the Third-Party Script Beast ![A cartoon developer is taming a large 'beast' made of code and tangled wires. The developer is putting a collar labeled 'async' and holding a leash labeled 'defer' on the beast, while corralling other parts of it towards a pen labeled 'Lazy Load Zone'.](/lag-to-riches-a-pwa-kit-developers-guide/taming-the-third-party-script-beast-8cac515268_hu_85f7408a07713acb.webp) Taming the Third-Party Script Beast: A visual guide to managing external scripts for better web performance. Third-party scripts are performance killers. You need to control them. - **Audit and Justify:** Open Chrome DevTools and look at the Network panel. Make a list of every third-party script. For each one, ask: “Do we need this?” If the value doesn’t outweigh the performance cost, eliminate it. - **Load Asynchronously:** Never, ever load a third-party script synchronously. Always use the async or defer attribute. Async lets it download without blocking the page, and defer makes sure it only runs after the page has finished parsing. - **Lazy Load Widgets:** For things like chat widgets or social media buttons, don’t load them initially. Use JavaScript to load the script only when the user scrolls near it or clicks a placeholder. - **Use a Consent Management Platform (CMP):** A good CMP integrated with Google Tag Manager (GTM) is a must-have. It stops marketing and ad tags from loading until the user gives consent. This is great for both privacy and performance. - **Check Your Service Worker:** Your PWA’s service worker might block requests to domains that aren’t on its whitelist. When adding a new third-party script, ensure its domain is [configured](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/970a3343ba05b321f66ae62192172ea3a42380a7/packages/pwa-kit-runtime/src/utils/middleware/security.js#L28) correctly in your service worker to prevent blocking. ### Create Bulletproof, Lightning-Fast Images Images are usually the heaviest part of a page. Optimising them is non-negotiable. - **Serve Responsive Images:** Use the `<picture>` element or srcset and sizes attributes on your `<img>` tags. This allows the browser to select the perfect-sized image for the device, so a phone doesn’t have to download a massive desktop image. - **Use Modern Formats:** Use WebP format for images whenever possible. It provides significantly better compression than JPEG or PNG, often cutting file size by 25-35% without noticeable quality loss. Cloudflare only supports WebP. If you use a third-party image provider, check what’s available, as there are now more modern options, including AVIF. - **Compress, Compress, Compress:** Use an image optimisation service or build tools to compress your images. A JPEG quality of 85 is usually a great sweet spot. - **Prevent Layout Shift with Dimensions:** This is a super-easy and effective fix for CLS. Always add width and height attributes to your `<img>` and `<video>` tags. This allows the browser to reserve the right amount of space before the media loads, preventing the annoying content jump. - **Lazy Load Offscreen Images:** For any image that’s not in the initial viewport, add the native loading=“lazy” attribute. This instructs the browser to delay loading those images until the user scrolls down to them, which significantly improves performance. ## Step 4: Make it a Habit - Monitoring, Debugging, and Continuous Improvement Performance isn’t a one-and-done task. It’s a discipline. You need a solid workflow to monitor, debug, and prevent problems from creeping back in. ### Your Performance-Sleuthing Toolkit You have a powerful set of free tools to become a performance detective. - **PageSpeed Insights (PSI):** This is your starting point. The top section, “Discover what your real users are experiencing,” is your CrUX field data—your final report card. The bottom section, “Diagnose performance issues,” is your lab data from Lighthouse. Use its “Opportunities” and “Diagnostics” to find the technical fixes you need to improve your field data scores. - **Google Lighthouse:** Running Lighthouse from Chrome DevTools provides the most detailed results. Dig into the recommendations to find render-blocking resources, massive network payloads, and unused JavaScript. The “Progressive Web App” audit is also crucial for making sure your service worker and manifest are set up correctly. - **Chrome DevTools:** - **Performance Panel:** This is your primary tool for identifying INP issues. Record a page load or interaction to get a “flame chart” of everything the main thread is doing. Look for long tasks (marked with a red triangle) to find the exact JavaScript functions that are causing lag. - **Network Panel:** Use this to inspect all network requests. Check your Cache-Control headers, analyse asset sizes, and use “Request blocking” to temporarily disable third-party scripts to see how much damage they’re doing. - **Application Panel:** This is your PWA command centre. Inspect your manifest, check your service worker’s status, clear caches, and simulate being offline to test your app’s reliability. | Symptom / Poor Metric | Likely PWA Kit Cause(s) | Recommended Diagnostic Tool(s) | Actionable Solution(s) | | --- | --- | --- | --- | | **Poor LCP on Product Detail Page** | 1\. Large, unoptimized hero image. 2. Slow, sequential API calls in getProps/useQuery during SSR. 3. Low CDN cache hit ratio. | 1\. PageSpeed Insights to identify the LCP element. 2. ?\_\_ server\_timing=true to check ssr:fetch-strategies time. 3. MRT logs and CDN analytics. | 1\. Compress hero image, serve in WebP format, use srcset. 2. Refactor data fetching to use Promise.all or a single aggregated API call. 3. Set longer Cache-Control headers. | | **Poor INP on Product Listing Page** | 1\. Long JavaScript task during client-side hydration. 2. Excessive re-renders when applying filters. 3. A blocking third-party analytics script. | 1\. DevTools Performance Panel to identify long tasks. 2. React DevTools Profiler to visualize component renders. 3. DevTools Network Panel to block the script and re-test. | 1\. Code-split the PLP’s JavaScript. 2. Use React.memo, useCallback, and useMemo on filter components. 3. Defer or lazy-load the third-party script. | | **High CLS on Homepage** | 1\. Images loading without width and height attributes. 2. A cookie consent banner or ad injected dynamically. 3. Web fonts causing a flash of unstyled text (FOUT). | 1\. Lighthouse audit to identify elements causing shifts. 2. DevTools Performance Panel with “Screenshots” enabled to see the shifts happen. | 1\. Add explicit width and height to all `<img>` tags. 2. Reserve space for the banner/ad with CSS. 3. Preload key fonts using `<link rel="preload">`. | ### PWA Kit-Specific Debugging Tricks The PWA Kit has some built-in secret weapons for debugging. - **The \_\_ server\_timing Parameter:** Add ?\_\_ server\_timing=true to any URL in your dev environment. You’ll get a Server-Timing header in the response that breaks down exactly how long each part of the SSR process took. It’s perfect for figuring out if a slow response is because of a slow API or a heavy React component. - **The ?\_\_ server\_only Parameter:** Use this parameter to see the pure, server-rendered version of a page without any client-side JavaScript. It’s great for seeing what search engines see and for spotting layout shifts between the server and client versions. - **Managed Runtime Log Center:** In production, the Log Center is your go-to for troubleshooting. You can search and filter logs from your app server to diagnose server-side errors and performance issues that only show up in the wild. ## Wrapping Up: Your Journey to a High-Performance Storefront Building a blazingly fast storefront with the Salesforce PWA Kit isn’t about finding one magic trick. It’s a discipline. It requires understanding what users care about, knowing your architecture’s strengths and weaknesses, and committing to a cycle of measuring, optimising, and monitoring. In the cutthroat world of B2C commerce, that’s not just a nice-to-have—it’s the ultimate competitive advantage that drives real revenue. --- ## Mastering Sitemaps in Salesforce B2C Commerce: A Developer’s Guide Canonical URL: https://rhino-inquisitor.com/mastering-sitemaps-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/mastering-sitemaps-in-sfcc/index.md Content type: article Published: 2025-06-16T07:30:19Z Updated: 2025-06-24T18:22:38Z Summary: Learn how sitemaps work in Salesforce B2C Commerce Cloud, how to configure them correctly, and what developers should monitor for SEO. Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, sfcc, sfra, technical ## Key Takeaways - Explains how SFCC sitemap generation works, including index files, settings, scheduling, and hreflang support - Covers both classic job-based and modern SCAPI-based approaches for adding custom sitemap files - Shows how headless storefronts can combine backend-generated catalog sitemaps with frontend-only route coverage Let’s be honest, as developers, “SEO” can sometimes feel like a four-letter word handed down from the marketing team. But what if I told you that one of the most critical SEO tools, the sitemap, is actually a fascinating piece of platform architecture you can control, automate, and even extend with code? In Salesforce B2C Commerce Cloud (SFCC), the sitemap serves a purpose beyond simply listing links. It is a robust and scalable system that communicates to search engines precisely what content exists on your site and its level of importance. Properly configuring your sitemap results in faster indexing, improved visibility, and greater satisfaction for your marketing team. If done incorrectly, however, it could render your newly launched products invisible to search engines like Google, as well as tools such as ChatGPT and Google Gemini. This guide will walk you through everything you need to know, from leveraging the powerful out-of-the-box tools to writing custom integrations and mastering sitemaps in a headless PWA Kit world. ## The “Easy Button”: The Built-in Sitemap Generator Think of the standard SFCC sitemap [generator](https://help.salesforce.com/s/articleView?id=cc.b2c_sitemap_topology.htm&language=de&type=5) as the “easy button” that handles 80% of the work for you. For massive e-commerce sites with millions of URLs, this is a lifesaver. At its core, the platform cleverly sidesteps search engine limitations, like the 50,000 URL or 10MB file size cap, by creating a two-tiered system. It generates a main sitemap\_index.xml file, which is the only URL you need to give to Google. This index file then points to a series of child sitemaps (sitemap\_0.xml, sitemap\_1.xml, etc.) that contain the actual URLs. You control all of this from the Business Manager: Merchant Tools > SEO > Sitemaps. ### Your Control Panel: The Settings Tab ![Sitemap settings panel in Salesforce B2C Commerce Business Manager](/mastering-sitemaps-in-sfcc/sitemap-business-manager-sfcc-1e208116dd_hu_8105d34658147e0a.webp) The Sitemap Settings in the Business Manager The Settings tab is your main control panel. Here’s what you, as a developer, need to care about 4: - **Content Inclusion:** You can choose exactly what gets included: products, categories, content assets, and even product images. - **Priority & Change Frequency:** These settings are direct hints to search engine crawlers. Priority (a scale of 0.1 to 1.0) suggests a URL’s importance relative to other pages on your site. Change Frequency (from always to never) suggests how often a page’s content is updated. - **Product Rules:** You can get granular, choosing to include only available products, available and orderable products, or all products. This directly ties into your inventory and data strategy. - **hreflang for Multi-Locale Sites (Alternate URLs):** If you manage a site with multiple languages or regions, enabling Include alternate URLs (hreflang) is a huge win. It automatically adds the necessary tags to tell search engines about the different versions of a page, a task that can be a manual pain on other platforms. ### The Golden Rule of Scheduling ![Job tab for scheduling sitemap generation in Business Manager](/mastering-sitemaps-in-sfcc/sitemap-business-manager-job-13ba1762a2_hu_c5241b99a2dd0f47.webp) Sitemap job scheduling tab You can run the sitemap generation manually or, more practically, schedule it as a recurring job from the Job tab. Here is the single most important operational detail: Always schedule the sitemap job to run ****after**** your daily data replication from the staging instance. If you run it before, all the new products and content from that day’s replication will be missing from the sitemap, rendering it stale the moment it’s created. ## Going Custom: When the Built-in Isn’t Enough ![Custom tab in Sitemap settings within Business Manager](/mastering-sitemaps-in-sfcc/sitemap-business-manager-custom-sitemaps-sfcc-2fdf912121_hu_1142ff92c1a5d617.webp) Custom Sitemaps lets teams add external or supplemental sitemap sources. What happens when you have content that doesn’t live in SFCC? Maybe you have a WordPress blog, an external reviews provider, or a separate forum. You need to get those URLs into your site’s sitemap index. SFCC gives you two powerful paths to do this. ### Path 1: The Classic Job Step (The Batch Approach) The traditional method involves building a custom job step within a cartridge. This is ideal for batch-oriented processes, such as pulling a sitemap file from an SFTP server on a nightly basis. Your script would use the [dw.sitemap.SitemapMgr](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_sitemap_SitemapMgr.html) script API. The key method is SitemapMgr.addCustomSitemapFile(hostName, file), which takes a file your script has fetched and places it in the correct directory to be picked up by the main sitemap generation job. This requires some classic SFCC development: writing the script and defining the job step in a [steptypes.json](/mastering-chunk-oriented-job-steps-in-salesforce-b2c-commerce-cloud/) or steptypes.xml file. ### Path 2: The Modern SCAPI Endpoint (The Real-Time Approach) For a more modern, API-first architecture, consider using the Salesforce Commerce API (SCAPI). The Shopper SEO API provides the [uploadCustomSitemapAndTriggerSitemapGeneration](https://developer.salesforce.com/docs/commerce/commerce-api/references/seo?meta=uploadCustomSitemapAndTriggerSitemapGeneration) endpoint. This is a PUT request that enables a trusted external system to upload a custom sitemap file directly to SFCC and initiate the generation process asynchronously. This is the ideal solution for event-driven systems. For example, a headless CMS could use a webhook to call this endpoint the instant a new article is published, getting that URL into the sitemap almost immediately. > **Time to run** — Remember that the generation part won’t be complete in just a few seconds. Run your POC to determine how long it takes to process, allowing you to make informed decisions about your architecture. ## Choices… choices | _Integration Method_ | _Best For_ | _Mechanism_ | _Vibe_ | | --- | --- | --- | --- | | **Manual Upload** | One-offs, testing | UI in Business Manager | Quick & Dirty | | **Script API Job** | Batch processes (e.g., nightly sync) | Custom job step using dw.sitemap.SitemapMgr | Classic & Reliable | | **SCAPI Endpoint** | Real-time, event-driven integrations | PUT request to the Shopper SEO API | Modern & Agile | ## Sitemaps in the Headless Universe: PWA Kit Edition Going headless with the Composable Storefront (PWA Kit) changes the game, but the sitemap strategy remains firmly [rooted in the backend](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/create-a-sitemap.html)—and for good reason. The SFCC backend is the system of record for the entire product catalog. Forcing the PWA Kit frontend to generate the sitemap would require an API call nightmare to fetch all that data. Instead, you use the backend’s power and bridge the gap. ### The Standard Headless Playbook 1. **Configure the Hostname Alias:** This is the most critical step. In Business Manager (Merchant Tools > SEO > Aliases), you must create an alias that exactly matches your PWA Kit’s live domain, for example `www.your-pwa.com`. This ensures the backend generates URLs with the correct domain. 2. **Generate in Business Manager:** Use the standard job you’ve already configured. 3. **Update robots.txt:** In your PWA Kit project’s code, add the Sitemap directive to your robots.txt file, pointing to [your sitemap index URL](https://www.your-pwa.com/sitemap_index.xml). 4. **Proxy the Request:** Your PWA Kit app needs to handle requests for the sitemap. You can add a rule to your server-side rendering logic (often in app/ssr.js) to proxy requests for /sitemap\_index.xml and its children to the SFCC backend where the files actually live. Or use the [eCDN for this job!](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/ecdn-rules-for-phased-headless-rollout.html) ### The Hybrid Approach for PWA-Only Routes But what about pages that _only_ exist in your PWA? Think of custom React-based landing pages or an “About Us” page that isn’t a content asset in SFCC. The backend generator has no idea these exist. The solution is an elegant hybrid approach that you can automate in your CI/CD pipeline: 1. **Backend Generates Core Sitemap:** The scheduled job on SFCC runs as normal, creating sitemaps for all products, categories, and content assets. 2. **Frontend Generates Custom Sitemap:** As a build step in your CI/CD pipeline, run a script that scans your PWA Kit’s routes and generates a small, separate sitemap file (e.g., `pwa-custom.xml`) containing only these frontend-specific URLs. 3. **Automate the Merge:** The final step of your deployment script makes a `PUT` request to the `uploadCustomSitemapAndTriggerSitemapGeneration` SCAPI endpoint, uploading the `pwa-custom.xml` file. This tells SFCC to regenerate the main index, adding a link to your new custom file. This strategy uses the right tool for the job: the backend’s efficiency for the massive catalog and the frontend’s build process to handle its own unique pages. ## Conclusion By mastering these tools and strategies, you can transform sitemap management from a chore into a powerful, automated part of your development and deployment workflow. You’ll build more robust sites, ensure content is discovered faster, and become an SEO hero in the process. --- ## Local vs Shared Variation Attributes in Commerce Cloud Canonical URL: https://rhino-inquisitor.com/local-vs-shared-variation-attributes-sfcc/ Markdown URL: https://rhino-inquisitor.com/local-vs-shared-variation-attributes-sfcc/index.md Content type: article Published: 2025-04-14T07:17:18Z Updated: 2025-04-23T07:24:17Z Summary: Understand when to use local or shared variation attributes in Commerce Cloud and how each model affects merchandising and product data. Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, technical ## Key Takeaways - Compares local and shared variation attributes in SFCC at both the data-model and XML-import levels - Explains the flexibility, maintenance, and scalability trade-offs between both approaches - Helps teams choose when to centralize variation models and when product-specific attributes are justified In the dynamic world of eCommerce, the concept of [product variation](/slicing-versus-variation-groups-in-sfcc/) holds significant importance. It empowers merchants to effectively present a range of product options, a crucial aspect for platforms like Salesforce B2C Commerce Cloud. These platforms often deal with extensive catalogs, each with a variety of attributes to cater to diverse customer preferences. Among the ways to handle [product variations](/the-attribute-fallback-system-in-sfcc/) are local and shared variation attributes. In this article, we will delve into the technical differences between these two types of attributes, exploring their definitions, implementations in catalog import XML, and their respective advantages and disadvantages. ## What Are Variation Attributes? Let’s start by understanding what [variation attributes](https://help.salesforce.com/s/articleView?id=commerce.comm_var_att_intro.htm&type=5) are. These are the unique characteristics that define the different options for a specific product. For instance, a t-shirt available in multiple colors and sizes has ‘color’ and ‘size’ as its variation attributes, allowing customers to select their preferred options. In Salesforce B2C Commerce Cloud, variation attributes play a pivotal role. They not only help in categorizing products but also significantly enhance the shopping experience by making product selection easier and more intuitive for customers. In terms of catalog import XML, variation attributes are represented in a structured format that ensures the system understands the attributes associated with each product. Supported Attribute Types Currently, only non-localizable string and integer fields are supported for variation. ## What Are Local Variation Attributes? Local variation attributes are specific to a single product or a small group of products within a catalog. These attributes apply only to the respective products that define them, which means they can vary significantly from one product to another. Local attributes are particularly useful when there is a need to cater to unique product offerings that don’t apply to the broader catalog. ![A screenshot of a product in the business manager showing the Variations tab with local variation attributes.](/local-vs-shared-variation-attributes-sfcc/local-variation-attributes-5fad46fb81_hu_715465932edf71c7.webp) Local variation attributes are defined per-product and do not propagate across the catalog. ### Implementation in Catalog Import XML In the [catalog import XML](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/xsd/catalog.xsd), local variation attributes are defined under the specific product they are associated with, which distinguishes them from shared attributes. The XML snippet below illustrates how local variation attributes are structured: ```xml <?xml version="1.0" encoding="UTF-8"?> <catalog xmlns="http://www.demandware.com/xml/impex/catalog/2006-10-31" catalog-id="apparel-m-catalog"> <product product-id="25113204M"> ... <variations> <attributes> <variation-attribute attribute-id="color" variation-attribute-id="color"> <display-name xml:lang="x-default">Color</display-name> <variation-attribute-values> <variation-attribute-value value="JJ2KCXX"> <display-value xml:lang="x-default">Gulf</display-value> </variation-attribute-value> <variation-attribute-value value="JJG28XX"> <display-value xml:lang="x-default">Pink</display-value> </variation-attribute-value> <variation-attribute-value value="JJI15XX"> <display-value xml:lang="x-default">White</display-value> </variation-attribute-value> </variation-attribute-values> </variation-attribute> <variation-attribute attribute-id="size" variation-attribute-id="size"> <display-name xml:lang="x-default">Size</display-name> <variation-attribute-values> <variation-attribute-value value="004"> <display-value xml:lang="x-default">4</display-value> </variation-attribute-value> <variation-attribute-value value="006"> <display-value xml:lang="x-default">6</display-value> </variation-attribute-value> <variation-attribute-value value="008"> <display-value xml:lang="x-default">8</display-value> </variation-attribute-value> </variation-attribute-values> </variation-attribute> </attributes> <variants> <variant product-id="008885004885M"/> ... </variants> </variations> ... </product> <product product-id="008885004885M"> <custom-attributes> <custom-attribute attribute-id="color">JJI15XX</custom-attribute> <custom-attribute attribute-id="refinementColor">white</custom-attribute> <custom-attribute attribute-id="size">006</custom-attribute> <custom-attribute attribute-id="width">Z</custom-attribute> </custom-attributes> </product> </catalog> ``` In this example, the main product defines a color and size variation attribute that only applies to this particular main product and its variants. ## What Are Shared Variation Attributes? On the other hand, shared variation attributes are those that can be applied across multiple products within the catalog. These attributes promote consistency and can streamline the management of products that share similar characteristics. For instance, if multiple shoes come in the same colors and sizes, having shared variation attributes simplifies catalog management. [![A screenshot of the Business Manager showing where to configure Shared Varaiation Attributes: Products and Catalogs > Shared Variation Attributes - Select Catalog](/local-vs-shared-variation-attributes-sfcc/defining-shared-variation-attributes-92b82313b9_hu_cefa253e2693ed94.webp)](defining-shared-variation-attributes-92b82313b9.png) Shared variation attributes are configured centrally and reused across multiple products in the catalog. [![A screenshot of a product in the business manager showing the Variations tab with shared variation attributes.](/local-vs-shared-variation-attributes-sfcc/shared-variation-attributes-0d55796d17_hu_cee714421256e790.webp)](shared-variation-attributes-0d55796d17.png) Once shared attributes are assigned, the product's Variations tab reflects the catalog-wide attribute definition. ### Implementation in Catalog Import XML Shared variation attributes in the catalog import XML are referenced as part of the catalog, rather than an individual product. The following XML example showcases how shared variation attributes are represented: ```xml <catalog xmlns="http://www.demandware.com/xml/impex/catalog/2006-10-31" catalog-id="apparel-m-catalog"> <variation-attribute attribute-id="color" variation-attribute-id="color"> <display-name xml:lang="x-default">Kleur</display-name> <variation-attribute-values> <variation-attribute-value value="black"> <display-value xml:lang="x-default">Black</display-value> </variation-attribute-value> </variation-attribute-values> </variation-attribute> <variation-attribute attribute-id="size" variation-attribute-id="size"> <display-name xml:lang="x-default">Size</display-name> <variation-attribute-values> <variation-attribute-value value="16"> <display-value xml:lang="x-default">16</display-value> <description xml:lang="x-default">16</description> </variation-attribute-value> <variation-attribute-value value="17"> <display-value xml:lang="x-default">17</display-value> <description xml:lang="x-default">17</description> </variation-attribute-value> <variation-attribute-value value="18"> <display-value xml:lang="x-default">18</display-value> <description xml:lang="x-default">18</description> </variation-attribute-value> </variation-attribute-values> </variation-attribute> ... <product product-id="main"> .... <variations> <attributes> <shared-variation-attribute attribute-id="color" variation-attribute-id="color"/> <shared-variation-attribute attribute-id="size" variation-attribute-id="size"/> </attributes> <variants> <variant product-id="123456"/> <variant product-id="7891011"/> </variants> <variation-groups> <variation-group product-id="123"/> <variation-group product-id="456"/> </variation-groups> </variations> </product> <product product-id="main-2"> .... <variations> <attributes> <shared-variation-attribute attribute-id="color" variation-attribute-id="color"/> <shared-variation-attribute attribute-id="size" variation-attribute-id="size"/> </attributes> <variants> <variant product-id="223456"/> <variant product-id="8891011"/> </variants> <variation-groups> <variation-group product-id="223"/> <variation-group product-id="556"/> </variation-groups> </variations> </product> <product product-id="123456"> <custom-attributes> <custom-attribute attribute-id="color">black</custom-attribute> <custom-attribute attribute-id="size">18</custom-attribute> </custom-attributes> </product> </catalog> ``` In this case, both products utilise the same shared attributes for “Color,” demonstrating the shared nature of these attributes. ## Pros and Cons of Local Variation Attributes ### Pros 1. **Specificity**: Local variation attributes allow for highly tailored product offerings, accommodating unique features that don’t apply to other products. 2. **Flexibility**: Merchants have the flexibility to quickly change or update the attributes for individual products without affecting others. 3. **Simplicity**: For products that have very distinctive attributes, local variation attributes can simplify the overview for customers by streamlining options. ### Cons 1. **Management Complexity**: Having numerous local attributes can lead to a complex catalog management system, making it harder to maintain and update individual products. 2. **Redundancy**: Local variation attributes, when overused, can lead to redundancy, especially if multiple products share similar attributes. 3. **Limited Scalability**: As the catalog grows, managing local attributes can become increasingly cumbersome, limiting long-term scalability. 4. **Import XML Size:** The import file exponentially grows over time, slowing down the overall import process. ## Pros and Cons of Shared Variation Attributes ### Pros 1. **Consistency**: Shared attributes ensure consistency across products, creating a more streamlined shopping experience for customers. 2. **Ease of Management**: Managing shared attributes can be less complex since changes made to these attributes automatically apply to all associated products. 3. **Scalability**: Shared attributes offer a scalable approach; as new products are added, they can easily adopt existing attributes without requiring extensive modifications. 4. **Import performance:** A smaller XML to import, with less duplication, means faster import speeds. ### Cons 1. **Lack of Flexibility**: The main drawback of shared variation attributes is the potential lack of flexibility when unique attributes are necessary for specific products. 2. **Limiting Options**: Merchants may find it challenging to personalise products since shared attributes can constrain variation options. 3. **Over-generalisation**: There is a risk of over-generalising product attributes, which may lead to a lackluster shopping experience for customers seeking specificity. ## Combination? In certain scenarios, combine approaches by utilising shared attributes for most of your product catalog while relying on localised variation attributes for a smaller portion! ## Conclusion Local and shared variation attributes play essential roles in product management within Salesforce B2C Commerce Cloud. Each has its set of advantages and potential downsides, and the choice between them often depends on the business’s specific requirements, the nature of the products being offered, and the desired customer experience. Understanding the nuances of local and shared attributes is not only important but paramount for any organisation aiming to leverage the full potential of its B2C Commerce Cloud solution. --- ## Sending Emails from SFCC Canonical URL: https://rhino-inquisitor.com/sending-emails-from-sfcc/ Markdown URL: https://rhino-inquisitor.com/sending-emails-from-sfcc/index.md Content type: article Published: 2024-12-09T08:19:31Z Updated: 2024-12-11T16:13:38Z Summary: This article covers the reasons for opting to send emails via Salesforce Commerce Cloud, the platform's limitations, the steps for programmatically Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, sfcc, sfra, technical ## Key Takeaways - Explains when sending transactional emails directly from SFCC is practical and where dedicated marketing platforms still win - Covers the implementation path for native email sending, template testing, SPF or SMTP setup, and platform constraints - Clarifies how email sending differs between classic SFRA-style implementations and composable storefront architectures Salesforce B2C Commerce Cloud is known as a [monolithic](https://www.atlassian.com/microservices/microservices-architecture/microservices-vs-monolith) system, providing a wide range of functionalities out of the box. One of the “_smaller_” features of the platform is its capability to send [emails directly](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-sending-email-via-scripts-or-hooks.html) without needing a third-party service. In this article, we will discuss the reasons for choosing to send emails from Salesforce Commerce Cloud, the limitations of the platform, the steps to programmatically send an email, how to test email templates, the process of configuring SPF records, and whether you can utilise your own SMTP server. ## Why Choose Salesforce B2C Commerce Cloud for Email In many past projects, I have opted to send emails from a Marketing Automation platform since it has many benefits compared to the built-in functionality. But if the items below do not affect you, SFCC can be a great platform to send your [transactional emails](https://help.salesforce.com/s/articleView?id=sf.icx_b2c_transactionalemail_req_workflow.htm&type=5) (order confirmation, password reset, registration, etc.). ### Marketing Opportunities In most Marketing platforms, you have the freedom to be highly flexible with the templates, adapting them to the current time period and campaigns happening. In Salesforce B2C Commerce Cloud, a code deployment is necessary, and extra testing is required to ensure the built functionalities still work. This can increase the workload, making it less feasible to make multiple adaptations over the year. While you may not want to modify your transactional emails frequently, it’s a lot easier to give them a nice ‘holiday’ or ’easter’ styling for a few weeks in the year using dedicated marketing tools. ![Illustration of seasonal variations in transactional email design.](/sending-emails-from-sfcc/a-mail-across-the-year-15b12cb7bc_hu_1f0669dfdc6374af.webp) #### Page Designer to the rescue With the addition of [Page Designer](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-dev-for-page-designer.html) a few years ago, we have gotten a more “visual” way of creating pages, compared to static ISML templates with slots and Content Assets. But with choosing to go this route, a few things need to be kept in mind: - A separate “master” template is required without the regular header/footer - Only components that include HTML/CSS understood by mail clients should be used (modern HTML & CSS can cause issues in some mail clients). - Personalization (Customer Groups in particular) can pose difficulties when the mail originates from a job rather than a direct storefront request, as the session “current customer” is not readily accessible. - If a user inadvertently deletes the page (yes, accidents happen), there should be a backup option or a notification to resolve the issue promptly. ### Only Basic Features Salesforce’s email capabilities may not be as feature-rich as those of dedicated email marketing platforms. You might miss advanced features such as personalised templates, optimised sending times and tracking. ### Deliverability Concerns Ensuring high deliverability rates can be challenging because you’re relying on shared IP addresses, which may affect the reputation of your emails. We will return to this topic later in the article since the platform provides us with some solutions! ### Cost The previous points may seem like I’m advocating for a dedicated email platform. However, the marketing automation features I mentioned come with costs! Generally, each email sent comes with a charge, and these costs can accumulate significantly over time. Fortunately, Salesforce Commerce Cloud doesn’t require a separate license, allowing you to send **unlimited emails** at **no additional cost**! Marketing Mails Sending transactional emails via Commerce Cloud remains the most sensible option, as creating marketing emails in SFCC is quite “challenging,” to put it mildly. ## How to Send an Email Programmatically Emails can be sent from Salesforce B2C Commerce Cloud via code easily. Here’s a basic example using server-side scripts: ```js function sendMail() { var mail = new dw.net.Mail(); mail.addTo("to@example.org"); mail.setFrom("from@example.org"); mail.setSubject("Example Email"); mail.setContent('my basic text content'); mail.send();//returns either Status.ERROR or Status.OK, mail might not be sent yet, when this method returns } ``` You can enhance your options further by creating custom ISML templates, offering greater flexibility: ```js function sendMail() { var template = new dw.util.Template("myTemplate.isml"); var content = template.render(o); var mail = new dw.net.Mail(); mail.addTo("to@example.org"); mail.setFrom("from@example.org"); mail.setSubject("Example Email"); mail.setContent(content); mail.send();//returns either Status.ERROR or Status.OK, mail might not be sent yet, when this method returns } ``` But then, of course, comes the next question… ## How do I test email templates in Commerce Cloud Unlike many Marketing Automation tools available today, the SFCC platform lacks an out-of-the-box email testing feature. However, there are ways to custom-build a solution. ### Rendering Controller With an ISML mail template, you can create a controller to display the email as a web page, using pre-defined parameters that enable developers and testers to easily see how it will appear. Production Hide this endpoint, or never deploy this controller to production. ### Email Test Controller You could also build a controller that will send an email to an address passed, with other parameters like: ```text TestEmail-Send?email=myemail@mail.com&orderId=10000001 ``` This would send an email for that specific order to the email passed, allowing testers and developers to verify the template without having to go through the entire checkout flow. Production Hide this endpoint, or never deploy this controller to production. ## Configuring SPF Records Sender Policy Framework ([SPF](https://en.wikipedia.org/wiki/SPF)) records are crucial for ensuring email deliverability. If this is not configured, providers such as Outlook and Gmail will simply prevent your emails from arriving. They will be completely blocked and will not even arrive in the spam folder. Configuring these SPF records is clearly documented [in the Salesforce SPF setup guide](https://help.salesforce.com/s/articleView?id=000391416&type=1). ## Can I Use My Own SMTP Server [![Email Settings screen used to configure SMTP and DKIM options.](/sending-emails-from-sfcc/sfcc-email-settings-21507245df_hu_5954b586bb66e4a7.webp)](/sending-emails-from-sfcc/sfcc-email-settings-21507245df.png) Administration > Operations > Email Settings Salesforce B2C Commerce Cloud supports [the use of an external SMTP server for sending emails](https://help.salesforce.com/s/articleView?id=cc.b2c_business_manager_email_configurator.htm&type=5). If you already have an established SMTP service or require advanced configurations, using an external SMTP server allows you to gain more control over the email delivery process, customise your settings, and potentially improve email deliverability rates. ### DKIM Support Using these SMTP settings, you can set up [DKIM](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) directly on the same page in the Business Manager. ## What rules must I follow Under typical usage, you should encounter no issues. However, certain security measures may lead to a [lockout](https://help.salesforce.com/s/articleView?id=000395276&type=1). In the worst case, you will not be able to send emails for 48 hours. ## Are attachments possible Absolutely! This was among the first articles I published on the blog: [How to send PDFs as attachments](/mail-attachments-in-b2c-commerce-cloud/) (though you’re certainly not restricted to just PDFs). ## Can I send mails from the Composable Storefront Directly from the Managed Runtime? No. You will have to make an API call to a [custom API](/in-the-ring-ocapi-versus-scapi/) or [hook](/how-to-use-ocapi-scapi-hooks/) into an existing standard API to attach sending an email through the platform. ## Conclusion While Salesforce B2C Commerce Cloud may not offer the same range of features as most Marketing Automation tools, it can still be highly effective for transactional messaging. --- ## Storefront Protection For Your Composable Storefront Canonical URL: https://rhino-inquisitor.com/storefront-protection-in-the-pwa-kit/ Markdown URL: https://rhino-inquisitor.com/storefront-protection-in-the-pwa-kit/index.md Content type: article Published: 2024-11-18T07:26:53Z Updated: 2024-11-20T12:36:26Z Summary: Learn how storefront protection applies to Composable Storefront projects, where SFRA patterns still help, and what extra checks to add. Categories: Salesforce Commerce Cloud, Technical Tags: pwa kit, sfcc, sfra ## Key Takeaways - Explains why classic Business Manager storefront protection does not automatically carry over to composable storefront projects - Shows how basic authentication middleware in the PWA Kit server can protect non-public Managed Runtime environments - Frames storefront protection as both an access-control need and an SEO safeguard for unfinished storefronts Protecting online stores using [Storefront Protection](https://help.salesforce.com/s/articleView?id=cc.b2c_storefront_password_protection.htm&type=5) in [SiteGenesis and SFRA](/the-move-from-sitegenesis-and-sfra-to-the-composable-storefront-as-a-developer/) is simple. But now that we have the [Composable Storefront](/sitegenesis-vs-sfra-vs-pwa/), we need to think about whether those protections still work. This blog post will talk about how to keep your Composable Storefront safe and what this new technology means for security. ## The Shift from Business Manager to Managed Runtime When utilising SFCC with SiteGenesis or SFRA (Salesforce Reference Architecture) sites, enabling Storefront Protection was a straightforward process. You can easily navigate through the Business Manager by following this path: ```text Administration > Sites > Manage Sites ``` We proceed on our journey by selecting the site you want to enable this for, then navigating to the site status tab after the page has finished loading. [![Site Status screen in Business Manager with Online Protected selected.](/storefront-protection-in-the-pwa-kit/online-protected-sfcc-b0634b710d_hu_21a4bb4c1ba806b4.webp)](/storefront-protection-in-the-pwa-kit/online-protected-sfcc-b0634b710d.jpg) This page allows us to switch to “Online (Protected),” which unveils a new field. [![Protected storefront password field shown after enabling Online Protected.](/storefront-protection-in-the-pwa-kit/storefront-protection-password-sfcc-c017798dc4_hu_6e2fec4ad9087629.webp)](/storefront-protection-in-the-pwa-kit/storefront-protection-password-sfcc-c017798dc4.png) Here, you choose a password that allows users to access the storefront. ### 1\. simple 2. effortless 3. straightforward The Storefront Protection method helps keep your online store safe and controls who can access it. However, things have changed with the new SFCC PWAs (Progressive Web Apps). Moving from Business Manager to Managed Runtime (MRT) is a big shift, and developers need to know that the protection settings from Business Manager don’t work for PWAs anymore. Because of this change, we must find new ways to keep our online stores safe. Password protection is still very important, especially when we’re working on a site or when we need to limit who can see it. So, how can we keep SFCC PWA storefronts safe and restrict access? ## Implementing Basic Authentication in The Composable Storefront A straightforward way to limit who can access your SFCC PWA storefront is to use [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication). This method works on the server side, meaning it runs on the computer that hosts your website. It involves setting up a special middleware function for the login process. Here are the steps to help you get started. ### Step 1: Locate the \`ssr.js\` File First, find your \`ssr.js\` file in your SFCC PWA project folder. This file is important because it helps with server-side rendering, which is necessary for safely displaying your online store’s content. ### Step 2: Create Middleware for Basic Authentication I’m not particularly eager to do things all over again if someone has already done a fantastic job. Here are some examples of how to add your own authentication middleware: - [A deprecated method (just for reference)](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/732/files) - [The latest example made by John Boxall](https://gist.github.com/taurgis/e6a60e14672df31a0e1d7ea311671f3c) - [An example Hamza Javed made recently on LinkedIn](https://www.digitscommerce.com/sfcc-pwa-ssr.js) ## Why would you do this Making sure your SFCC PWA store has a password is really important. This is especially true when you’re still working on it or it’s not ready for everyone to see. Because it’s in the cloud, anything you put online can be accessed unless you put up some protection. If you don’t secure it, people who shouldn’t see your work might get access to important information and unfinished parts of the site. Also, if the site isn’t protected, search engines might find it too soon and show it to everyone, even though it’s not finished. This could hurt your website’s reputation and lower how it ranks in search results. By using a simple password protection, you can keep your work safe and ensure only the right people can check it out. This helps keep your project intact and protects your brand’s reputation. ## Is there an interface planned Right now, the main suggestion (to my knowledge) is to stick with the coding solution. I haven’t seen any plans for an interface for “Storefront Protection”. This feature can be added easily with just a little development using environment variables. I believe the time and resources spent on improving the PWA Kit project would be better used on other priorities instead of creating interfaces for these features. --- ## Third-Party API Caching in Commerce Cloud Canonical URL: https://rhino-inquisitor.com/third-party-api-caching-in-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/third-party-api-caching-in-commerce-cloud/index.md Content type: article Published: 2024-11-11T05:35:00Z Updated: 2024-11-13T09:26:49Z Summary: Learn how to cache third-party API responses in Commerce Cloud to improve performance, control latency, and avoid stale-data pitfalls. Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, sfcc, sfra, technical ## Key Takeaways - Explains how to enable response caching for third-party services in SFCC through the LocalServiceRegistry and HTTP client - Highlights the practical benefits of caching for performance, reliability, rate-limit pressure, and external service cost control - Covers the important caveats around stale data, cache invalidation, service limits, and debugging complexity Enhancing the performance of your different online channels is a given, including keeping an eye on any third-party integrations. All Salesforce Commerce Cloud sites rely on APIs in some capacity, such as for retrieving location data, weather updates, address verification, [submitting files](/submitting-a-file-to-a-third-party-service-in-sfcc/), and more, all with different levels of performance stability. 😅. Understanding and applying caching for third-party services can enhance your third-party’s integration performance and cost-effectiveness. Now, let’s delve into the process, its benefits, and some things to remember to get you going. ## Caching with LocalServiceRegistry ![Salesforce Commerce Cloud Web Service Framework overview image](/third-party-api-caching-in-commerce-cloud/sfcc-service-framework-b996d130d4_hu_994e183dd03e376d.webp) Salesforce Commerce Cloud Web Service Framework The [Web Service Framework](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-webservices.html) is key to managing external service interactions. It enables developers (and other profiles) to manage third-party integrations with [ease](https://trailhead.salesforce.com/content/learn/modules/b2c-integration-approaches/b2c-learn-web-services-framework) from the comfort of the Business Manager. One of those built-in features is caching responses from third-party APIs, which reduces the need for repeated network requests and, in many cases, reduces costs related to those services (usage-based licenses). Creating a service in the [LocalServiceRegistry](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/index.html?target=class_dw_svc_LocalServiceRegistry.html) comes with a simple configuration for managing request handling. Here’s a basic example of how to create a service with a caching feature: ```js var callTestGet = LocalServiceRegistry.createService("test.http.get", { createRequest: function(svc: HTTPService, args) { svc.client.enableCaching(1000); svc.setRequestMethod("GET"); }, parseResponse: function(svc: HTTPService, client: HTTPClient) { return client.text; }, mockCall: function(svc: HTTPService, client: HTTPClient) { return { statusCode: 200, statusMessage: "Success", text: "MOCK RESPONSE (" + svc.URL + ")" }; }, filterLogMessage: function(msg: String) { return msg.replace("headers", "OFFWITHTHEHEADERS"); } }); ``` [In this snippet](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-webservices.html#configure-underlying-clients), the \`**enableCaching**\` method is invoked, enabling caching for the HTTP requests serviced by this configuration. The argument (in this case, \`1000\`) represents a timeout setting, which dictates how long a cached response will be valid before the subsequent request is made. ![Official documentation snippet showing enableCaching on an HTTP service](/third-party-api-caching-in-commerce-cloud/configuring-underlying-clients-95d307a0e7_hu_fbbaa3f6cd774061.webp) A screenshot of the official documentation on how to add caching to a service. ## Why Caching Matters [Caching](/caching-rest-apis-in-sfcc/) has several benefits, especially for services with consistent data and infrequent updates. Let’s have a look at how this minor code change can significantly affect the way your Salesforce Commerce Cloud channel works: 1. **Faster performance:** Caching allows your site to retrieve data from “local” storage instead of repeatedly calling an external server. When a cached response is available, the app server can quickly fulfil requests, significantly reducing wait times. 2. **Greater Reliability:** With caching, your site becomes more robust. If a third-party service goes down or experiences issues, your app can still provide cached data, ensuring a smoother user experience. 3. **Better Rate Limit Management:** Many APIs limit the number of requests you can make within a specific timeframe. Using cached responses reduces the number of requests sent out, helping you stay within these limits and preventing potential service interruptions. ## Everyday Use Cases for Caching Here are a few everyday situations where you might want to use [caching](/caching-in-the-sfcc-composable-storefront/): 1. **Google Location Services:** Location data doesn’t change very often, so caching it can speed up response times in local applications. 2. **Address Verification Services:** Address information stays the same over time. Caching these responses can improve efficiency. 3. **Weather Services:** Weather data can be cached for short periods. While it might change frequently, most applications don’t require constant real-time updates. Implementing caching for these services can significantly enhance performance, boost speed, and reduce expenses. However, don’t anticipate any “magic 🪄"—it’s the accumulation of many small enhancements that can lead to significant improvements. The development effort here is minimal, yet the potential impact is substantial! Is anyone looking for quick wins? ## Clearing the cache ![Service Maintenance screen used to invalidate HTTP client response cache](/third-party-api-caching-in-commerce-cloud/clearing-httpclient-response-cache-c4b7ab1863_hu_825d197b5ffbdec.webp) A screenshot of the 'Service Maintenance' configuration page in the Business Manager. You can clear the HTTPClient Response cache in the Business Manager by going to `Administration > Operations > Service Maintenance`. Here, you’ll find options related to this cache. To clear cached responses for ALL services, simply click the **Invalidate** button next to “HTTP Client Response Cache.” Service Specific There isn’t an option to clear the cache for a specific service. ## Some things to keep in mind ### General Caching Warnings > **Caching:** HTTP responses has numerous benefits, yet it’s crucial to be mindful of potential drawbacks. - **Stale Data:** Cached data can become outdated, especially if the third-party API updates its responses frequently. Be sure to set a cache expiration period that matches the data’s update frequency. - **Inconsistent States:** Relying too much on cached data without refreshing it can lead to users receiving outdated or incorrect information. This can negatively affect user experience and erode trust. - **Error Propagation:** If there’s an error from the external service and you cache this response, users might keep encountering the same error until the cache is cleared or expires. - **Debugging Complexity:** Debugging can get tricky if cached responses interfere with your expectations while developing or testing your application. It’s important to know precisely what data is being cached. - **Impact on Business Logic:** Cached responses might not show real-time changes crucial for essential business processes. This can result in making incorrect decisions based on outdated data. ### LocalServiceRegistry-Specific Considerations #### Limitations [It caches only status codes of 2xx with content length and size under 50k](https://sfcclearning.com/infocenter/DWAPI/scriptapi/html/api/class_dw_svc_HTTPService.php#dw_svc_HTTPService_setCachingTTL_Number_DetailAnchor), which are not immediately written to a file. The cache keys consist of the URL and the user name. The system automatically manages and limits the total size of cacheable content and the number of cached items. #### Initializing the HTTP Client When configuring the HTTPClient, only use the \`getClient\` method and other HTTPClient functions within the \`createRequest\` callback or any following callbacks. Accessing the client before invoking service will yield \`null\`, resulting in service call failures. #### Rate Limits and Circuit Breakers Remember that cached requests still count toward your service’s rate limits and circuit breaker configuration (and quota limits). While caching helps reduce direct external requests, every time you call the service—whether through the cache or directly—it impacts your statistical limits. This could cause service disruptions if you exceed certain [thresholds](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/quota/html/API_Quotas.html#category_I/O%20and%20Network). #### Monitoring Cached Requests Monitoring cached requests is a crucial part of making sure that your caching mechanism is working. It’s about “pressing the enable button” _**and**_ actively tracking its impact on your site’s performance and usability. ## Conclusion In conclusion, adding a caching mechanism to the LocalServiceRegistry for third-party services is a significant step towards boosting your performance and reducing operational costs. Even if the improvements are not always dramatic, every enhancement contributes to a smoother user experience. Here’s an example of a successful (anonymised) result from using this cache and rate limiting bot traffic: ![Graph showing lower third-party API traffic after bot filtering and caching](/third-party-api-caching-in-commerce-cloud/third-party-service-caching-results-e1731261763486-2847fa50c4_hu_b1d1721a80e61ce9.webp) The number of requests handled by the API decreased considerably, leading to a lower monthly bill. These improvements not only increased overall performance but also reduced costs on the third-party service, as each API call incurred a charge. --- ## Origin Shielding in Commerce Cloud Canonical URL: https://rhino-inquisitor.com/the-importance-of-origin-shielding/ Markdown URL: https://rhino-inquisitor.com/the-importance-of-origin-shielding/index.md Content type: article Published: 2024-11-04T08:40:19Z Updated: 2024-11-04T08:41:59Z Summary: Learn why origin shielding matters in Commerce Cloud, how it protects origin infrastructure, and when to include it in your traffic strategy. Categories: Architecture, Salesforce Commerce Cloud, Technical Tags: composable storefront, sfcc, technical ## Key Takeaways - Explains what origin shielding is in the SFCC and eCDN context and why it protects storefront and API origins from direct access - Highlights the practical impact on PIG access, third-party integrations, and Managed Runtime origin locking - Provides a short operational checklist for reducing disruption through vanity domains, communication, testing, and monitoring Today, we’re exploring the crucial role of [Origin](https://www.cloudflare.com/learning/cdn/glossary/origin-server/) Shielding in Salesforce B2C Commerce Cloud. As online security becomes increasingly important (and always has been), we’ll look at what Origin Shielding (and Origin Locking) is. We will also share the steps involved in your projects. Let’s dive into the details! ## What is “Origin Shielding”? Origin shielding protects the origin server - in our case the Application Servers - by funneling all incoming traffic through an intermediate layer, or shield. When someone tries to access content hosted on Salesforce, Mobify, or Demandware, the Embedded Content Delivery Network (eCDN) steps in. It intercepts the request, verifies its legitimacy, and only sends valid requests to the origin servers. This process helps reduce the risk of direct attacks on the origin infrastructure and adds an extra layer of protection against unauthorised access. After all, Cloudflare does have a few things in it’s arsenal. Long story short, origin shielding is a security measure for safeguarding cloud-hosted infrastructure, ensuring both the integrity and availability of Salesforce’s services. ![A dramatic image of a superhero in front of a server, protecting it from a 'bad' actor in the shadows.](/the-importance-of-origin-shielding/origin-shielding-v2-280aa345d3_hu_b4df0198734116af.webp) Origin shielding acts as a protective layer between the public internet and Salesforce's cloud infrastructure. ## The back-end and OCAPI Origin shielding was implemented to manage access to the Demandware URLs of our storefronts and the OCAPI on the “Primary Instance Groups.” Although this change was communicated multiple times in advance, [many projects still encountered unexpected disconnections from third-party services](/a-look-back-at-origin-shielding/). With the introduction of Origin Shielding, any third-party system attempting to access controllers or OCAPI APIs through the Demandware URL received an error page. [![A screenshot of the Cloudflare Origin Shielding error shows that the user has been blocked.](/the-importance-of-origin-shielding/cloudflare-origin-shielding-error-b81358c14c_hu_893d0ec3559a75f8.webp)](cloudflare-origin-shielding-error-b81358c14c.png) Third-party integrations using the legacy Demandware hostname hit this Cloudflare block after Origin Shielding was enforced. ## SCAPI The SCAPI has not changed much. It still operates on Cloudflare Edge Functions and manages all the complexities behind the scenes. However, this setup means we have less control and are entirely dependent on Salesforce to ensure everything works smoothly. ## Managed Runtime and Origin Locking In the Composable Storefront, we gain more control because we handle all the operations ourselves. Fortunately, this process is [fully documented on the help site](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration#access-control-headers)! What if I don’t? It’s important to protect your “origin,” which is the Mobify domain. If you don’t, you risk allowing Google and other bots to index this domain, which can negatively impact your SEO. This could lead to users accidentally accessing the Mobify domain, rather than your vanity one. ## An overprotective “hero” The image I used before may seem a bit dramatic, but it highlights that we need to be vigilant with ourselves. The system doesn’t distinguish between good and bad actors, which can lead to inconveniences. We need the “know-how” to ensure our third-party systems can access everything we require. ## What do I do? To ensure that both you and any third-party systems do not encounter access issues due to Origin Shielding, just do a few simple things. The steps below might seem simple and even like common sense. However, during the stress of going live and approaching deadlines, they can easily be overlooked. All PIG instances are behind it In recent years, the “Origin Shielding” transformation has caused unexpected access errors for some users in their environments. However, this should no longer be an issue for new projects, as this is now the standard practice. ### 1\. Configure Vanity Domains The first thing to do to prevent access interruptions is to configure a vanity domain for all your environments, including staging, development, and production. A vanity domain serves as a friendly URL that is easier to remember and manage while also being recognised by Origin Shielding ([and configured in the eCDN itself](/lets-go-live-ecdn/) ). Rather than having ‘_[https://production-eu01-mybrand.demandware.net](https://production-eu01-mybrand.demandware.net)_’, we can use a nicer domain such as ‘_[https://brand.com](https://brand.com)_’ ### 2\. Use the domains The next step is pretty simple: _**Good communication**_. Make sure to inform all relevant parties to update their configurations to point to the vanity domains rather than the direct Demandware URLs. Communicating this information to the right people will significantly reduce the likelihood of encountering error pages due to unauthorised access errors. ### 3\. Test Before launching, make sure to test everything thoroughly. Check that all third-party systems can access your storefront and API features through the vanity domain. This step will help you find and fix any issues before they affect your operations. ![A cartoon depicting two people conversing with a chat bubble containing various colored emoticons.](/the-importance-of-origin-shielding/good-communication-8688aa2fb2_hu_f4845839559c9a97.webp) Good communication with integration teams is essential: confirm all third-party access works through the vanity domain before go-live. ### 4\. Monitor Not everything is in our power Some logs are easier to access than others. However, Salesforce has made significant improvements over the past two years to enhance our access to tools like the eCDN and Managed Runtime logs. Monitor your eCDN logs for any unusual activity or blocked requests. This will help you spot if any third-party systems are trying to access your resources, allowing you to take action quickly. --- ## B2C Commerce Cloud: Features and Tech Stacks Canonical URL: https://rhino-inquisitor.com/sfcc-introduction/ Markdown URL: https://rhino-inquisitor.com/sfcc-introduction/index.md Content type: article Published: 2024-10-28T06:53:07Z Updated: 2024-10-28T06:53:53Z Summary: An introduction to Salesforce B2C Commerce Cloud, covering core platform features, typical tech stacks, and where new teams should start learning. Categories: Salesforce Commerce Cloud Tags: composable storefront, headless, sfcc, sfra ## Key Takeaways - Introduces B2C Commerce Cloud through its history, core capabilities, and distinct place inside the wider Salesforce ecosystem - Explains the platform's major tech-stack transitions from pipelines to controllers to composable storefront development - Gives newcomers a practical overview of APIs, local setup, and the main architectural choices they will encounter Play video AI Summary: Here’s a summary of the presentation created by AI. (With a little course correction help from me) Join me as we delve into the world of B2C Commerce cloud, its history, tech stacks, and the shift towards headless architecture. In this insightful session, learn about the evolution, development languages, APIs, and setting up a composable storefront. ## Introduction to B2C Commerce Cloud (Demandware) Welcome to the world of B2C Commerce Cloud, part of the expansive Salesforce ecosystem. If you’re looking to dive into the intricacies of B2C Commerce Cloud, you’re in the right place. Let’s explore what makes this platform unique, how it fits into the Salesforce family, and understand its various components and historical background. ## Evolution from Demandware to B2C Commerce Cloud ### The Demandware Genesis In 2004, Demandware was founded to offer e-commerce solutions with a unique flavour. After twelve years of service, the company was acquired by Salesforce in 2016 and rebranded as B2C Commerce Cloud. This acquisition coincided with a series of strategic integrations by Salesforce and solidified Demandware’s role as a core component of Salesforce Commerce offerings. ### The Growth Phase Over the years, several acquisitions and integrations have significantly enhanced B2C Commerce Cloud’s capabilities. ## B2C Commerce cloud versus Commerce on Core One of the first points of clarification when discussing Commerce Cloud is the differentiation between its various offerings: - **B2C Commerce Cloud**: Tailored for business-to-consumer interactions. - **B2B Commerce Cloud**: Designed for business-to-business operations, also known as Commerce on Core, emphasising its deep integration with the core Salesforce platform. - **D2C Commerce Cloud:** Designed for business-to-consumer interactions, focusing on B2B companies directly selling to consumers. ### Managed Packages vs. Cartridges A unique trait of B2C Commerce Cloud is the absence of managed and unmanaged packages. Instead, developers use cartridges similar to zip files containing all the necessary source code. This differs from the package-based model seen in core Salesforce development. ### Role-Based Access and Permissions While Salesforce’s core platform offers extensive role-based access and permissions options, B2C Commerce Cloud simplifies this by offering module-level access. Users can have read or write access to entire modules, such as products, rather than specific records or fields. ### The Development Landscape B2C Commerce Cloud utilises JavaScript for both backend and frontend development, marking a notable shift from the Apex and Lightning Web Components traditionally used in core Salesforce. ## B2C Commerce Cloud Development Evolution ### The Early Days: Pipelines At first, Demandware utilised a pipeline architecture similar to Salesforce flows, adopting a low-code method to establish backend logic. This setup enabled developers to outline page rendering processes using a visual interface. ### Transition to Controllers In subsequent years, pipelines were supplemented and later largely replaced by controllers written in JavaScript. This phase saw Demandware transitioning into more conventional coding methods while retaining some of its original workflow design elements. ### Modern Stack: Storefront Reference Architecture and Beyond The most significant evolution in the platform’s architecture was the introduction of the Mobile-First Reference Architecture (MFRA) and the Storefront Reference Architecture (SFRA). These updates modernised the front end and established a more modular and flexible e-commerce platform. ### Headless Commerce: Composable Storefront In 2021, B2C Commerce Cloud underwent another substantial transformation, embracing the headless commerce model with the acquisition and integration of Mobify. This led to the creation of the PWA Kit and Managed Runtime, now known collectively as the Composable Storefront. This shift aimed to separate frontend and backend development, providing: - **Flexibility**: Different teams can work on the frontend and backend simultaneously without conflicting changes. - **Scalability**: Easier to scale different parts of the application independently. - **Adaptability**: Enables use of the latest frontend technologies like React, ensuring developers leverage modern, well-supported tools and frameworks. ## Delving into the Technical Architecture ### Understanding the Composable Storefront The composable storefront represents the latest and most flexible approach to building e-commerce apps on B2C Commerce Cloud. Here’s how it plays out: - **Managed Runtime**: Hosts the frontend application, handling deployment and environment management. - **PWA Kit**: A React-based frontend framework that communicates with the backend using robust APIs. ### API Connectivity: Open Commerce API and Salesforce Commerce API B2C Commerce Cloud offers two primary API sets: 1. **Open Commerce API (OCAPI)**: The original set of APIs dating back to Demandware’s early days. 2. **Salesforce Commerce API (SCAPI)**: A newer set designed to provide a more seamless and integrated experience with Salesforce environments, capable of connecting to the environment’s underlying services, like the product database. Both APIs enable different degrees of interaction between the frontend and backend systems, with SCAPI being pushed as the preferred future standard. ## Creating Your Own Composable Storefront ### Local Development Setup To set up a local development environment for the composable storefront: 1. Clone the [Retail App Example](https://github.com/SalesforceCommerceCloud/pwa-kit) from GitHub. (via npx) 2. Install necessary dependencies and configure local settings. 3. Run the application locally to start your development. ```bash npx @salesforce/pwa-kit-create-app npm start ``` The above commands will set up your project, start the development server, and allow you to make changes to the code, with instant live reloading to see your updates. ## Accessing Sandboxes [Getting a sandbox](/how-to-get-a-salesforce-b2c-commerce-cloud-sandbox/) is not easy if you are not a partner or customer. ## Conclusion B2C Commerce Cloud offers a robust, scalable, and customisable solution for modern e-commerce needs. Understanding its history, components, and the evolving development landscape can provide powerful insights for architects, developers, and business owners. Whether you’re just starting or are looking to deepen your expertise, the paths to learning and development within the B2C Commerce Cloud ecosystem are numerous and rewarding. Dive in, explore, and make the most of the invaluable resources available to you. --- ## Use SFRA REST Endpoints in a Composable Storefront? Canonical URL: https://rhino-inquisitor.com/should-i-use-sfra-rest-endpoints-in-a-composable-storefront/ Markdown URL: https://rhino-inquisitor.com/should-i-use-sfra-rest-endpoints-in-a-composable-storefront/index.md Content type: article Published: 2024-10-21T09:36:19Z Updated: 2024-10-21T09:36:27Z Summary: When working with Salesforce B2C Commerce Cloud in a hybrid approach (using SFRA with a Composable Storefront project), you naturally end up with some Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, sfcc, sfra, technical ## Key Takeaways - Argues that SFRA controllers should not be used as custom REST endpoints in modern composable storefront projects - Explains why custom SCAPI endpoints are the better native option for authentication, caching, request-method support, and architecture clarity - Highlights the operational downsides of controller-based APIs, including session creation, session bridging, and added system load When working with Salesforce B2C Commerce Cloud in a hybrid approach (using SFRA with a Composable Storefront project), you naturally end up with some pages as SFRA Controllers and other parts of the project built on the Composable Storefront. In that regard, you end up using [SFRA](/sitegenesis-vs-sfra-vs-pwa/) Controllers, and it all works with the Composable Storefront through the magic of [SLAS](/how-to-set-up-slas-for-the-composable-storefront/)! But is the same true for using controllers to create REST endpoints? ## There is a better native solution Let’s get straight to the answer without beating around the bush: The answer to the question in this blog post is “NO.” While controllers were the only option in the past, we now have a more flexible solution: [Custom SCAPI endpoints](https://developer.salesforce.com/docs/commerce/commerce-api/guide/custom-apis.html) that support all request methods (GET, POST, PUT, DELETE). This flexibility allows you to adapt to different request types. Besides all request methods, we get: - [Same authentication methodology](https://developer.salesforce.com/docs/commerce/commerce-api/guide/custom-api-authentication.html) (SLAS JWT) - [Personalisation & caching](https://developer.salesforce.com/docs/commerce/commerce-api/guide/custom-api-caching.html) So, if you have some controllers or [custom OCAPI endpoints](/creating-custom-ocapi-endpoints/) left over on a project built before this, it might be a good time to add a ticket to your backlog to upgrade them. Are you still interested in the reason for this? If so, keep on reading! ## Reasons not to do it ### Supported methods Out of the box, the only two methods you can support with SFRA are [GET](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/blob/1cb2b329fa281333403bb2681b939e727aee809a/cartridges/modules/server/server.js#L115) and [POST](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/blob/1cb2b329fa281333403bb2681b939e727aee809a/cartridges/modules/server/server.js#L126). This is quite the limiting factor when working in a headless and composable fashion, where you make every endpoint a POST. There is a way around this limitation that I experimented with before custom SCAPI endpoints were a thing in my “[Headless Reference Architecture](https://github.com/taurgis/headless-reference-architecture) (Deprecated)”, a branch off of SFRA specifically made for Composable Storefront projects needing to create custom controller endpoints. ### Personalisation and session bridging When creating endpoints that require personalisation, you need to use “plugin\_slas” to transfer your JWT to a session cookie. However, in specific scenarios, redirects and URL refreshes are some of the “actions” that occur. While this is fine for a regular user loading a page in the browser, for integrations, it can be a significant hurdle to overcome. It can also introduce extra API calls and delays in getting responses. #### Adding complexity to your API architecture Employing session transformation and SLAS this way increases architectural complexity, complicating debugging efforts unnecessarily. ### Session creation One of the benefits of choosing Salesforce is that we don’t have to worry about server and hardware-related issues, as scaling happens automatically. However, this doesn’t mean we should introduce unnecessary load onto the system just because we can. A downside of calling a “controller API” is that it behaves like an SFRA request. If the request does not attach a session cookie, the system will recognise that it needs to start a new one. If we poorly implement a custom endpoint that is called on every page load to retrieve “mundane information,” we will create thousands of sessions for no reason. These unnecessary sessions also need to be cleaned from the database, creating additional system load that could be better utilised. ![A person using a calculator for Excel has built-in functions to do calculations for you. It represents inefficient work and creates a significant workload for no reason.](/should-i-use-sfra-rest-endpoints-in-a-composable-storefront/calculator-and-excel-e1728648264417-2b10df8062_hu_70c035a969134ee7.webp) ## Conclusion? The conclusion was already shared at the [start of the article](#conclusion)! --- ## SWC And Storybook: Error: Failed to load native binding Canonical URL: https://rhino-inquisitor.com/swc-and-storybook-error-failed-to-load-native-binding/ Markdown URL: https://rhino-inquisitor.com/swc-and-storybook-error-failed-to-load-native-binding/index.md Content type: page Published: 2024-10-19T16:33:40Z Updated: 2024-10-19T16:39:11Z Summary: Fix the SWC Storybook native binding error after switching between Apple Silicon and Intel environments by reinstalling dependencies cleanly. Categories: Documentation When switching between my M1 MacBook and Intel X64 MacBook today, I ran into an odd error: ```text Error: Failed to load native binding at Object. (/node_modules/@swc/core/binding.js:333:11) at Module._compile (node:internal/modules/cjs/loader:1469:14) at Module._extensions..js (node:internal/modules/cjs/loader:1548:10) at Object.newLoader (/node_modules/esbuild-register/dist/node.js:2262:9) at extensions..js (/node_modules/esbuild-register/dist/node.js:4833:24) at Module.load (node:internal/modules/cjs/loader:1288:32) at Module._load (node:internal/modules/cjs/loader:1104:12) at Module.require (node:internal/modules/cjs/loader:1311:19) at require (node:internal/modules/helpers:179:18) at Object. (/node_modules/@swc/core/index.js:49:17) ``` ## Solution Deleting my **package-lock.json** file and **node\_modules**, and then running ’npm install’ again magically fixed the problem! --- ## Caching in the Salesforce Composable Storefront Canonical URL: https://rhino-inquisitor.com/caching-in-the-sfcc-composable-storefront/ Markdown URL: https://rhino-inquisitor.com/caching-in-the-sfcc-composable-storefront/index.md Content type: article Published: 2024-10-14T09:42:12Z Updated: 2024-10-14T12:49:23Z Summary: Learn how caching works in the Salesforce Composable Storefront, which layers matter most, and where it improves real-world speed. Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, sfcc, technical ## Key Takeaways - Explains where SSR, CDN, and API caching fit in the Composable Storefront stack - Highlights cache-control, invalidation, and replication caveats teams need to plan for - Covers personalized caching behavior for custom APIs and hook-based responses Caching, Performance, Lighthouse Speed, CrUX, … and probably many more terms have crossed your desk and mind ever since you got into web development and, more specifically, if you are here, Salesforce B2C Commerce Cloud. With the platform’s various iterations, understanding the differences is crucial. [SFRA](/sitegenesis-vs-sfra-vs-pwa/) differs from the Composable Storefront, so your experience with one may not directly apply to the other. But you aren’t here for pretty intro speeches and chit-chat—let’s get into the options you should know! ## Server-Side Rendering & Caching When we talk about the server side in the Composable Storefront, we shouldn’t forget that our “head” has now been completely separated from the “body”, which is an entirely different way of thinking compared to SFRA. And within that “Head”, the PWA-Kit, we have the option to make use of Server Side Rendering. But why do we even have this concept? ### Why Server Side Rendering For several reasons, server-side Rendering (SSR) is essential in a Single Page Application (SPA), especially for an e-commerce website. SSR helps improve the website’s search engine optimisation (SEO). Search engines rely on the initial HTML content of a page to index its content. With SSR, the server sends fully rendered HTML to the client, making it easier for search engine crawlers to index the site, resulting in better visibility and ranking in search results. It also significantly boosts the initial page load time and overall website performance. By rendering the initial HTML content on the server and sending it to the client, SSR reduces the time it takes for the user to see and interact with the content. This leads to a better user experience, a critical factor for e-commerce sites where user engagement directly impacts sales. SSR also plays a significant role in social media sharing and link previews. When a link to a page is shared on social media platforms, having pre-rendered HTML content allows for a better link presentation, including rich previews with images and metadata. This can significantly improve click-through rates and user engagement. ### But it should be cached Just like SFRA and SiteGenesis, caching the HTML generated by the server will significantly improve the performance that users experience in the browser and reduce the system load. This allows the system to focus on more critical aspects of the site that cannot be cached, such as the checkout. If you don’t cache these pages, the initial page loads will have to wait for all of the “anonymous” API calls and for building the page: - SLAS Session initialisation - Categories call for the menu - Your main page API (Page Designer, Product Search, …) - React component rendering If they are not cached, all of these items can raise your TTFB (time to first byte) metric well above 1.5 seconds for every page visit (first-page load; after that, the client side takes over). Luckily, we can easily enable this mechanic via the code: ```js const Home = () => { ... const {res} = useServerContext() if (res) { res.set( 'Cache-Control', `s-maxage=${MAX_CACHE_AGE}, stale-while-revalidate=${STALE_WHILE_REVALIDATE}` ) } ... } ``` > **Cdn:** Know that the CDN part of the Managed Runtime takes care of this caching mechanism. At the time of writing, this is CloudFront. The plan is to migrate to the eCDN for a generic architecture (Forward-Looking Statement). > **Default Cache Times:** Be aware that the default cache time is only 15 minutes, which is low. Consider changing this to a few hours! But keep in mind that the replication does not automatically clear its cache in the Managed Runtime like we are used to in SFRA, but an API is available (hint, hint). ## API Caching When separating the head from the body, we still need a way for them to communicate. This is where various REST APIs, including SCAPI, come into play. These APIs also have a set of rules, including caching. This is just the start when we are heading into Composable territory; each piece of the puzzle has its own set of rules!. Some important caching caveats to be aware of: > **Not Found:** 404 responses for a GET call are automatically cached when the feature flag “Web Adapter Caching of 404 Responses for Dynamic Content” is enabled. > **Replication:** When replicating new code changes to the SCAPI or OCAPI, it’s important to remember that there is a 15-minute delay in cache clearing. This is because SCAPI and OCAPI caching are linked to the “Page Cache” setting that we are familiar with in SFRA and SiteGenesis. > **Clearing The Cache:** Currently, the only way to manually invalidate the cache is to invalidate the entire site page cache. In Business Manager, go to Administration > Sites > Manage Sites > Site Name - Cache, and then select the Cache tab. In the “Cache Invalidation” section, there is a button to invalidate the site page cache. Once you trigger the invalidation, the entire site page cache, including the cache related to SCAPI responses, will be cleared within 15 minutes. ### Standard API Salesforce B2C Commerce Cloud comes with many REST APIs out of the box (some you can extend, others you can not). These APIs have their own rules for caching and personalised caching. These rules have been documented [in the server-side web-tier caching guide](https://developer.salesforce.com/docs/commerce/commerce-api/guide/server-side-web-tier-caching.html); be sure to have a look! #### Feature Switch For most, this option will already be enabled or will not even be visible anymore in the business manager. But verify that Server-Side Web-Tier Caching has been enabled in your feature switches. (_Administration> Global Preferences > Feature Switches_) ![Business Manager feature toggle for enabling SCAPI server-side web-tier caching.](/caching-in-the-sfcc-composable-storefront/scapi-server-side-web-tier-caching-ead7ec1b79_hu_166435b552f1ff40.webp) Figure 1: Business Manager feature toggle for enabling SCAPI server-side web-tier caching The feature toggle in the Business Manager ### Custom & Customising APIs #### Adjusting caching Within a hook or custom endpoint you can modify the cache time with a simple line of code: `response.setExpires()` ```js exports.modifyGETResponse = function(scriptCategory, categoryWO) { response.setExpires(Date.now() + 3600000); return new Status( Status.OK ); } ``` ### Personalisation When personalisation is enabled for a resource, additional information such as active promotions, product sorting rules, price books, and ABTest groups becomes part of the cache key (besides the URL). This allows the cache to store different response variations and deliver the correct version to the API user based on this additional information. It’s important to use the [Shopper Context API](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-context) to apply changes in personalization-related resources and to append a custom query parameter to the URL (the primary unique key) for requests that are supposed to produce different responses due to conditional hook logic. You can also enable this within a hook or custom API with this line of code: `response.setVaryBy("price_promotion");` ```js exports.modifyGETResponse = function(scriptCategory, categoryWO) { response.setVaryBy("price_promotion"); return new Status( Status.OK ); } ``` --- ## Where can you "hook" into an SFRA request or controller? Canonical URL: https://rhino-inquisitor.com/where-to-hook-into-an-sfra-controller/ Markdown URL: https://rhino-inquisitor.com/where-to-hook-into-an-sfra-controller/index.md Content type: article Published: 2024-10-07T07:17:57Z Updated: 2024-10-07T07:35:26Z Summary: Have you ever wondered how Salesforce Commerce Cloud, especially SFRA (Storefront Reference Architecture), handles the rendering of pages based on Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, sfra, technical ## Key Takeaways - Explains the main extension points available around SFRA requests and routes, from global request hooks to route middleware and route events - Shows how prepend, append, and replace affect controller execution order and customization behavior - Highlights the importance of cartridge-path order and careful complexity management when layering multiple route customizations Have you ever wondered how Salesforce Commerce Cloud, especially [SFRA](/sitegenesis-vs-sfra-vs-pwa/) (Storefront Reference Architecture), handles the rendering of pages based on controllers and routes? It’s like embarking from point A to point B, with controlled detours and sudden stops. This blog will explore how SFRA allows us to navigate these situations and the various options available at different locations. Let’s dive in! ## Global Hooks Before we discuss the SFRA specifics, let’s start with some [global options](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/index.html?target=class_dw_system_RequestHooks.html) that allow us to execute code for any request (SFRA or not). For the technical details, please read [this blog post by Johnny Tordgeman.](https://medium.com/perimeterx/11-days-of-salesforce-storefront-reference-architecture-sfra-day-8-a-tale-of-two-events-fce297029857) ### onRequest The onRequest hook in SFCC allows you to intercept and modify an incoming HTTP request before the system processes it. This hook is commonly used for [session validation](https://github.com/SalesforceCommerceCloud/composable-hybrid-sitegenesis-poc/blob/0ceeef56aeab190a24378a0d7cae487477c18a16/cartridges/int_slas/cartridge/scripts/hooks/request/onRequest.js#L39), [request validation](https://github.com/SalesforceCommerceCloud/sfcc-hooks-collection/blob/b7f8d7c02b92cb1f449cb246073832626f227388/commerce-cloud-code/plugin_hooktacular/cartridge/scripts/hooks/onRequest.js#L13), or custom logging tasks. > **Cached URLs** > > This hook is executed for all requests, even if the Web Adapter (page cache) caches them. > **Dangerous** > > Whilst this hook provides a lot of flexibility, it also hooks into _every_ request. So, any exception or delay introduced by your custom code will be reflected on all pages and requests. ### onSession The onSession hook is a server-side hook executed at the beginning of each new session. This hook allows you to perform custom logic or set session attributes before the session is initialised. It can be used to customise the session behaviour (like [`plugin_slas`](https://github.com/SalesforceCommerceCloud/plugin_slas/blob/main/cartridges/plugin_slas/cartridge/scripts/hooks/request/onSession.js)), such as setting default values, checking for certain conditions, or performing any necessary setup before the session is fully established. > **Dangerous** > > Like the onRequest hook, any delay or exception introduced here can be devastating. ## SFRA Routes ![Standard Home.js controller with Show and ErrorNotFound routes.](/where-to-hook-into-an-sfra-controller/home-controller-routes-in-sfra-ca8b9d167a_hu_f9c19969fd170428.webp) The 'home.js' controller file of SFRA Before we get started, we need to ensure we are on the same page on what a “[route](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/blob/1cb2b329fa281333403bb2681b939e727aee809a/cartridges/modules/server/route.js)” is. In the context of SFRA (Storefront Reference Architecture) of SFCC (Salesforce Commerce Cloud), a controller route is a mapping between a URL and a specific controller function. When a user navigates to a specific URL within the SFRA storefront, the controller function, a key element of the SFRA architecture, handles the request and generates the appropriate response (usually ISML or JSON). The standard available options, and the most common ones, are: - GET - POST These will serve as the ‘base route’, the starting point of our project. But remember, this is just the beginning. We have the power to extend and customize this base route of SFRA, as we’ll discover in the options outlined in this blog post. ## SFRA Server functions to extend and replace > **Cartridge Path** > > In this example, we are assuming that there is only one extra cartridge in the cartridge path. This simplifies the explanation, as adding more than one cartridge to the path with an expanding function would make it more difficult to understand. ![Flow diagram of the standard Home-Show controller logic.](/where-to-hook-into-an-sfra-controller/home-show-sfra-controller-be0043f3bf_hu_4b626fc60ad11c6.webp) The standard Home-Show controller logic visualised ```text Cartridge path: plugin_custom:app_storefront_base ``` ### server.prepend() The `server.prepend` function adds a middleware function to the beginning of the route stack. This allows you to execute code before the base (`app_storefront_base`) processing begins. Here’s a simple example of how you can use `server.prepend` with the homepage function: ```js server.prepend('Show', function (req, res, next) { // Your code here will be executed before the app_storefront_base next(); }); ``` ![SFRA prepending of Home-Show](/where-to-hook-into-an-sfra-controller/sfra-prepend-home-show-de79cdab82_hu_fcc1c3831c9d3669.webp) Visualising what 'prepending' does in a single route (Home-Show) > **Fun Fact** > > Prepending was one of the first [pull requests](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/commit/3f471420e847ffeaf8fea9955a2f1481169a0e86) I had made to SFRA. ### server.append() The `server.append` function adds a middleware function to the end of the route stack. This allows you to execute code after the base (`app_storefront_base`) processing finishes. Here’s a simple example of how you can use `server.append` with the homepage function: ```js server.append('Show', function (req, res, next) { // Your code here will be executed after the show function in app_storefront_base next(); }); ``` ![SFRA appending of Home-Show](/where-to-hook-into-an-sfra-controller/sfra-append-home-show-f8e98c7dcd_hu_e93d91e5c51a6fd4.webp) Visualising what 'appending' does in a single route (Home-Show) ### server.replace() The `server.replace` function replaces the entire route stack up until that point. This allows you to replace code in the base (`app_storefront_base`) fully. Here’s a simple example of how you can use `server.replace` with the homepage function: ```js server.replace('Show', function (req, res, next) { var Site = require('dw/system/Site'); var PageMgr = require('dw/experience/PageMgr'); var pageMetaHelper = require('*/cartridge/scripts/helpers/pageMetaHelper'); pageMetaHelper.setPageMetaTags(req.pageMetaData, Site.current); var page = PageMgr.getPage('homepage'); if (page && page.isVisible()) { res.page('homepage'); } else { res.render('home/homePage'); } next(); }); ``` ![SFRA replacing of Home-Show](/where-to-hook-into-an-sfra-controller/sfra-replace-home-show-d90b35f072_hu_198f5928ca21f67d.webp) Visualising what 'replacing' does in a single route (Home-Show) ## SFRA Route Hooks The options explained above already give you quite a bit of flexibility. But what if I told you there is even more to come? The route itself also exposes a few “events” in which we can hook into: - **route: Start:** Executes at the start of the route, before any middleware defined using `server.*` - **route: BeforeComplete:** Executes after all route middleware is finished but before the “route:Complete” event. - **route: Complete:** The final event, after everything else. - **route: Step:** Executed between each route middleware. - **route: Redirect:** Executed when a “res.redirect()” is executed. ```js server.replace('Show', function (req, res, next) { this.on('route:BeforeComplete', function (req, res) { var viewData = res.getViewData(); // Your custom logic, executed at the end of the route }); next(); }); ``` ## Bringing it all together ![Combined diagram of SFRA route middleware and hook extension points.](/where-to-hook-into-an-sfra-controller/sfra-home-route-with-all-extension-points-2-7e4462fe3e_hu_e9529a55edbb1a45.webp) Bringing all of the options together! ## Multiple Cartridges The cartridge path influences the order in which SFRA middlewares are executed. Cartridges higher up in the path are given precedence over those lower down. This means that the middleware in cartridges at the beginning of the path will be executed before those in cartridges further down the path. New to the concept of “cartridge path”? Have a look at [this trail](https://trailhead.salesforce.com/content/learn/modules/b2c-cartridges/b2c-cartridges-explore)! > **Try to experiment** > > When working across multiple cartridges, make use of your debugger (e.g. Prophet) to check in what order your code is executed on the server side to understand the order of execution fully. > **Don’t go overboard** > > Remember that the complexity of adjusting a route is not something to brush over, especially if people often change on the project. Keep your code well structured and the order of execution of every middleware documented. --- ## It sure has been quiet on this blog. Canonical URL: https://rhino-inquisitor.com/it-sure-has-been-quiet-on-this-blog/ Markdown URL: https://rhino-inquisitor.com/it-sure-has-been-quiet-on-this-blog/index.md Content type: article Published: 2024-08-19T06:57:25Z Updated: 2024-08-19T06:57:31Z Summary: It sure has been quite a while since I made my last blog post; I even missed a release log - sorry about that. But why is that? Categories: Community Tags: ohana, sfcc ## Key Takeaways - Explains the personal and professional reasons behind the recent slowdown in blog posting - Highlights side projects in smart home automation and Business Manager React tooling - Confirms the blog is continuing with a lower publishing cadence rather than shutting down It sure has been quite a while since I made my [last blog post](/the-latest-in-sfcc-version-24-7/); I even missed a release log - sorry about that. But why is that? And what have I been up to for the past two to three months? Is it the end of this blog? Adaptability is a defining trait of mine. I thrive on learning and embracing change. As my wife can attest, my interests are ever-evolving—some change monthly, while others take years to shift. Looking at my habits, she asked why I had yet to switch wives. (**_Note_:** I am not planning a switch ) ## Smart Home ![Nanoleaf wall panels configured to display the day's weather for the kids.](/it-sure-has-been-quiet-on-this-blog/img-7215-47b9f2d828_hu_8384dd744c2f140c.webp) Four months ago, one of those switches happened. I dove back into Home Automation, which I looked into a few years back during Corona. Still, I did something different: Blogging about Salesforce Commerce Cloud. But the itch didn’t go away and has risen again. If you were someone who looked at my GitHub, you might have noticed a new repository popping up a while ago: [https://github.com/taurgis/homebridge-iRobot-v2](https://github.com/taurgis/homebridge-iRobot-v2). Even though I mostly work in management and architecture at work, the itch to do development work never goes away—and this also provided me with a new way of experimenting with new things. The result? My ventilation system turns on and off depending on the temperature in the vents and outside, my awnings open based on sunlight readings, I can monitor the electricity usage of my heat pump, my kid’s wake-up light is now fully schedulable via my phone, and so much more… But if you also dabble in smart homes, you probably know it can cause headaches and a lot of debugging. However, the rewards of a fully automated home are worth the effort. Oh, and for those curious, I use Apple HomeKit, which has been a reliable platform for managing my smart home devices and automation. It also allows me to keep things on my local network, as I am trying to avoid “cloud services” for security purposes. ## Bringing React to the Business Manager Last year, I also started a project which, for now, is branded the “FastForward Business Manager Accelerator” (quite the mouthful, I know) to quickly build modules using React in the Business Manager. This has also taken away much of my time and allowed me to learn React and what it entails. When hearing about the new redesign of the Business Manager, this project seemed in jeopardy. Would my hard work still work? But last week, I was happy to confirm that it all still spins and turns how it should, with a few minor adjustments using the Shadow DOM. Maybe this is a reminder for some people: - A storybook-powered React component library - A storybook-powered React hooks library to talk to the Rest of the APIs of SFCC with little effort - A starter template, just like SiteGenesis, SFRA, and the PWA-Kit, to speed up getting started - … [FastForward Business Manager Accelerator demo recording](/it-sure-has-been-quiet-on-this-blog/fastforward-business-manager-accelerator.mp4) ![FastForward Business Manager Accelerator Storybook interface.](/it-sure-has-been-quiet-on-this-blog/fastforward-storybook-7ad70ee20d_hu_e60e14e158502a33.webp) ## Kids getting older I always wondered why people between their 30s and 40s sometimes disappeared from volunteering and returned some 10 years later. This year, I learned that keeping kids busy takes more time and effort once they pass 3 to 5 years of age 😂 As my kids grow older, I find myself more involved in their activities, from sports to camps, and even the inevitable clean-up duty. This means less time behind the screen, but it’s a sacrifice I’m more than willing to make for their well-being. I’m sure many of you can relate to this juggling act of work and parenting, and the personal sacrifices it often entails. ## A lot of work to do in difficult times The retail and commerce industry has been in a bad spot for the past two years. It has been hit with one surprise after the other, with many people losing their jobs as massive cuts are made within Salesforce, customers, and partners alike. I have seen several brands file for bankruptcy or put up for sale in the past year. The proof that this is happening is very real, with many available profiles on the market with a vast amount of experience, but combined with companies having to watch their budgets tightly and becoming unable to afford the available talent. Quite a few brands have disappeared from the market, even those that have been around for decades. There is no room for mistakes, making experimentation quite risky for many. This is something we notice around the world, which also means that I need to focus on the bullseye to ensure that we keep our place in this world—a battle that I am not fighting alone. ## So what about the blog Rest assured, the blog remains a significant part of my life, albeit currently on a lower priority. I’ve decided to adjust the posting frequency to monthly, but the blog is here to stay, a testament to my unwavering commitment to sharing with you all! --- ## SFCC 24.7 Release Focused on Speed and Security Canonical URL: https://rhino-inquisitor.com/the-latest-in-sfcc-version-24-7/ Markdown URL: https://rhino-inquisitor.com/the-latest-in-sfcc-version-24-7/index.md Content type: article Published: 2024-07-08T07:51:29Z Updated: 2024-07-08T07:53:46Z Summary: In some places there is too much rain, in other places it is too hot. The weather might not be consistent, but the release schedule of SFCC sure is! Categories: Release Notes, Salesforce Commerce Cloud Tags: release notes, sfcc, technical ## Key Takeaways - Highlights the most relevant 24.7 changes across WAFv2 migration, search performance, staging origin shielding, and SCAPI enhancements - Explains the release themes of speed, security, and better operational tooling for both storefront and headless teams - Calls out related PWA Kit and tooling updates that teams should verify as part of their upgrade cycle In some places there is too much rain, in other places it is too hot. The weather might not be consistent, but the release schedule of SFCC sure is! This time we look at the [July 2024 (24.7) release](https://help.salesforce.com/s/articleView?id=sf.b2c_rn_24_7_release.htm&type=5)! Are you interested in last month’s release notes? Read the [24.6 release overview](/what-is-new-in-sfcc-24-6/). ## Migrate to eCDN WAFv2 > Salesforce B2C Commerce now uses eCDN with WAFv2. WAFv2 brings advanced security features to safeguard all your zones, both existing and new. You can migrate your existing customer zones from WAFv1 to WAFv2 as a self-service option. You can configure eCDN WAFv2 settings directly through the Business Manager UI or CDN Zones API for new zones. In addition, eCDN with WAFv2 integrates ruleset enhancements that improve firewall security and reduce false positives, improving threat detection accuracy and minimizing disruptions to normal operations. I may be a recording on repeat, but security for any online platform is a must. With the new WAFV2, we get: - Automated OWASP ruleset updates (based on the official code repository) - eCDN-managed rules managed by the Salesforce Security Team - Automated exposed credential checks How do you migrate? Click the “**Start WAFv2 Migration**” button in the Business Manager eCDN configuration screen, and get going! ## Platform ### Search Response Times Are Quicker > B2C Commerce has improved the performance of the common category lookup in storefront search and search refinement. Based on internal testing, the search engine calculates search refinements two times faster. With improved search, your users experience faster storefront response times, providing a smoother browsing experience. I am excited to see that the built-in search engine is receiving a lot of attention this year. It’s not only adding new features but also enhancing existing ones! Improved performance is always a great addition to new releases, especially if we don’t have to do anything extra! ### Get Enhanced Security with TLS v1.3 > The B2C Commerce service framework now supports TLS v1.3 for outgoing HTTP calls made from the platform. TLS v1.3 provides enhanced security features that don’t require complex configuration. It offers modern encryption standards that protect against known vulnerabilities and supports secure integration with third-party partners. If you encounter connectivity issues while using TLS v1.3, contact Support for assistance. And yet another platform update, this time for security, where we do not have to modify anything! Verify integrations With any update such as this, verify all third-party integrations before this release hits your production instance! ### Implement Enhanced Security Controls in Commerce Cloud > Commerce Cloud is implementing a new security measure that blocks traffic to staging instances that doesn’t originate from Commerce Cloud eCDN from accessing the hyphenated demandware.net hostname. This change rejects all calls using ‌hyphenated hostnames, such as staging-, to access the Open Commerce API (OCAPI) or Storefront. > > The introduction of Origin Shielding for staging impacts Commerce Cloud customers who currently have implementations that involve direct calls to POD IPs. > > You can create a proxy zone on Staging instances through the Business Manager and configure a custom hostname with an automatically renewing eCDN Managed certificate for added protection. Verify integrations With any update such as this, verify all third-party integrations before this release hits your production instance! **Step 1: Effective Date** When: The new security measure will be effective from October 7, 2024. **Step 2: Impact Assessment** This change will impact customers who directly call POD IPs in their Commerce Cloud implementations. **Step 3: Preparing for the Change** How to prepare: 1. _Evaluate_: Check your current implementations for any calls made to OCAPI or Storefront that use direct POD IPs, dot-form hostnames, or hyphenated hostnames like staging.xxx.demandware.net or staging-xxx.demandware.net. 2. _Update_: Modify any services or applications to use the vanity hostname instead, ensuring that traffic routes through eCDN. 3. _Create a Proxy Zone_: Use the Business Manager to set up a proxy zone in the Staging instances. Then, configure a custom hostname with an eCDN-managed certificate that renews automatically for extra security. **Step 4: Seeking Assistance** If you need more information or help with this transition, please contact your Customer Service Manager (CSM). ## OCAPI & SCAPI ### Shopper Context now supports Geolocation Site ID The siteId is required from now on! With this new release, we have a new addition to the shopper context: [Geolocation](https://developer.salesforce.com/docs/commerce/commerce-api/guide/shopper-context-geolocation.html)! While geolocation is not 100% trustworthy in some use cases (VPN, …), it is a handy tool to make an educated guess on the physical location of a customer. ### New endpoint: External Sitemap Upload > This API uploads a custom sitemap and triggers the sitemap generation process. Previously, integrating third-party sitemaps into Commerce Cloud was possible, though it required manual work, a job, or some custom coding. With this [new API](https://developer.salesforce.com/docs/commerce/commerce-api/references/seo?meta=uploadCustomSitemapAndTriggerSitemapGeneration), external systems can push a custom XML to Commerce Cloud and start the updating process! ### Collect Request Details > With B2C Commerce version 24.7, you can generate a JSON document that contains comprehensive information about the request. This JSON document is beneficial for troubleshooting, because it provides detailed information that is not included with standard logging, such as request authorization, hook execution, request query parameters, headers, and body. Another excellent debugging tool has been added to the list, allowing you to investigate what is happening behind the scenes. Within these details, there are some interesting metrics: - Hook execution time - Authentication information - Scopes used - Request runtime in MS - … Want to find out more? [Go here](https://developer.salesforce.com/docs/commerce/commerce-api/guide/collect-request-details.html). ### Server-Side Web-Tier Caching > Server-Side Web-Tier Caching is automatically turned on for all instances that don’t use /shopper-product/products and /shopper-search API endpoints on their Production instances. As with anything happening “automatically”, please verify on your production instances everything you have implemented is still working as expected: [https://developer.salesforce.com/docs/commerce/commerce-api/guide/server-side-web-tier-caching.html](https://developer.salesforce.com/docs/commerce/commerce-api/guide/server-side-web-tier-caching.html) ### SCAPI updates also on the main “release notes” Finally, the SCAPI release information has also made it to the “main” release notes site! But if I can nitpick a bit, the formatting still requires some work. [https://help.salesforce.com/s/articleView?id=sf.b2c\_com\_api\_june\_2024.htm&type=5](https://help.salesforce.com/s/articleView?id=sf.b2c_com_api_june_2024.htm&type=5) ## Development ### Import and Export Dynamic Categorization Rules > n Business Manager, easily import and export dynamic categorization rules, including the excluded product list. The Catalogs Import & Export feature now updates the catalog.xsd schema with detailed information on categorization rules and excluded products within the catalog tag structure. Previously, you couldn’t import and export the dynamic categorization rules. Before this update, we could not easily back up or import the categorisation rules from an external system, making them more challenging to implement in some cases (or even a blocker). This update can back up these rules and allow external control. This will be extremely helpful in preserving the hard work of our merchandisers. ### Import External Coupon Redemptions > You can now update the status of a coupon redeemed outside of B2C Commerce using the new Coupon Redemption API (/organizations/{organizationId}/coupons/actions/redeem). To identify the source of redemption for an external coupon, use a custom reference ID or any custom string. You can also add an optional email address to the redemption for further tracking and communication. To update multiple coupon redemptions at one time, use the new ImportCouponCodeRedemptionsStep job step. This bulk import, which works only in merge mode, streamlines the process of managing multiple redemptions at scale. This is a big update for any business working in multiple online and offline channels. With this update, we can [batch import](https://help.salesforce.com/s/articleView?id=cc.b2c_coupons_and_coupon_code_object_import_export.htm&type=5) or have a third-party system call the brand new “[Coupon Redemption API](https://developer.salesforce.com/docs/commerce/commerce-api/references/coupons?meta=redeemCoupon&q=redemption)”. ## PWA Kit v3.6.0 - [https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.6.0](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.6.0) A big release focusing on many different areas important to any project: Support for new APIs, performance, and accessibility! ### Improvements - **Product Tile Revamp**: Displays different pricing for various products on product tiles and PDP, and shows pricing on cart, checkout, and wishlist pages. - **Promotional Callouts**: Promotional messages are now visible on product list and detail pages. - **Selectable Swatch Groups**: Attributes like color can now be selected via swatch groups. - **Badges and Lazy Basket Creation**: New badges are displayed, and baskets are created lazily to improve performance. - **Cache Control**: Implements the `stale-while-revalidate` directive for better caching. ### Accessibility Enhancements - Added live region support to components. - Replaced `<p>` tags with heading tags on the cart page. - Improved alt text for product tile images. - Added `aria-hidden` to the search icon and explicit headers to the cart modal. - Autocomplete is now available for text input fields, and error messages include an error icon. ### Performance Improvements - Navigation components now load their categories lazy, enhancing performance. ### Bug Fixes - Fixed SEO component to correctly set the keywords meta tag. - Resolved issues with the RecommendedProducts component toggling the favourite icon. ## Bugfixes [Many ticket](https://issues.salesforce.com/#sortCriteria=%40sflast_modified_date_external__c%20descending&f[sfcategoryfull]=Commerce%7CB2C%20Commerce)s were moved to “Solution in development” or “Solution Scheduled”. ## Updated Cartridges & Tools ### composable-hybrid-sitegenesis-poc (v2.2.0) - [https://github.com/SalesforceCommerceCloud/composable-hybrid-sitegenesis-poc](https://github.com/SalesforceCommerceCloud/composable-hybrid-sitegenesis-poc) > This repository demonstrates a proof of concept (POC) for implementing SLAS and phased rollouts on SiteGenesis. The examples given use the latest version of SiteGenesis, using JavaScript controllers, but the same approach could be used on pipeline versions of SiteGenesis. - upgrade to plugin\_slas 7.3.0 by [@sandragolden](https://github.com/sandragolden) in [#16](https://github.com/SalesforceCommerceCloud/composable-hybrid-sitegenesis-poc/pull/16) --- ## What is new in Salesforce Commerce Cloud 24.6? Canonical URL: https://rhino-inquisitor.com/what-is-new-in-sfcc-24-6/ Markdown URL: https://rhino-inquisitor.com/what-is-new-in-sfcc-24-6/index.md Content type: article Published: 2024-06-03T12:04:25Z Updated: 2024-06-03T12:04:39Z Summary: "Connections" is in our rear-view mirror, but some new updates to the platform are ahead! This time, we look at the June 2024 (24.6) release! Categories: Release Notes, Salesforce Commerce Cloud Tags: headless, ocapi, release notes, sfcc, technical ## Key Takeaways - Highlights the most relevant 24.6 updates across Commerce Concierge, search and SEO improvements, new APIs, and service-framework changes - Explains what the release means for both headless teams and Business Manager users, especially around preferences, sorting, and SCAPI support - Calls out the related cartridge and tooling updates that teams may want to track alongside the platform release “[Connections](/salesforce-connections-2024-and-sfcc/)” is in our rear-view mirror, but some new updates to the platform are ahead! This time, we look at the [June 2024 (24.6) release](https://help.salesforce.com/s/articleView?id=sf.b2c_rn_24_6_release.htm&type=5)! Are you interested in last month’s release notes? [Read the 24.5 release notes](/getting-secured-with-the-24-5-salesforce-b2c-commerce-cloud-release/)! ## Commerce Concierge has arrived > Offer your shoppers bots that provide multichannel conversational product recommendations and add products to the cart with the new Commerce Concierge for B2C Einstein Bot template. Create an enhanced bot from the template and connect your store to a new Einstein bot. You can also use the new Commerce Concierge bot blocks to add functionality. AI has been the talk of the year at Salesforce and beyond, and finally, the first fruits of these talks have become available to us. Unfortunately, with all these new features also comes a license that needs to be purchased - Commerce Concierge or Shopper Copilot is no different. Contact your Salesforce account executive to purchase the Einstein Bots and digital Engagement add-on, and to get the set-up started, head over to this [documentation page](https://help.salesforce.com/s/articleView?id=sf.comm_set_up_commerce_concierge_for_a_b2c_store.htm&type=5). ## Platform ### Venezuela VED and VES Currency Codes Are Supported > Merchants doing business in Venezuela can now use the VED, VES, and VEF currency codes. Previously, only VEF was supported. Salesforce Commerce Cloud already had quite an extensive list of supported currencies and [localisations](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-localization.html%27). It is good to see that Salesforce is still investing in expanding into more regions. ### Get Improved Search Index Performance > B2C Commerce has updated the search index rebuild process. The update decreases resource usage and improves performance, and an unchanged index is no longer published when no changes are detected. Previously, a redundant product update index task was executed following the index rebuild, and a new search index was published when no documents were altered. When managing multiple sites within a single environment or dealing with a large product catalog, the search index job can take a considerable amount of time to execute. Any performance improvement to the search index is highly appreciated! ### Get Better SEO Search Results > In Business Manager, the Catalog URL rules now use the localizable display value for product attributes with the type Enum of String. The localizable display value improves readability and the SEO value of storefront URLs that use multiple languages. Previously, Product URL attributes used the non-localizable Value. It’s a bit of a confusing title, but the general idea is that your SEO will improve if you wanted to use localised “Enum of String” values in your URL before - but it didn’t work the way you expected. With this new update you can optimise your URL structure for SEO with this new attribute support (if it applies). PWA Kit By default, the PWA Kit does not use this feature - meaning that this update does not apply to your project unless custom development has happened. ## Business Manager ### Create Active Data Sorting Rules ![Search Index Query Testing tool showing active-data sorting support.](/what-is-new-in-sfcc-24-6/search-query-testing-tool-sfcc-8fb16cf218_hu_b946a31fd2d49b95.webp) > The Search Index Query Testing (SIQT) tool now supports sorting rules with active data sorting attributes. Get consistent sorting results in a storefront and when testing an active data sorting rule. Previously, if a sorting rule with active data was used in SIQT, the sorting used text relevance and didn’t consider active data. **How:**To access the SIQT tool, in Business Manager, select** Merchant Tools | Search | Search Index Query Testing**. With this new update, we are finally able to correctly test our sorting rules, which makes our lives just a little bit easier when debugging what is going on in the storefront. ## OCAPI & SCAPI ### New preferences API > The new Preferences API allows you to retrieve Site and Global preferences. There’s been a continuous addition of new APIs to the SCAPI in recent months. This is great news for everyone working on Headless and PWA Kit projects. Read all about the new [Preferences API here](https://developer.salesforce.com/docs/commerce/commerce-api/references/preferences?meta=Summary). ### Shopper Custom Objects API limit added > Shopper Custom Object API scopes are now limited to 20 entries. This is now enforced in both SLAS API and SLAS Admin UI. A “quota limit” has been added to the [Custom Objects API](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-custom-objects?meta=Summary). Please keep this update in mind if you are close to or past this new platform governance rule. ### Error message clarification > SLAS IDP integration has enhanced error handling to return more meaningful error messages to the caller. No change in error code information. The refined error message: “The Account is disabled” is returned for any user account disabled in B2C Commerce. No change in the error code. A small update to make debugging life just a little better. ### Multiple SLAS sessions for a single USID on a single device > SLAS now allows shoppers to have multiple clients and authenticate on the same device with a single USID, provided the clients use their respective refresh\_tokens to refresh their sessions. This might not be the most common use-case, but does open the door for more complex session related use-cases. ### Better SCAPI bundle support > With B2C Commerce version 24.5, the Shopper Baskets API supports patching variations within product bundles in a single call. This enhancement provides: > > - More efficient and streamlined product bundle management, making it easier to update multiple variations within a bundle without the need for multiple API calls. > - Increased productivity for developers managing complex product bundles. Bundle support in the PWA Kit (and headless in general) was not known to provide the best experience. Over the past two years, updates have been made in multiple locations to improve this experience. Let’s keep em coming! ### Order Search Engine Provides Better Performance > The search engine that provides results for the order\_search API (OCAPI) has been updated across multiple instances. This update is aimed at enhancing the performance of the search engine. No user impact or behavioral change is expected. In the last few months, the performance updates have been hitting one after the other, this time for the “Order Search” API. We’ll take any increase in speed for the APIs, especially one that contains essential data and is often used by third-party integrations. ## Development ### Service Framework Is Upgraded > B2C Commerce is upgrading the supported SFTP algorithms in the service framework. The algorithms now include: > > - Host Key—ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, rsa-sha2-512, rsa-sha2-256, ssh-rsa, ssh-dss > - Key Exchange (KEX)—curve25519-sha256, [curve25519-sha256@libssh.org](mailto:curve25519-sha256@libssh.org), ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1, diffie-hellman-group-exchange-sha1, diffie-hellman-group1-sha1 > - Cipher—aes128-ctr, aes192-ctr, aes256-ctr, [aes128-gcm@openssh.com](mailto:aes128-gcm@openssh.com), [aes256-gcm@openssh.com](mailto:aes256-gcm@openssh.com), aes128-cbc, 3des-ctr, 3des-cbc, blowfish-cbc, aes192-cbc, aes256-cbc > - Message Authentication Code (MAC)—hmac-sha2-256-etm@openssh.com, [hmac-sha2-512-etm@openssh.com](mailto:hmac-sha2-512-etm@openssh.com), [hmac-sha1-etm@openssh.com](mailto:hmac-sha1-etm@openssh.com), hmac-sha2-256, hmac-sha2-512, hmac-sha1, hmac-md5, hmac-sha1-96, hmac-md5-96 > - Public Key Authentication—rsa-sha2-512, rsa-sha2-256, ssh-rsa It has been a while since any changes were made to the Service Framework. With this update, we now have better support for SFTP algorithms and security options, which is always great to see! ## Updated Cartridges & Tools ### b2c-tools (v0.25.1) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances and administrative APIs (SCAPI, ODS, etc). It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. - support specifying features dir for API use by [@clavery](https://github.com/clavery) in [#135](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/135) ### plugin\_passwordlesslogin (v2.0.0) - [https://github.com/SalesforceCommerceCloud/plugin\_passwordlesslogin](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin) > Passwordless login is a way to verify a user’s identity without using a password. It offers protection against the most prevalent cyberattacks, such as phishing and brute-force password cracking. Passwordless login systems use authentication methods that are more secure than regular passwords, including magic links, one-time codes, registered devices or tokens, and biometrics. - brought cartridge up to date so that it works alongside the latest plugin\_slas, v7.3.0 - updated login forms and email to include the new 8 digit pin code instead of a direct link for login - added SCAPI custom API endpoint that handles the auth and email send for composable --- ## Salesforce Connections 2024 and B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/salesforce-connections-2024-and-sfcc/ Markdown URL: https://rhino-inquisitor.com/salesforce-connections-2024-and-sfcc/index.md Content type: article Published: 2024-05-16T09:28:06Z Updated: 2024-05-16T09:28:17Z Summary: Preview of Salesforce Connections 2024 for SFCC teams, with the most relevant commerce sessions, roadmap talks, and meetup picks. Categories: Community, Salesforce Commerce Cloud Tags: event, sfcc ## Key Takeaways - Previews Salesforce Connections 2024 from an SFCC-focused attendee perspective - Curates the most relevant B2C Commerce and composable-storefront sessions across both event days - Helps community members prioritize overlapping sessions, roadmap content, and meetup opportunities The wait is almost over. Next week, it is time for Salesforce Connections 2024. I can’t believe it has already been two years since then—and that one was quite memorable, as I was last [awarded my Golden Hoodie](/events-and-the-golden-hoodie/) during the keynote! So, what does this iteration of Connections have in store for us? Will there be enough content for B2C enthusiasts to keep us occupied for two full days? ## No epic concert at Connections ![Wide stadium view from the upper stands looking down at the concert stage.](/salesforce-connections-2024-and-sfcc/img-4015-9ece77c62f_hu_4896ec7187ce0aac.webp) Let’s pull this cat out of the bag before discussing Commerce Cloud-related matters. For a long time, we got used to getting an epic concert one of the evenings of the event, but that does not seem to be the case this time. It is unfortunate, but it should also technically not be the only reason you got to an event like this (although I have to admit it was always a blast). And not to worry—in its place comes “Connections Celebration,” which will appeal to some people more than the concert—you can’t please everyone! > The Connections Celebration brings together everyone for an end-of-day celebration with entertainment, networking, and fun. DJ Jem, the pinnacle of Chicago nightlife entertainment, will be setting the mood, while cirque performers will surprise and delight from the theater stages. Plus, we’ll have three unique photo opportunities to indulge in. And what’s a celebration without snacks? Delicious bites, along with spiked coffee stations, top tier wine, and nonalcoholic mocktails, will be available throughout the celebration. ## Agenda for B2C Even though your planned agenda may not turn out exactly as expected, it’s still helpful to keep track of important events and schedule changes using the events app and the Connections agenda builder. I haven’t included all sessions related to Commerce Cloud in this list. This is more of a compilation of sessions that I plan to join, unless my agenda ends up completely different as usual. ### Wednesday May 22 #### [Composable Success in B2C Commerce](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1708477055712001uVgz) - 8:45 AM - 60 Minutes - Round Table ( ROOM W185, Level 1) Thinking about moving to a composable storefront? Did you already implement headless or composable? Learn how others are building unique headless and composable experiences on B2C Commerce. #### [Lacing Up for Success: ASICS’ Path to Composable Commerce](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1707187014107001Umk4) - 9:00 AM - 20 Minutes - Theater Session (Campground, LEVEL 3) Learn about ASICS Digital’s multiphased transition to headless and how its API-led approach supports an ecosystem of sites and apps, with improved digital experiences and operational efficiencies. #### [Future-Proof and Modernize B2C to Accelerate Growth & Scale](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1707187026922001UUDj) - 9:30 AM - 20 Minutes - Theater Session (Campground, LEVEL 3) Learn how Samsonite accelerated its journey to a modern B2C experience with Red Van’s Autobahn platform, migrating eight commerce sites in nine months, resulting in growth that topped expectations. #### [How VF Corp Unified a Multi-Brand Business with B2C Commerce](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1707186998517001UJ9s) - 11:45 AM - 20 Minutes - Theater Session (Campground, LEVEL 3) Learn how VF Corp launched iconic brands leveraging SFRA, Composable Storefront, Commerce APIs, Marketing Cloud, and MuleSoft, enabling flexibility and unique branded experiences. #### [Power Growth Everywhere with the #1 AI Commerce Platform](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1706836533453001c4dh) - 12:30 PM - 50 Minutes - Keynote (Room W375, LEVEL 3) Join us for groundbreaking innovations designed to help any business quickly increase sales and reduce costs by activating commerce on the #1 AI Platform for Commerce. #### [Go Headless, the Future of Online Storefronts](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1709855362609001YnVl) - 12:45 PM - 20 Minutes - Theater Session (Campground, LEVEL 3) Learn how to leverage new headless offerings from Buy with Prime, exclusively for Commerce Cloud, to optimize costs, architecture flexibility, and build world-class shopping experiences. #### [How Grilla Grills Drove 3x Site Performance in 4 Months](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1707186997988001U2Ap) - 01:45 PM - 20 Minutes - Theater Session (Campground, LEVEL 3) Learn how Grilla Grills was able to launch with Salesforce Commerce Composable Storefront in just four months. The company saw a 318% faster time to launch, driving more revenue to its business. #### [How Commerce Cloud Delivers 100% Uptime Over the Holidays](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1707186999747001UJxH) - 02:45 PM - 20 Minutes - Theater Session (Campground, LEVEL 3) Learn how commerce innovations in trust and scale ensure the platform is highly available, performant, and secure, to ensure business success — and peace of mind — during your peak shopping events. #### [Win the Digital Experience: B2C Commerce Roadmap Deep Dive](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1706836533834001c0Lh) - 04:00 PM - 40 Minutes - Breakout Session (Room W179, LEVEL 1) Get a sneak peek into the future of B2C Commerce. Discover innovations empowering customers to activate commerce across all channels, maximizing revenue with the most comprehensive platform. #### [Optimizing Operations: Enhanced Business Manager Experience](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1708477056673001ubPL) - 04:15 PM - 60 Minutes - Roundtable (Room W185, LEVEL 1) Get a sneak peek into our new business manager experience and discover how it is driving efficiency, increasing conversion, and fueling revenue growth. ### Thursday May 23 #### [Win the Digital Experience: B2C Commerce Roadmap Deep Dive](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1706836533834001c0Lh) (Thursday May 23) - 04:00 PM - 40 Minutes - Breakout Session (Room W183AB, LEVEL 1) Get a sneak peek into the future of B2C Commerce. Discover innovations empowering customers to activate commerce across all channels, maximizing revenue with the most comprehensive platform. #### [Adyen Global Payments on Salesforce’s Composable Storefront](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1707187028700001UEWg) - 02:45 PM - 20 Minutes - Theater Session (Campground, LEVEL 3) Learn about Salesforce’s latest integration with Adyen that streamlines global payments for your customers, ensuring a swift, secure, and efficient checkout experience for your e-commerce business. #### [Composable Success in B2C Commerce](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1708477055712001uVgz) (Thursday May 23) - 8:45 AM - 60 Minutes - Round Table ( ROOM W185, Level 1) Thinking about moving to a composable storefront? Did you already implement headless or composable? Learn how others are building unique headless and composable experiences on B2C Commerce. #### [Driving Commerce Innovation Through Slack and Open Source](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1707187013338001Ure5) - 12:15 PM - 60 Minutes - Round Table ( ROOM W185, Level 1) Explore how the Unofficial SFCC Slack Community and open source foster collaboration, innovation, and growth — ultimately driving business success. #### [Commerce Developer and Architect Unconference](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog/session/1706836533834001c0Lh) - 04:00 PM - 60 Minutes - Roundtable (Room W185, LEVEL 1) Remember the days when Connections was XChange? We’re bringing back a popular technical meetup, where the community decides and discusses topics. Bring your ideas and get ready to collaborate. ## A lot of people to meet and sessions to do The above agenda concludes that decisions will need to be made. Several sessions overlap, but fortunately, many are scheduled more than once, allowing for some flexibility. I, for one, am excited about the added attention the #CommerceCrew has received, which gives us ample opportunities to meet up! See you at [Connections](https://reg.salesforce.com/flow/plus/cnx24/sessioncatalog/page/Catalog)? --- ## What's New in the SFCC 24.5 Security Release Canonical URL: https://rhino-inquisitor.com/getting-secured-with-the-24-5-salesforce-b2c-commerce-cloud-release/ Markdown URL: https://rhino-inquisitor.com/getting-secured-with-the-24-5-salesforce-b2c-commerce-cloud-release/index.md Content type: article Published: 2024-05-03T11:25:41Z Updated: 2024-05-06T07:48:10Z Summary: Again, it is time for the monthly Salesforce B2C Commerce Cloud release! This time, we look at the May 2024 (24.5) release! Categories: Release Notes, Salesforce Commerce Cloud Tags: release notes, sfcc, technical ## Key Takeaways - Highlights the major 24.5 security and extensibility changes across eCDN, baskets, and headers - Explains why WAFv2 and storefront order allow lists matter for stronger platform security - Calls out new headless capabilities and deprecations teams should review before upgrading Again, it is time for the monthly Salesforce B2C Commerce Cloud release! This time, we look at the [May 2024 (24.5) release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_24_5_release.htm&type=5)! Are you interested in last month’s release notes? Read the [24.4 release overview](/getting-to-know-the-sfcc-24-4-release/). ## Platform ### Five Minute Minimum Period Enforced for WAF Log Retrieval > A minimum period of five minutes is now enforced for retrieving WAF logs. This enhancement prevents setting the end time for log requests within five minutes of the current time. This update aims to provide more reliable and complete logs—nothing much to say about this. ### Upgrade Your Security Posture with eCDN WAFv2 > B2C Commerce announces the upgraded version of our eCDN, now featuring WAFv2, bringing a host of advanced security features to safeguard your online presence. Here’s what you can expect with eCDN WAFv2: > > - **Open Web Application Security Project (OWASP) Ruleset Integration:** The eCDN OWASP Core Ruleset integrates the latest OWASP ModSecurity Core Rule Set (CRS). Your CDN provider routinely monitors for updates from OWASP based on the latest version available from the official code repository. > - **eCDN Managed Rules:** Provide fast and effective protection for all your applications. The rule set is frequently updated to address emerging vulnerabilities and reduce false positives. > - **eCDN Exposed Credentials Check:** A managed ruleset of pre-configured rules for well-known CMS applications. The ruleset conducts a check against a public database of stolen credentials. > - **Configurability via Business Manager UI and CDN Zones API:** With this update, configuring the eCDN WAFv2 settings is now accessible through the Business Manager UI and for new zones, through the CDN Zones API. > - **Reduced False Positive Detections:** The upgraded WAFv2 includes updated managed rulesets that reduce false positives. The rulesets enhance threat detection accuracy while minimizing disruptions to your normal operations. This is a significant update to the WAF! Increasing security is always on everyone’s mind, so getting an upgrade is much needed. This is one of the parts of Commerce Cloud over which we had little control until last year. With all updates on the SCAPI side (and also UI) related to security and now this upgrade, we are finally getting some control over everything happening in Cloudflare behind the scenes. ## Business Manager ### Refine and Customize Promotions > The Business Manager Promotion Refinements feature now offers expanded support for custom product attributes. With this update, users can now create refinable promotions that utilize custom localizable product attributes, as well as custom product attributes of type enum-of-string and enum-of-int. This enhancement addresses the previous limitation where Business Manager users could not set up refinable promotions with these specific custom attribute data types or localizable attributes. This update might seem small to some, but it dramatically impacts the flexibility of an already flexible promotion engine. Using localised attributes means that regional promotions just got a lot easier! ## OCAPI & SCAPI ### Custom Headers > You can now use the Script API response object to set custom response headers. Finally, we get access to our custom headers! This is another excellent addition that opens [more flexibility](https://developer.salesforce.com/docs/commerce/commerce-api/guide/extensibility_via_hooks.html?q=c_#custom-headers) for headless projects. ### External Taxation Mode > With B2C Commerce 24.5, You can use external taxation mode with the Shopper Baskets API when hooks are enabled. For details, see External Taxation Documentation. It is well known that filling in all the necessary data in the [Tax Tables](https://help.salesforce.com/s/articleView?id=cc.b2c_tax_table_object_import_export.htm&language=en_US&type=5) of Commerce Cloud can be challenging for some regions worldwide. This is where third-party systems come into play to ease the burden of this task. Now, with [a clear path](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-baskets?meta=Summary) to follow in Salesforce Commerce Cloud’s headless space, integrating these third-party systems has become much easier. However, it’s important to protect these endpoints from unauthorised access and potential misuse. When following the link, we are greeted with this documentation: The B2C Commerce API calculates taxes internally using tax tables. If you want to integrate with a third-party tax provider or calculate taxes on your own, you can use the external taxation feature to add a taxation rate and optional taxation value. When setting a taxation rate, the taxation is calculated for this specific rate. If you pass a value, this value is used as a taxation value, as well, without recalculation. To use this feature, set the `taxMode` parameter externally when creating the basket. When using external taxation, you must set a tax rate either in one request to the `/baskets/{basketId}/taxes` or with separate requests for each line item, using `/baskets/{basketId}/items/{lineItemId}/taxes`. If the tax mode of a basket is set to `external`, a tax item is required for all line items, even for zero-tax items, to avoid oversights. ### Deprecation Notification > The following Shopper Baskets (v1 and v2) endpoints are deprecated and are no longer supported: > > - addPriceBooksToBasket > - getPriceBooksForBasket If you are using any of these APIs, take this into account. However, no documentation on these endpoints yet gives alternatives. ## Development ### Enhance Order Access Security with the Allow List > Enable the Allow-List feature on the Limit Storefront Order Access setting if you aren’t yet limiting Storefront Order Access at all. This feature enhances security and control over who can access orders and which controllers can access order functions. **How:** In Business Manager | Orders | Order Preferences. Set the Limit Storefront Order Access dropdown to Allow List. Enter allowed storefront controllers as a comma-separated list. Only the controllers on the allow list can access customer orders. For projects on SiteGenesis or SFRA, we now have more fine-grained control over Order Access security now. However, we should always aim to secure everything. But this option provides us with additional choices, which is always beneficial. ## Account Manager ### Upcoming Removal of Deprecated Roles in Account Manager > Salesforce is removing deprecated roles from Account Manager. To prevent any disruption in your organization’s workflow, ensure you aren’t using the deprecated roles. How: Review the list of deprecated roles that are slated for removal. Reassign any users currently using these roles. For assistance with reassigning roles, see Edit a User Account. The affected roles include: > > - SLAS Organization Admin role (Deprecated for API Clients only) > - XChange roles > - Documentation User, Documentation Linguist, Documentation Reviewer > - statuspage.io User > - Business Manager Partner > - CQuotient Configurator Administrator > - Order Management Admin > - Order Management User A bit of cleaning up is happening here! But if you use these roles in an “old” automation routine, you might want to remove them to avoid exceptions. ## PWA Kit v3.5.x > - Add Support for SLAS private flow #1722 > - Fix invalid query params warnings and allow custom query #1655 > - Fix cannot read properties of undefined (reading ‘unshift’) #1689 > - Add Shopper SEO hook #1688 > - Update useLocalStorage implementation to be more responsive #1703 > - Storefront Preview: avoid stale cached Commerce API responses, whenever the Shopper Context is set #1701 There is a new [release](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.5.0) of the PWA Kit, with the most significant addition being support for an SLAS private flow. This update should boost performance, as fewer API calls are needed to get the ball rolling! This also offers an excellent example of how to securely do these kinds of integrations without exposing credentials. ## Updated Cartridges & Tools ### b2c-tools (v0.25.0) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances and administrative APIs (SCAPI, ODS, etc). It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. - Bugfix - corrects path for types in package.json by [@nick11703](https://github.com/nick11703) in [#133](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/133) - Feature - allow reading certificate from buffer by [@nick11703](https://github.com/nick11703) in [#134](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/134) ### plugin\_slas(v7.3.0) - [https://github.com/SalesforceCommerceCloud/plugin\_slas](https://github.com/SalesforceCommerceCloud/plugin_slas) > This cartridge extends authentication for guest users and registered shoppers using the Shopper Login and API Access Service (SLAS). - Reduce session churn on hybrid sites [#187](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/187) - Use refresh token expiry from SLAS [#154](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/154) - Update OCAPI version regex to allow double digit minor numbers [#182](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/182) - Add support for SLAS private clients [#178](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/178) --- ## The sunsetting of ARC300 (Architect B2C Commerce Solutions) Canonical URL: https://rhino-inquisitor.com/the-sunsetting-of-arc300-architect-b2c-commerce-solutions/ Markdown URL: https://rhino-inquisitor.com/the-sunsetting-of-arc300-architect-b2c-commerce-solutions/index.md Content type: article Published: 2024-04-29T07:43:13Z Updated: 2024-04-29T07:46:01Z Summary: Trailhead Academy, Salesforce's official learning platform, offers a wide range of courses that help individuals acquire the new skills and knowledge Categories: Salesforce Commerce Cloud Tags: sfcc, trailhead academy ## Key Takeaways - Explains the significance of the sunset of ARC300 for Commerce Cloud architects and learners preparing for the architect credential - Adds a personal instructor perspective on what the course meant, who it served, and why its retirement matters - Points readers toward alternative preparation paths while speculating on what a future replacement course may emphasize [Trailhead Academy](http://trailheadacademy.salesforce.com/my-learning), Salesforce’s official learning platform, offers a wide range of courses that help individuals acquire the new skills and knowledge needed to succeed in the ever-evolving world of technology. Among these, the ARC300, also known as the ‘Salesforce Architect B2C Commerce Solutions’ course, held significant importance. This recently sunsetted course was a crucial resource for experienced B2C Commerce Technical Leads, Solution Architects, B2C Commerce Developers, Technical Directors, Owners of Technical Design and Quality Implementations, and anyone aspiring to earn their Salesforce B2C Commerce Architect credential. So, what now? Let me go back a few years in time first, as I was one of the few instructors of this course. ## Could I do it Has it been three years already? It seems like only yesterday that I was asked whether I would be interested in teaching a course about architecture within Salesforce B2C Commerce Cloud. Honestly, it took little persuasion to get me to do this, although I was wondering whether or not I would have the skills to convey the required knowledge to others. It is one thing to know everything about Salesforce B2C Commerce Cloud. However, it is another to pass on that knowledge to others via a virtual class—it was still in the minds of the coronavirus crisis, so Salesforce had crossed physical courses off the list. Honestly, I was glad for that fact—I could do it from the comfort of my own home. ## Quite the adventure But those fears turned out to be for nought, and I got great reviews from those who took my classes, which gave me the confidence to continue and offer two classes a year. Ultimately, companies even requested private courses, giving me more opportunities to learn and convey my knowledge. Each class gave me new insights from those participating, and hopefully, I was able to give them some new insights to tackle the projects they were doing and those in the future! ## To all good stories comes an end Unfortunately, all good things must come to an end, and the same goes for the ‘Salesforce Architect B2C Commerce Solutions’ course. In April 2024, the course was sunsetted, marking the end of an era for the individuals who had benefited from the knowledge and skills it provided. While it is always sad to see something you love come to an end, it’s important to remember its impact on the lives of those who could learn from it. It was a great learning experience to convey knowledge to others and explain concepts. ## Will there be a new course ![A group of people stands atop a mountain, overlooking a city where a Trailhead Academy cap hovers in the sky.](/the-sunsetting-of-arc300-architect-b2c-commerce-solutions/looking-to-the-future-of-trailhead-academy-86a27ca5fe_hu_52775388b1b13b66.webp) While the ‘Salesforce Architect B2C Commerce Solutions’ course may have been sunsetted, a new course can always replace it. With the ever-evolving world of technology, keeping up to date with the latest industry trends and knowledge is essential. Salesforce is known for its commitment to continuous improvement, and the Trailhead Academy platform is a testament to this. It is plausible that Salesforce is already working on a new course to fill the gap left by the sunsetted course. With the rise of Composable Commerce and the increasing demand for personalised customer experiences, the new course will likely also focus on B2C Commerce Cloud architecture and design, but with more of a focus on microservices architecture, headless commerce, and AI-powered personalisation. Although nothing has been confirmed yet, it is exciting to speculate on the future of Trailhead Academy and the Commerce Crew. ## How can I prepare for the Architect exam now Since no alternative course is available yet, you will have to resort to all resources available on [Trailhead](https://trailhead.salesforce.com/trails?products=commercecloud&sort=RELEVANCE), the [Partner Learning Camp](http://partnerlearningcamp.salesforce.com) (if you have access), and, of course, my [own blog](/the-b2c-commerce-architect-certification/), which has multiple resources available to get you started! If you are planning on taking the exam shortly, good luck! --- ## Getting to know the SFCC 24.4 Release Canonical URL: https://rhino-inquisitor.com/getting-to-know-the-sfcc-24-4-release/ Markdown URL: https://rhino-inquisitor.com/getting-to-know-the-sfcc-24-4-release/index.md Content type: article Published: 2024-04-01T08:03:24Z Updated: 2024-04-02T07:39:31Z Summary: It's that time of the year again! The April 2024 (24.4) release of Salesforce B2C Commerce Cloud is finally here, just in time for the spring season. Categories: Release Notes, Salesforce Commerce Cloud Tags: release notes, sfcc ## Key Takeaways - Highlights 24.4 changes around custom APIs, rogue query limits, and Page Designer image management - Explains new SCAPI and OCAPI behavior that can replace older customization workarounds - Flags security and operations changes like OCAPI token invalidation and staging eCDN management It’s that time of the year again! The [April 2024 (24.4)](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_24_4_release.htm&type=5) release of Salesforce B2C Commerce Cloud is finally here, just in time for the spring season. Let’s take a closer look at all the exciting new features and improvements this release offers. Are you interested in last month’s release notes? [Read the 24.3 release notes](/digging-into-the-b2c-commerce-cloud-24-3-release/)! ## Added support for additional HTTP methods for Custom APIs The newly enabled methods in 22.4 now allow us to create custom endpoints for any use-case (theoretically): - POST - PUT - PATCH - DELETE - HEAD - OPTIONS This update is highly anticipated by Headless projects, as it offers greater flexibility in the Composable Storefront than ever before! Read all about it [in the Custom APIs guide](https://developer.salesforce.com/docs/commerce/commerce-api/guide/custom-apis.html). ## Rogue Query Timeouts in B2C Commerce > To protect customer instances and associated services from outages, B2C Commerce restricts rogue queries that produce 200 thousand results or more. To better protect Salesforce B2C Commerce, Salesforce plans to limit the allowed offset value from 200 thousand to 10 thousand.. Salesforce’s Commerce Cloud B2C platform has restricted rogue queries producing 200,000 or more results to protect customer instances from outages. In the 24.6 Release in June 2024, the allowed offset value will be limited to 10,000. If a rogue query is generated, an error message will notify API users that the offset value needs to be set to under 200,000, while Business Manager calls will fail without the message. To reduce the risk of generating large queries, users are advised to make their queries more targeted via filters and offset values. What batch APIs can be used to still retrieve large datasets? - For orders - **[processOrders](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_order_OrderMgr.html#dw_order_OrderMgr_processOrders_Function_String_Object_DetailAnchor)** - **[Class OrderMgr](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_order_OrderMgr.html)** - For customers - **[processProfiles](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_customer_CustomerMgr.html#dw_customer_CustomerMgr_processProfiles_Function_String_Object_DetailAnchor)** - **[Class CustomerMgr](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_customer_CustomerMgr.html)** ```text application failed to invoke [search_protocol.search()] on server, responding with fault. exception was [com.demandware.core.rpc.server.InvocationException: exception while invoking operation], cause [org.elasticsearch.ElasticsearchIllegalArgumentException: Search request offset <value> is greater than offset limit 200000 for tenant '<GroupID>_<Instance>', type 'order'] ``` ## Manage More Images in Page Designer ![Page Designer media picker showing support for browsing up to 1,000 images in one folder.](/getting-to-know-the-sfcc-24-4-release/images-in-sfcc-page-designer-2ae797ab98_hu_7e752915df150cb4.webp) The media picker now shows up to 1,000 images per folder instead of 200. > The Page Designer image and media picker now supports up to 1,000 images per folder. Previously, only 200 images within a folder were accessible in the image picker, even if more existed. The increased image limit improves the user experience for merchandisers and content creators and avoids workarounds, such as creating subfolders for extra images. Since the introduction of Page Designer, users have been facing a recurring issue of images not being found due to the 200-image limit. This issue has been reported globally on a monthly basis. The good news is that the limit has been increased to 1000. This should provide some relief to users while setting up their pages. It is still not unlimited, so it is important to manage folders effectively to avoid reaching the 1000 limit in the near future. ## Business Manager​ ### Configure eCDN for Staging in Business Manager ![Staging Business Manager with Embedded CDN Settings highlighted.](/getting-to-know-the-sfcc-24-4-release/ecdn-config-in-business-manager-staging-a7d7b2d965_hu_b18f05903fa501f2.webp) Staging now exposes eCDN setup in Business Manager instead of through support tickets. > Business Manager now supports configuring eCDN for staging environments. eCDN settings are specific to each instance (development, staging, and production), and you manage them individually. When you create a proxy zone in production, the zone doesn’t replicate a corresponding proxy zone in your development or staging instance. The new eCDN configuration feature simplifies onboarding new sites for staging instances, making it easier to mimic your production instance. Because the configuration uses the existing CDN-API, you can use either Business Manager or the API to manage your eCDN configurations. It feels like only yesterday that I [published my blog post](/how-to-set-up-the-ecdn-in-sfcc-staging/) on how to upload certificates to the staging environment. With this latest release, we can now use the same user interface that we use in production and development. This is a great update that should simplify our lives, especially considering that in the past, we had to rely on support to get this done. ### Auto-Correction is Disabled by Default ![Searchable Attributes settings showing Autocorrection defaulting to No.](/getting-to-know-the-sfcc-24-4-release/searchable-attributes-in-commerce-cloud-db3ab0524f_hu_9924ce771237aacf.webp) Autocorrection now defaults to No for new searchable attributes, which helps protect technical fields like SKU. > The default setting for auto-correction for searchable attributes added after the B2C Commerce 24.4 release is now set to No. This change affects searchable attributes added through the Business Manager UI or via import. Existing configurations aren’t affected. Previously, when you added a searchable attribute, the default setting was Yes, which could cause issues in instances when search functions shouldn’t correct values, such as the product SKU, ID, or ISBN. Additionally, the auto-correction dictionary’s size can incrementally increase over time, leading to search noise. A small change has been made to remedy some confusion that can occur while configuring attributes. The Autocorrection feature is now a manual action that needs to be taken by the user, instead of being set by the system by default. This is a nice change that will improve the overall user experience. ## OCAPI & SCAPI ### productSearch gets more data > With B2C Commerce 24.3, expanded the Shopper Search API productSearch endpoint to include additional parameters: productPromotions, imageGroups, priceRanges, and variants Hooks have been a go-to patch for information like this for a while now, and being able to replace these customisations with platform-native solutions will help keep our projects maintainable. Hook cleanup time! ### New API: searchCustomerGroup > Search for customer groups in a given Site Id. The query attribute specifies a complex query that can be used to narrow down the search. With each new release, a new API seems to appear—[this time](https://developer.salesforce.com/docs/commerce/commerce-api/references/customers?meta=searchCustomerGroup), one for the “management” side of things. ### New API: Shopper Custom Objects API > Use the Shopper Custom Objects API to retrieve custom object information. You can specify an object type ID as well as a key attribute for the object. Another use case where the [OCAPI](/in-the-ring-ocapi-versus-scapi/) is no longer required, and we can access Custom Objects in our composable projects more easily. ### Check for Customization with SCAPI > Two new SCAPI response headers are available to check for custom requests and resulting hook execution errors. Two new headers have made their way into the SCAPI: 1. **`sfdc_customization`**–indicates whether customization has been applied during the request execution. Currently, the only possible value for the header is “HOOK”, which indicates that a hook execution was registered. 2. **`sfdc_customization_error`**–if the value is “1", an error occurred within a hook execution. This is a great addition that will allow us to get more information on the client side of what is going on and take some of the guesswork out of it. ### OCAPI JWT Response to Updated Passwords Is Changed > To enhance security and align with the SLAS JWT session handling, we updated how the OCAPI JWT handles password changes. Now, if your customer changes their password, all previously issued active OCAPI JWTs are invalidated. The OCAPI client receives an HTTP 401 response, accompanied by a body message that indicates an invalid access token. Previously, the JWT remained valid until its normal timeout. ```text “fault”: { “arguments”: { “accessToken”: “Customer credentials changed after token was issued. Please Login again.” }, “type”: “InvalidAccessTokenException”, “message”: “The request is unauthorized, the access token is invalid.” } ``` Security is a serious matter, and automatic deactivation of active sessions is a valuable update that can give peace of mind. We can also use the information from the response to inform customers of what is happening. Unfortunately, the error message does not have a unique identifier, only an “English” message, making translating or creating a key slightly more challenging. ## Updated Cartridges & Tools ### b2c-tools (v0.21.1) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances and administrative APIs (SCAPI, ODS, etc). It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. - support parent traversal in page designer library ### plugin\_passwordlesslogin (v1.2.2) - [https://github.com/SalesforceCommerceCloud/plugin\_passwordlesslogin](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin) > Passwordless login is a way to verify a user’s identity without using a password. It offers protection against the most prevalent cyberattacks, such as phishing and brute-force password cracking. Passwordless login systems use authentication methods that are more secure than regular passwords, including magic links, one-time codes, registered devices or tokens, and biometrics. - exclude scapi calls from onSession logic by [@sandragolden](https://github.com/sandragolden) and [@clavery](https://github.com/clavery) in [#18](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin/pull/18) --- ## How to migrate passwords from Magento using Argon2 Canonical URL: https://rhino-inquisitor.com/migrate-magento-passwords-using-argon2/ Markdown URL: https://rhino-inquisitor.com/migrate-magento-passwords-using-argon2/index.md Content type: article Published: 2024-03-27T08:47:32Z Updated: 2024-03-28T15:01:14Z Summary: Learn how to migrate Magento passwords with Argon2, preserve account access, and plan a safer authentication transition. Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, technical ## Key Takeaways - Explains the gap between Magento Argon2 password hashes and SFCC's native import capabilities - Provides a Node.js verification script that can validate Magento-style Argon2 hashes during migration - Recommends a secure transition pattern where migrated accounts are upgraded after successful legacy-password verification As a developer, you might encounter situations where you need to [migrate](https://osapishchuk.medium.com/legacy-customers-password-migration-3fa1596303cc) data from one platform to another securely. This requires handling sensitive data like passwords with utmost care. In the case of Magento, password hashing is done using the Argon2 algorithm (depending on the Magento version, your mileage may vary), which is known for its security and resistance against brute force attacks. Now, if you’re migrating from Magento to Salesforce B2C Commerce Cloud, you need to make sure that the passwords are securely migrated as well. The bad news is that Salesforce B2C Commerce Cloud does not support the Argon2 algorithm out of the box for importing. The good news is that I managed to migrate a Python script to Node.js that verifies the Magento password hash using the Argon2 algorithm. ## TL;DR; The script I have created a [script](https://osapishchuk.medium.com/legacy-customers-password-migration-3fa1596303cc) that can be used for various purposes. However, I would strongly suggest using it only for educational purposes or with proper authorisation. You can just change this script to meet your specific needs. For example, you can use it to develop a microservice for migrational purposes with proper authorisation. ### hashes.txt ```text ab5ebf8d273b085b6a60336198e0a5a2090fdc3e0606a678315c7274ab06e046:5PiKJRn28bBKoFMopMaaKuV47aJ6GzVg:3_32_2_67108864 ``` ### wordlist.txt ```text Password1 Password2 Password@ Password3 ``` ### Script ```js const argon2 = require('argon2'); const fs = require('fs'); const readline = require('readline'); const path = require('path'); const hashFilePath = path.join(__dirname, 'hashes.txt'); const wordlistFilePath = path.join(__dirname, 'wordlist.txt'); /** * Verifies the given hash string with the given password. * * @param {string} hashString - The hash string to verify. * @param {string} password - The password to verify the hash with. * * @returns {Promise} */ async function verifyHash(hashString, password) { const split = hashString.trim().split(":"); if (split.length !== 3) { console.log(`Invalid hash format: ${hashString}`); return; } let [hash, salt_b64, version] = split; if (version === "2" || version === "3") { version += "_32_2_67108864"; hashString = `${hash}:${salt_b64}:${version}`; } const salt = Buffer.from(salt_b64.substring(0, 16)); const versionInfo = version.split("_"); if (versionInfo.length !== 4) { console.log(`Invalid version format: ${hashString}`); return; } const hashLength = parseInt(versionInfo[1]); const hashTimeCost = parseInt(versionInfo[2]); const hashMemory = parseInt(versionInfo[3]) / 1024; password = Buffer.from(password.trim()); const result = await argon2.hash(password, { salt, type: argon2.argon2id, memoryCost: hashMemory, timeCost: hashTimeCost, parallelism: 1, hashLength: hashLength, raw: true }); const hexHash = result.toString('hex'); if (hexHash === hash) { console.log(`${hashString.trim()}:${password.toString()}`); } } /** * Processes each line of the file at the given file path. * * @param {string} filePath - The path to the file to process. * @param {Function} processLine - The function to process each line of the file. * * @returns {Promise} */ async function processFile(filePath, processLine) { const fileStream = fs.createReadStream(filePath); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { await processLine(line); } } /** * Processes each hash string in the hash file and verifies it with each password in the wordlist file. */ processFile(hashFilePath, async (hashString) => { await processFile(wordlistFilePath, async (password) => { await verifyHash(hashString, password); }); }).then(() => { console.log("Done"); }); ``` ## Breaking It Down ### Dependencies The code relies on the `argon2` library to hash passwords securely using the Argon2 algorithm, which should not come as a surprise. The downside is that this module is written in C, which makes it impossible to use in the back-end of Commerce Cloud. It is possible to migrate (probably), but it would require a significant amount of effort. It also uses the `fs` module for reading files, `readline` for processing lines, and `path` for handling file paths. ### VerifyHash This function takes a stored hash (`hashString`) and a candidate password (`password`). It performs the following steps: - Parses the hash string into its components (hash, salt, and version). - Adjusts the version if needed. - Extracts the salt. - Retrieves information about hash length, time cost, and memory cost. - Computes a new hash using Argon2 with the same parameters. - Compares the computed hash with the stored hash. - If they match, it logs the hash and the original password. #### Version Information Luckily, Magento stores the required parameters for Argon2 in its version number, which can be extracted for our purposes: _hash _:_ salt_: **3\_ 32\_2\_ 67108864** ## Conclusion Although Commerce Cloud does not support Argon2 by default, this workaround is available. You can create a Microservice in Node.js to enable frictionless migration for customers. During login, you can call the service to verify the entered credentials and update the Commerce Cloud password with the available plain text password. After the migration, you should have an attribute to turn off this service call for that account to avoid unnecessary calls. Security As we are dealing with sensitive data, it is crucial to ensure that your service is built securely and that hashes or passwords are never exposed to the outside world. --- ## In the ring: OCAPI versus SCAPI Canonical URL: https://rhino-inquisitor.com/in-the-ring-ocapi-versus-scapi/ Markdown URL: https://rhino-inquisitor.com/in-the-ring-ocapi-versus-scapi/index.md Content type: article Published: 2024-03-18T08:49:51Z Updated: 2024-03-19T15:11:36Z Summary: As we move into 2024, the SCAPI has received much attention and has been updated with new APIs, updates, and performance improvements. Categories: Architecture, Salesforce Commerce Cloud Tags: headless, sfcc, technical ## Key Takeaways - Compares OCAPI and SCAPI across platform strategy, authentication, architecture, and extensibility - Argues that SCAPI is where major new investment and APIs are landing - Explains why OCAPI still matters because SCAPI and existing integrations still depend on it As we move into 2024, the SCAPI has received much attention and has been updated with new APIs, updates, and performance improvements. On the other hand, the OCAPI rarely gets any new features in its release notes, leading some to believe it is outdated or deprecated. In this article, I will explore this topic in detail to determine whether or not these claims are accurate. So, let’s get rumbling! ## OCAPI versus SCAPI Salesforce B2C Commerce Cloud has a long-standing history with its OCAPI, which offers a broad range of APIs for various purposes. One typical integration that highlights the functionality of these APIs is [Newstore](https://www.newstore.com). This mobile application solution uses customisation hooks in the provided cartridge to integrate with the APIs. The SCAPI, or Storefront Commerce API, is a relatively “new” set of APIs introduced on [July 22, 2020](https://help.salesforce.com/s/articleView?id=sf.sf_com_api_W7858177_ga_release.htm&language=nl_NL&type=5). It offers a different way of interacting with SFCC (Salesforce Commerce Cloud) from third-party systems and headless front-ends than the way we had been doing with the OCAPI (Open Commerce API) before. However, there is one drawback to the SCAPI: not all APIs that exist in the OCAPI are available in the SCAPI, at least not yet. Let’s keep score, shall we? **OCAPI:** 1 **SCAPI:** 0 ## New APIs In recent years, the SCAPI has introduced several [new APIs](/category/release-notes/) that the OCAPI does not have. These new APIs have been implemented to address OCAPI gaps or expose new functionality, such as those related to SEO and CDN, allowing for more robust and comprehensive functionality. SCAPI now offers a wide range of APIs for developers to use, allowing them to build customised solutions for their clients. As these new APIs have been developed explicitly for SCAPI, it is unlikely that the OCAPI will ever have access to them. In the future, it is clear that any significant new APIs will only be added to the SCAPI, which aligns with the platform’s strategy. **OCAPI:** 1 **SCAPI:** 1 ## SLAS [SLAS](/how-to-set-up-slas-for-the-composable-storefront/), or Shopper Login and API Access Service, is a Salesforce Commerce Cloud (SFCC) feature allowing third-party systems or headless front-ends to authenticate shoppers and make API calls. It’s an authentication orchestration service that can handle various scenarios without requiring the creation of custom code for each one separately. (Some tweaking of parameters and configuration is still required, but that’s not the focus of this article.): - **B2C Authentication:** Normal login with Salesforce B2C Commerce Cloud - **Social Login** (Third-party login): Login with platforms such as Google and Facebook - **Passwordless Login:** Login via e-mail or SMS - **Trusted Agent:** Have a third-party person or system login on behalf of a customer Although it is possible to use this service in conjunction with OCAPI, it is more part of the SCAPI offering, so let us give a point to SCAPI in this case. **OCAPI:** 1 **SCAPI:** 2 ## PWA Kit Have you heard about the PWA Kit or [Composable Storefront](/the-move-from-sitegenesis-and-sfra-to-the-composable-storefront-as-a-developer/)? You may have, as it’s the latest addition to the front-end options besides SiteGenesis and SFRA. The Composable Storefront is a Headless storefront that connects to the back-end SFCC systems through the SCAPI. Although it used to be connected to the OCAPI due to some limitations with the [hooks](/how-to-use-ocapi-scapi-hooks/) system, the latest version is now fully connected to the SCAPI. It’s no secret that the Composable Storefront is the primary driver for these innovations. Another point to SCAPI! **OCAPI:** 1 **SCAPI:** 3 Oh my … things aren’t looking proper for the OCAPI. ## Infrastructure ![The Composable Storefront architecture](/in-the-ring-ocapi-versus-scapi/composable-storefront-architecture-54fe68c81a_hu_d5ec0b64656305dc.webp) The architectural setups of the OCAPI and SCAPI options are entirely different. The OCAPI runs on the back end, the exact location as the Business Manager, [SFRA/SG](/sitegenesis-vs-sfra-vs-pwa/) storefront, and your custom code. On the other hand, the SCAPI used to run through a MuleSoft instance managed by Salesforce. In the current architecture, CloudFlare workers have taken over that role. Although the SCAPI has an extra layer in between, it gives Salesforce the flexibility to make their architecture more flexible (and composable) by allowing them to have one point of entry while being able to upgrade, fix, or replace parts without anyone noticing. By replacing MuleSoft with CloudFlare, the amount of network delay introduced should be minimal. The OCAPI wins for its simplicity, but the SCAPI wins for its future-proof architecture. Nevertheless, this future-proof architecture can only work if it has been set up correctly, and we don’t have any view into that black box. So, for me, both of them get a point here! **OCAPI:** 2 **SCAPI:** 4 ## Rate Limits APIs can be enjoyable to work with, but they are also vulnerable to DDoS attacks and poor design, leading to excessive API calls and a heavy server load. Yet, the OCAPI is designed to be safe and user-friendly, and CloudFlare and Salesforce-managed firewalls protect it to ensure server safety and limit the number of requests. Although the rate-limiter is a straightforward “pass” or “block” method, it is essential to consider its impact and be prepared for the worst. Contract Info: On a side note, all OCAPI calls are counted as “Storefront Requests”, which are part of the contract. The SCAPI has implemented a new “Load Shedding” system to replace rate limits. This system provides a comprehensive view of what is happening behind the scenes. Not all APIs are the same Not all SCAPI endpoints work with this new system, but some are still protected with set rate limits. **OCAPI:** 2 **SCAPI:** 5 ## Conclusion The SCAPI outperforms the OCAPI in multiple ways, which is why the former was implemented. However, if you are still extensively using the OCAPI, there is no need to worry because you are not alone - even the SCAPI uses it behind the scenes. Many SCAPI API calls are just a proxy for OCAPI calls. Consequently, as long as the SCAPI depends on the OCAPI, it is not going anywhere. --- ## Two Years of Blogging in the SFCC Ecosystem Canonical URL: https://rhino-inquisitor.com/reflecting-on-2-years-of-blogging/ Markdown URL: https://rhino-inquisitor.com/reflecting-on-2-years-of-blogging/index.md Content type: article Published: 2024-03-11T20:17:04Z Updated: 2024-03-11T20:19:14Z Summary: A look back at two years of Rhino Inquisitor, the lessons behind the posts, and how the blog's focus has evolved over time. Categories: Community Tags: community, ohana ## Key Takeaways - Reflects on two years of Rhino Inquisitor and the impact the blog has had on the SFCC community - Explains the shift toward revising older articles as the platform evolves rather than only publishing new ones - Combines the anniversary update with future plans, a renewed MVP recognition, and personal creative interests I am delighted to announce that I have completed two years of my journey with the Rhino Inquisitor blog. This journey has been a blend of difficulties and achievements. I am fortunate to have had the opportunity to impart my knowledge and understanding to the constantly expanding group of developers, architects, and enthusiasts who are a part of the Salesforce B2C Commerce Cloud ecosystem. Hmm… that sounds like I’m quitting. Not to worry; it’s quite the opposite! I will continue on this journey, but let’s move on, shall we? ## How it all started When I [started](/pdf-and-salesforce-commerce-cloud-b2c/) the blog, I primarily focused on providing technical articles about development, architectural diagrams, and community-related topics. I wanted to help developers and architects better understand Salesforce B2C Commerce Cloud and its capabilities. Over the past two years, I have written many articles, released every week, covering a wide range of topics. I have seen my readership grow as more people discover the value (at least, that’s what I hope) of the information provided on the blog. I have received numerous comments and feedback from readers who have found my articles helpful in their work. ## Revising is necessary ![A hand holding a red pen, marking words in red that need correction.](/reflecting-on-2-years-of-blogging/revising-text-4905c7d647_hu_51bba36734a996cd.webp) However, reflecting on the past two years, I realise it is about more than just the numbers. What matters most is my impact on the community and the knowledge I have provided to others. I have seen people take the knowledge and insights they have gained from my blog and apply them to create solutions and drive their projects forward. As technology evolves, I recognise the importance of keeping my posts current. I am committed to revisiting my historical posts, updating them to match the current state of the platform and re-testing scenarios. I want to ensure everyone can access accurate and relevant information to help them achieve their goals. ## The coming year For the next year, I will continue to write articles, but at a slower pace, based on what I see happening in the ecosystem. My main focus will be to revise and update at least one article a week, ensuring that all the articles I have written provide accurate information to everyone who uses my blog. I have also been given another opportunity to contribute to the community, which I cannot disclose much about. This new project will require a significant amount of time and effort, and if I continue at the pace I am currently maintaining with my blog, I will not be able to do justice to either of them. However, this new endeavour will be worth the wait. ## Renewed as an MVP I am delighted to share that I have been selected as a Salesforce MVP for another year. Words cannot express how grateful I am for this recognition. The past few years have been a remarkable journey, and being acknowledged as a Salesforce MVP means that I am on the right path and should continue working with the same dedication and commitment. I want to thank everyone at [Forward](https://www.forward.eu), [Salesforce](https://www.salesforce.com/eu/?ir=1), and the [community](https://unofficialsfcc.com) for their support and guidance. I could not have achieved this success without their constant encouragement and motivation. Thank you all for helping me reach where I am today. The list of names to thank would be too long, but you know who you are! THANK YOU! ## Other things It’s been a while since I’ve indulged in one of my favourite hobbies, but recently, I’ve rediscovered my love for tinkering. Before the pandemic hit in 2020, I used to spend my evenings attending cooking and electrician classes and experimenting with Arduino and Raspberry PIs to create home automation systems. I had to put this passion on hold for a while, but I’m excited to dive back into it and see what new creations I can come up with. There’s something genuinely satisfying about taking a hands-on approach to learning and creating, and I’m looking forward to seeing where this rediscovered hobby takes me. ![Electronics tinkering workspace with components laid out for a hobby project.](/reflecting-on-2-years-of-blogging/1601710443407-d2c723ac02_hu_6240ca22f2c0a070.webp) --- ## Digging into the B2C Commerce Cloud 24.3 release Canonical URL: https://rhino-inquisitor.com/digging-into-the-b2c-commerce-cloud-24-3-release/ Markdown URL: https://rhino-inquisitor.com/digging-into-the-b2c-commerce-cloud-24-3-release/index.md Content type: article Published: 2024-03-04T09:04:46Z Updated: 2024-03-04T09:07:27Z Summary: As snowy days slowly turn into sunny ones, the 24.3 release of SFCC has arrived! Let us have a look at the March release of 2024. Categories: Release Notes, Salesforce Commerce Cloud Tags: release notes, sfcc, technical ## Key Takeaways - Highlights 24.3 changes affecting baskets, translations, SCAPI caching, and load shedding - Calls out new custom headers and Shopper Baskets v2 migration considerations - Flags operational changes like disabled scheduled backups and new Business Manager alerts As snowy days slowly turn into sunny ones, the 24.3 release of SFCC has arrived! Let us have a look at the [March release of 2024](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_24_3_release.htm&type=5). Are you interested in last month’s release notes? Read the [24.2 release overview](/a-look-at-the-salesforce-b2c-commerce-cloud-24-2-release/). ## Platform ## Add More Product Line Items per Basket ![Basket preferences showing the new default limit of 200 product line items.](/digging-into-the-b2c-commerce-cloud-24-3-release/basket-product-line-items-in-sfcc-d24a6fcde8_hu_5626031dca6f88f6.webp) > If your site was limited to 50 line items per basket, the maximum number is increased to 200. This new limit doesn’t affect users who have been granted a lower or higher limit. Quite a big uplift in the amount of different product line items allowed in a single basket by default. This will be particularly handy in certain industries such as groceries, gifting, and even some small B2B cases. ### Prioritize Resource Bundle Lookup > You can now change the order of the resource bundle lookup and give priority to the WebDAV resource bundle. The default lookup first checks the resource bundle IDs of the code cartridges assigned to your site and then checks WebDAV. If you have resource bundles with the same ID in the cartridge and WebDAV, the cartridge resource bundle is always selected over the resource bundle in the WebDAV location. You can now use a toggle to switch the order to check WebDAV first. A new feature toggle is now available under “Feature Switches” in the “Global” section of the Administration panel. This option will give a bit more flexibility in translation management and open new routes. Does anyone care to revisit [“Resource Manager”](https://github.com/SalesforceCommerceCloud/resource-manager)? ### Scheduled Backups Button Is Disabled > The Scheduled Backups button is no longer available. Instead, use a custom~~er~~ job to schedule backups of your production and development environments. The scheduled backup feature has been turned off on all PIG environments except for the staging environment. This feature was initially intended for the staging environment. So, most projects won’t be affected by this change. However, if you use this feature in other environments, you can use a system job step called [SiteExport](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/jobstepapi/html/api/jobstep.SiteExport.html) that you can schedule independently. ## Business Manager ### Display Alert Messages in Business Manager ![Notification settings showing banner, header, and homepage alert placements.](/digging-into-the-b2c-commerce-cloud-24-3-release/sfcc-alerts-business-manager-5ad8b6e1f2_hu_abc7dfe2553e9c91.webp) > Display alerts as a persistent banner on the top of every Business Manager page. Alerts can relate to Business Manager modules and are only visible to users with permissions to access the module. Salesforce might also use the enhanced alerting framework to display critical system messages to Business Manager users. A new option that is more prominent and cannot be ignored. To enable, go to Administration | Operations | Notification Settings in Business Manager and select the Banner alert type. ## OCAPI & SCAPI ### Prepare for Changes to Server-Side Web-Tier Caching > If you provision your SCAPI zone with short code, SCAPI caching is enabled by default after March 12, 2024, and the feature switch SCAPI Server-Side Web-Tier Caching has no effect. If you enroll in SCAPI before March 12, 2024, you can continue to enable SCAPI caching in Business Manager. To enable caching, in Business Manager, select Administration | Feature Switches, and turn on SCAPI Server-Side Web-Tier Caching. Performance is always a hot topic for any industry, and having Web-Tier cache active will hopefully have a significant impact on the performance of all headless channels. The new standard after March 12th Be sure to test all your channels with the feature switch enabled before March 12, when it becomes active! ## SCAPI - Shopper SEO > - Updated getUrlMapping’s response to include the optional property resourceSubType, which indicates whether the resolved object is a Page Designer content asset or a Content Slot asset. For more information, see the UrlMapping type reference. > - Updated getUrlMapping to support URL redirects. For more information, see the URL Resolution guide. > - Updated getUrlMapping to support these hooks: dw.shop.seo.url\_mapping.beforeGET and dw.shop.seo.url\_ mapping.modifyGETResponse. Some updates to the [URL mapping endpoint](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-seo?meta=getUrlMapping), which include support for [URL Redirection from the Business Manager](https://help.salesforce.com/s/articleView?id=cc.b2c_url_redirects.htm&type=5)! ## Shopper Baskets v2 > - Provides support for temporary baskets. Temporary baskets can perform calculations to generate totals, line items, promotions, and item availability without affecting the shopper’s storefront cart. You can use these calculations for temporary basket checkout. > - New Shopper Basket v2 response fields: > 1. groupedTaxItems > 2. taxRoundedAtGroup > 3. temporaryBasket > **Deprecation:** The dw.ocapi.shop.basket.beforePOST hook is no longer supported in Shopper Baskets V2 and is replaced by the dw.ocapi.shop.basket.beforePOST\_v2 hook. The new version for Shopper Baskets looks a bit different from v1, so adjust your customisations if you plan to upgrade. ## SCAPI Load Shedding > - If the system reaches a load threshold, an HTTP 503 response is returned for a subset of API families. > - Covers APIs not covered by rate limits that are considered non-critical, for example: endpoints related to search, products, and authentication. Load shedding is not used for checkout-related endpoints, such as Shopper Baskets and Shopper Orders, to ensure that shoppers can complete an in-progress checkout. > - Includes additional HTTP response headers that allow you to understand the current system load: sfdc\_load, which represents a load percentage with higher percentages indicating higher loads, and sfdc\_ load\_status, which is a enum WARN|THROTTLE that helps you understand the relative health of the system. We received a notification regarding removing rate limits for SCAPI endpoints some time ago. Instead, a new system called Load Shedding has been introduced. This system allows us to monitor the performance of the APIs based on different response headers that have been added. If necessary, we can also introduce our safety features. While this system gives us more control, it also introduces a new scenario to take into account. ## Custom Request Headers > Developers can send custom request headers that are passed and made available in server-side custom implementations. It is now possible to add custom headers to your requests to use in your customisations on the server-side. **Pattern:** c\_{yourHeader} ## Account Manager ### Security Update for the Audit History Logs > Starting with the 1.32.2 release, the full name and full email address for active audit history users are masked from administrators. Masking occurs when the active user isn’t part of the organization and they’re active in Audit History for a User, Organization, or API Client sessions. Masking is also used when organization users view their audit history on the start page. The mask improves security compliance. A minor update for security compliance. ## Bugfixes Quite the list of bug fixes this time! - [SLAS generates Access token successfully for disabled customer](https://issues.salesforce.com/issue/a028c00000yy3tiAAA/slas-generates-access-token-successfully-for-disabled-customer) - [SCAPI Merge basket functionality does not carry over the bonus line item to registered shopper basket](https://issues.salesforce.com/issue/a028c00000x9LCOAA2/scapi-merge-basket-functionality-does-not-carry-over-the-bonus-line-item-to-registered-shopper-basket) - [Warn messages logged for SCAPI shopper-products](https://issues.salesforce.com/issue/a028c00000yD1VUAA0/warn-messages-logged-for-scapi-shopper-products) - [Storefront on behalf of a customer is failing to access from chrome due to google enforcing to block 3rd party cookies](https://issues.salesforce.com/issue/a028c00000yEhQAAA0/storefront-on-behalf-of-a-customer-is-failing-to-access-from-chrome-due-to-google-enforcing-to-block-3rd-party-cookies) - [Localization: FirstDayOfWeek - DatePicker uses Language Locale instead of Country Locale](https://issues.salesforce.com/issue/a028c00000xB1ZuAAK/localization-firstdayofweek--datepicker-uses-language-locale-instead-of-country-locale) - [SCAPI Error Response is not Correctly JSON Encoded](https://issues.salesforce.com/issue/a028c00000xB0sgAAC/scapi-error-response-is-not-correctly-json-encoded) ## Updated Cartridges & Tools ### plugin\_passwordlesslogin (v1.2.1) - [https://github.com/SalesforceCommerceCloud/plugin\_passwordlesslogin](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin) > Passwordless login is a way to verify a user’s identity without using a password. It offers protection against the most prevalent cyberattacks, such as phishing and brute-force password cracking. Passwordless login systems use authentication methods that are more secure than regular passwords, including magic links, one-time codes, registered devices or tokens, and biometrics. Update feature so that callbacks, redirects, and scopes are not overwritten. ### composable-hybrid-sitegenesis-poc (v2.1.1) - [https://github.com/SalesforceCommerceCloud/composable-hybrid-sitegenesis-poc](https://github.com/SalesforceCommerceCloud/composable-hybrid-sitegenesis-poc) > This repository demonstrates a proof of concept (POC) for implementing SLAS and phased rollouts on SiteGenesis. The examples given use the latest version of SiteGenesis, using JavaScript controllers, but the same approach could be used on pipeline versions of SiteGenesis. Although we are already at v2.1.1, this repository is new and its first release. ### b2c-tools (v0.20.0) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances and administrative APIs (SCAPI, ODS, etc). It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. - bdw.js rename and updates by [@jlbruno](https://github.com/jlbruno) in [#119](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/119) - Updating readme instructions for local project install by [@jlbruno](https://github.com/jlbruno) in [#120](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/120) - added intellij support for groups by [@sandragolden](https://github.com/sandragolden) in [#121](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/121) --- ## The journey from developer to architect Canonical URL: https://rhino-inquisitor.com/the-journey-from-developer-to-architect/ Markdown URL: https://rhino-inquisitor.com/the-journey-from-developer-to-architect/index.md Content type: article Published: 2024-02-26T06:36:00Z Updated: 2024-02-26T10:26:22Z Summary: A personal look at the move from developer to architect, including the mindset shifts, trade-offs, and lessons that mattered most. Categories: Corporate Tags: architect, developer, ohana, sfcc ## Key Takeaways - Explains the different architect roles and how they relate to Salesforce and Commerce Cloud work - Describes the practical shift from hands-on development toward meetings, responsibility, documentation, and solution ownership - Offers a personal perspective on deciding whether the move from developer to architect is the right next step So you want to be an [architect](/what-skills-do-i-need-as-a-sfcc-architect/), do you? At least, that is why I am guessing you came to this page! Well, you came to the right place! I have gone through this transition myself, and here are some topics I wanted to write about the role. ## What is an architect ![Salesforce Architect branded t-shirt from the Shirtforce community store.](/the-journey-from-developer-to-architect/salesforce-architect-65b8ca1808_hu_dad3a09ca24ce3ef.webp) The Salesforce Architect Shirtforce shirt is where career milestone meets community identity—a badge of the role you can wear quite literally. But first things first, let us define what an architect is before we go any further. We will not be designing buildings. If that is why you are here, you came to the wrong blog! Let us first dig into the different types of architects. Do you look surprised? Yes, there are multiple types, each of which has a different role in this world. ### Solution Architect ![Illustration introducing the Solution Architect role.](/the-journey-from-developer-to-architect/solution-architect-4a4b8fdff7_hu_16c55ec8036697c5.webp) Solution Architects translate business challenges into product and service recommendations, drawing on a broad view of Salesforce offerings and third-party options to answer each question. If we have to define a Solution Architect in a few sentences, it would be to evaluate all business requirements and develop the best solutions by proposing products and services. Solution Architects are given a business challenge/problem and are tasked with coming up with the answers to these questions. Solution Architects keep a high-level overview of all the different systems and their capabilities to make the best decisions for a specific business question. After weighing all the pros and cons, they propose various possibilities to answer the question. If we look at this role within Salesforce, solution architects understand all ( or a reasonable amount ) of Salesforce’s offerings to provide solutions using them. And, of course, if there is no product within the Salesforce ecosystem, look at third-party vendors to fill in the gaps. Are you interested in B2C Solution Architecture? Then be sure to read the [Salesforce B2C Solution Architect’s Handbook](https://www.amazon.com/Salesforce-Solution-Architects-business-consumer/dp/1801817030), authored by [Mike King](https://www.linkedin.com/in/mikeeking/). ### Enterprise Architect A completely different type of architect than the Solution Architect. The main goal of an Enterprise Architect is to validate the solutions provided to the business and that they are aligned with the organisation’s strategy. An Enterprise Architect has a top-level overview of the organisation regarding knowledge, capabilities, and potential. I could write an elaborate article on this, but I will forward you [an excellent article on Apex Hours](https://www.apexhours.com/salesforce-enterprise-architecture/). ### Technical Architect ![Illustration introducing the Technical Architect role in Salesforce.](/the-journey-from-developer-to-architect/salesforce-technical-architect-01186ac1bd_hu_2b3af1890524e47c.webp) Technical Architects go deep in one platform domain and own its hard engineering decisions. The final one in this list is the Technical Architect, the most specialised one. This type of architect will take a single part or implementation of the big puzzle and focus on that. They will focus on this domain and gain in-depth knowledge that the Enterprise and Solution Architect lacks. If we look at the Technical Architect certification within Salesforce, these Architects have a deep knowledge of everything related to the Salesforce CRM system. They know the ins and outs of all the different cogs that make that system work - and make them work for them, which is not an easy feat! To learn more about it, you can go to [Trailhead](https://trailhead.salesforce.com/en/credentials/technicalarchitect?&utm_source=salesforce&utm_medium=blog-360&utm_campaign=trailblazer_blog&utm_content=careers_nov21_what_is_an_architect&icid=SFBLOG:tbc-blog:7010M0000025ltGQAQ). ### Putting them together If we look at the different architects listed above, it is clear that they work as a team to get “things done.” Each has its specialisation and stakeholders to get projects towards the finish line. I am a Technical B2C Commerce Cloud Architect moving to a Salesforce B2C Solution Architect if I look at myself. I have specialised knowledge of B2C Commerce Cloud platform and a high-level understanding of different clouds within and outside the Salesforce domain. Using that knowledge, I look at business cases to develop solutions using Salesforce products (or third-party solutions), mainly connecting them with Salesforce B2C Commerce Cloud. ## The journey But I am getting ahead of myself; how does everything change if you go from being a developer to an architect? Well, a lot will change! ### Development One of the most significant changes going from developer to architect (or any lead position for that matter) is that the amount of time a day you spend writing code will go down dramatically. And that is something you need to prepare yourself for. You will handle the theoretical more and guide others to implement the practical. ### Meetings ![A group of people in a meeting room, conversing with a group of people online.](/the-journey-from-developer-to-architect/meetings-c1c58511a8_hu_9bb42c5b104f89ab.webp) Architect roles trade coding time for requirements, alignment, and decision-making across teams. One of the reasons you will be doing less development is because you will be in many more meetings than before. You will be gathering requirements from a client, internal discussions about architecture, follow-up meetings to answer questions you still have and many more reasons to have meetings. People will also contact you more with questions about decisions that have to be made and help support the team during development (without developing yourself). ### Responsibility Do not take the title ‘architect’ lightly. You will lay the groundwork for the projects in any of the different types. If this is not done correctly, things can go awry rather quickly. It is the same with, and yes, I will compare with buildings, civil architecture. If the groundworks are shabby, the building will topple over sooner or later. A large proportion of the success or failure of a project lies with the architect, so be prepared to shoulder it! ### Make yourself heard Get used to voicing your opinion toward your colleagues and your clients. Since you will be shouldering a large proportion of the responsibility, be sure that your views are heard and taken into account. So, learn to be vocal and get used to talking to all types of people. You will be doing it a lot! And remember: it is OK to make mistakes, but take responsibility for them! ### Documentation / Analysis Instead of writing code, you will write text to support the team doing the implementation and the business. Get used to writing a lot of documents and drawing diagrams! I decided to use [Grammarly](https://www.grammarly.com/) to help write English (as it is not my native language). ### Don’t reinvent the wheel There is a lot of excellent documentation and help available on the web. Make use of it! If you have been in development for a long time, you might need some refreshers about diagramming and other things. A good place to start is the [Architect Help site of Salesforce](https://architect.salesforce.com/)! ## In the end The role of an architect is quite diverse if you consider the various “types”. However, it’s crucial to evaluate if you’re willing to make the necessary changes to your daily work routine. If you have a passion for development and want to continue in that field, it might be best to delay pursuing a career as an architect for a few years. There is nothing wrong with growing within the developer role. In the end, if every developer becomes an architect, there will be no one left to actually build anything. --- ## How to load client-side JavaScript and CSS in SFRA Canonical URL: https://rhino-inquisitor.com/how-to-load-client-side-javascript-and-css-in-sfra/ Markdown URL: https://rhino-inquisitor.com/how-to-load-client-side-javascript-and-css-in-sfra/index.md Content type: article Published: 2024-02-19T08:28:48Z Updated: 2024-02-19T08:31:26Z Summary: Client-side JavaScript is quite necessary these days to create functionalities and have a good user experience. But how do you load it in SFRA? Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, sfra, technical ## Key Takeaways - Explains how SFRA loads client-side CSS and JavaScript through assets.js and page templates - Shows where htmlHead.isml and scripts.isml render the queued asset lists - Warns why remote includes and missing page decorators can make asset loading appear broken Since you are here, I bet you’ve been banging your head against your keyboard trying to figure out how to load some sweet client-side javascript in Salesforce Commerce Cloud’s [SFRA](/sitegenesis-vs-sfra-vs-pwa/) (Storefront Reference Architecture). Well, fear not, because I’m here to help (hopefully)! First, let’s ensure we’re on the same page. SFRA uses ISML ([Internet Store Markup Language](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-working-with-templates.html)) for its templates and layouts, which means that to load in some javascript, we’ll need to use certain ISML tags and SFRA “features” to include it in our templates. ## SFRA provides a helper The Storefront Reference Architecture provides many features and “helpers” to make developers’ lives easier. One of those features is the “[assets.js](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/blob/master/cartridges/app_storefront_base/cartridge/scripts/assets.js)” file to load client-side JavaScript and CSS in a structured way. ```js var assets = require('*/cartridge/scripts/assets.js'); assets.addCss('/css/account/my-file.css'); assets.addJs('/js/my-file.js'); ``` ### What is it In short: It is a “singleton” type class with two arrays that stores all CSS and JavaScript files that need to be loaded for the current page. ### When does it load the files #### CSS The “[htmlHead.isml](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/blob/50ee82face6e0a000f649a51f162e8a3f171531c/cartridges/app_storefront_base/cartridge/templates/default/common/htmlHead.isml)” template is loaded within the pages of your project. And within that template, you’ll find the following code: This code is responsible for loading all the fancy styles that are present in that array we talked about earlier. ```html <isloop items="${ require('*/cartridge/scripts/assets.js').styles }" var="style"> <link rel="stylesheet" href="${style.src}" <isif condition="${style.integrity != null}">integrity="${style.integrity}" crossorigin="anonymous"</isif> /> </isloop> ``` #### JavaScript Like styles, you can also load JavaScript files into your SFRA project using ISML. The main difference is that you’ll be using the [scripts.isml](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/blob/master/cartridges/app_storefront_base/cartridge/templates/default/common/scripts.isml) template instead of htmlHead.isml. And if you want to see the big picture, you can check out the “[page.isml](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/blob/master/cartridges/app_storefront_base/cartridge/templates/default/common/layout/page.isml#L32)” file, which is the highest-level ISML file used in SFRA. ```html <script>//common/scripts.isml</script> <script defer type="text/javascript" src="${URLUtils.staticURL('/js/main.js')}"> </script> <isloop items="${ require('*/cartridge/scripts/assets.js').scripts }" var="script"> <isif condition="${script.integrity != null}"> <script defer type="text/javascript" integrity="${script.integrity}" crossorigin="anonymous" src="${script.src}"></script> <iselse> <script defer type="text/javascript" src="${script.src}"></script> </isif> </isloop> ``` ## It doesn’t work! Why ### Remote Includes If you’re using a [remote include](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/ops_troubleshooting/b2c_understanding_remote_includes.html) to render your component and loading the CSS and JS within that component with “assets.js”, you might have noticed that it doesn’t work. Here’s why: When you make a remote include, it’s essentially a separate internal request. And here’s the thing about “assets.js” - it works in a singleton way - but only on the request level, meaning that variables are only stored per request and not for all requests. So when you add JS and CSS within the remote include, the main request doesn’t know about it because it’s being stored in a separate store. As a result, the added JS and CSS are not rendered on the page. Make sense? ![A visual representation of the Home-Show controller for explaining the scoping of assets.js](/how-to-load-client-side-javascript-and-css-in-sfra/javascript-and-css-scoping-in-sfra-2-5444adf22e_hu_d2e23cf2de687e9e.webp) Figure 1: A visual representation of the Home-Show controller for explaining the scoping of assets.js ### Caching This might seem like a no-brainer, but it’s worth mentioning: remember to clear your cache or disable it entirely if necessary (in your development environment). Trust me; it can save you a lot of headaches. ### A controller without “page.isml” If you need to render a small component or a unique page type that isn’t like the central styling of SFRA, you might need to take matters into your own hands (re-create it or use a different system). Without the ISML templates we mentioned earlier, there’s no way for the CSS and JS files to be rendered in HTML. Keep that in mind. As a reference, here is how a controller template in SFRA is usually “decorated”, which includes our “assets.js” templates: ```html <isdecorate template="common/layout/page"> <!-- The template between the header and footer ---> </isdecorate> ``` ## Conclusion Getting your JavaScript and CSS to appear in the HTML code is not a difficult task. However, a few crucial elements are required to make it happen in a structured way, which SFRA (Storefront Reference Architecture) provides. You should utilise the tools provided to you, as they can make your life just a tiny bit easier. --- ## Attribute Fallback in SFCC Variation Groups Canonical URL: https://rhino-inquisitor.com/the-attribute-fallback-system-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/the-attribute-fallback-system-in-sfcc/index.md Content type: article Published: 2024-02-12T07:54:09Z Updated: 2024-02-12T07:54:18Z Summary: One of the features of B2C Commerce Cloud is the ability to create and use variation products, which share common attributes but differ in one or more Categories: Architecture, Salesforce Commerce Cloud, Technical Tags: sfcc, technical ## Key Takeaways - Explains how attribute fallback works across base products, variation groups, and variants in SFCC - Highlights the operational benefits of reduced duplication for catalog maintenance, imports, and development - Clarifies the important exception that pricing behaves differently from other fallback-supported attributes One of the features of B2C Commerce Cloud is the ability to create and use [variation](/slicing-versus-variation-groups-in-sfcc/) products, which share common attributes but differ in one or more aspects, such as colour, size, or style. Variation products can help merchants offer more choices to their customers and optimise their inventory management. Managing variant products can be a challenging task, especially when it comes to defining and displaying the attributes of each variant. To simplify the process for merchants, integrations, and developers, a system has been implemented that prevents duplication of data at different levels (base, variation group, variant). In this article, we will explore this system and its advantages. ## What are variation groups, and how do they differ from slicing? When it comes to varying on an attribute, there are two options within Salesforce B2C Commerce Cloud. [In a previous article](/slicing-versus-variation-groups-in-sfcc/), this concept has been explained in detail. ## How does the attribute fallback system work for variation products, groups, and base products? ![A visual representation of the Variation Group model by using a t-shirt. There colours of shirts, each with their own set of sizes with one base product at the top.](/the-attribute-fallback-system-in-sfcc/variation-model-attribute-fallback-af1b94cc0e_hu_5d6a2384bb735fd3.webp) Attribute values cascade from variant up to variation group and then to the base product when not explicitly set at a lower level. The attribute fallback system is a mechanism that allows B2C Commerce Cloud to automatically retrieve the attribute values of variation products from other sources, such as variation groups or base products when they are not explicitly defined for the variant. This way, merchants can save time and effort in maintaining the attributes of various products and ensure that the customers see the correct and relevant information on the storefront. The attribute fallback system works as follows: - When a customer views a variation product on the storefront, B2C Commerce Cloud first checks if the attribute value is defined for the variation product itself. For example, if the customer views a red shirt in size L, B2C Commerce Cloud first checks if the variant’s name and description are defined. - If the attribute value is not defined for the variation product, B2C Commerce Cloud then checks if the attribute value is defined for the variation group to which the variation product belongs. For example, if the red “large” shirt is part of a variation group “red shirt”, B2C Commerce Cloud checks if the name and description of the shirt are defined for the variation group. - If the attribute value is not defined for any of the variation groups, B2C Commerce Cloud then checks if the attribute value is defined for the base product that the variation product is derived from. For example, if the red large shirt is a variation of a generic “shirt”, B2C Commerce Cloud checks if the name and description are defined for the base product. - If the attribute value is not defined for the base product, B2C Commerce Cloud returns a default or empty value. For example, if none of the sources define the name of the red large shirt, B2C Commerce Cloud returns null for the variant. ### Price ![A variation group product detail page of a shirt where the variants have different prices, ending up with a 'range'.](/the-attribute-fallback-system-in-sfcc/modern-striped-shirt-price-range-f088973939_hu_14c1e5a09bc74278.webp) When variant prices differ, the storefront displays a price range on the variation group PDP rather than a single price. The attribute fallback system applies to all attributes of variation products except for the price attribute. The price attribute does not have a fallback from variation products to variation groups, as variation groups do not have prices. Instead, the price of a variation group is calculated as the range of the prices of the variation products within the group. For example, if a variation group for all red handbags contains three variants with prices of $130, $132, and $135, the price of the variation group is displayed as $130-$135 on the storefront. ## What does it mean for development? Luckily for the developers this system works seamlessly for developers and fetching attributes will automatically set some processes in the works behind the scenes just as the [locale fallback](/understanding-locale-fallback-in-sfcc/). - `dw.catalog.Variant` class has attribute fallback behavior to first obtain attributes from (one or more) assigned variation groups and then from the base product. - `dw.catalog.VariationGroup` class has attribute fallback behavior to obtain attributes from the base product, when the attribute isn’t specified by the variation group. [![Salesforce B2C Commerce API documentation highlighting variation model fallback behavior.](/the-attribute-fallback-system-in-sfcc/variation-model-fallback-in-code-docs-1-ba4d97c55f_hu_cb5e82960933c39.webp)](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/index.html?target=class_dw_catalog_Product.html) The dw.catalog.VariationGroup API explicitly documents fallback to base product attributes when the variation group doesn't define them. ## Advantages for data import Importing data can be time-consuming and resource-intensive, especially when dealing with large or complex data structures. The attribute fallback system can reduce the amount of data needed to be imported, as merchants do not have to define the attribute values for every variation product or group. This way, the merchants can save time and effort in preparing and validating the data and avoid duplicating or conflicting information across different data sources. ### Import Speed Reducing the amount of data in your XML files can lead to a significant decrease in file size. This, in turn, can result in faster imports and improved performance. By removing unnecessary duplicate elements, attributes, and content, you can streamline the import XML files, making them easier to process and leaves more room for other processes. ## Many advantages In conclusion, implementing a fallback system has many advantages, especially when it comes to keeping duplicate values away from your database. It is possible that the fallback system may have some disadvantages. However, since this system is a part of Salesforce Commerce Cloud’s “black box,” we can only hope that any potential drawbacks have been addressed behind the scenes, so that we do not need to be concerned about them. --- ## A look at the Salesforce B2C Commerce Cloud 24.2 release Canonical URL: https://rhino-inquisitor.com/a-look-at-the-salesforce-b2c-commerce-cloud-24-2-release/ Markdown URL: https://rhino-inquisitor.com/a-look-at-the-salesforce-b2c-commerce-cloud-24-2-release/index.md Content type: article Published: 2024-02-05T06:59:49Z Updated: 2024-02-06T09:05:09Z Summary: Review the Salesforce B2C Commerce Cloud 24.2 release and the platform updates worth testing across storefront, API, and operational workflows. Categories: Release Notes, Salesforce Commerce Cloud Tags: release notes, sfcc, technical ## Key Takeaways - Warns that partitioned cookies are on by default and need hybrid-flow testing - Highlights GA custom SCAPI endpoints and other API changes worth revalidating - Flags platform and framework upgrades like SFRA 7 and PWA Kit 3.4 It’s time to gear up for the February 2024 ([24.2](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_24_2_release.htm&type=5)) release of Salesforce B2C Commerce Cloud! With the arrival of this latest release, let’s look at what’s new and exciting! You can always check out [last month’s release notes](/sfcc-24-1-release-a-new-year-update/) by clicking here if you missed it. ## Platform ### Partitioned Cookies On By Default This new feature is automatically enabled with the 24.2 release and may cause unexpected behaviour if you have complex use cases involving cookies. Please turn it off until you have completed all necessary testing. Affects Hybrid Deployments An extra warning for those using hybrid deployments: it is important to test adequately as this change may disrupt standard customer flows. [![A screenshot showing the Feature switch called 'Partioned Cookies' with the default value of 'true'.](/a-look-at-the-salesforce-b2c-commerce-cloud-24-2-release/partioned-cookies-in-sfcc-cb426ac0c4_hu_ca065a48694ec503.webp)](partioned-cookies-in-sfcc-cb426ac0c4.png) Partitioned Cookies quietly shipped as a feature flag before most teams noticed the change. Concerning browser vendors’ ongoing deprecation of third-party cookies, a new feature in Salesforce B2C Commerce Cloud affects how cookies are handled: “[Partitioned Cookies](https://developer.mozilla.org/en-US/docs/Web/Privacy/Partitioned_cookies)” Cookies that are sent by controller code, such as via `response.addHttpCookie` will now have the Partitioned flag set. Most people won’t notice a difference, but this change may have side effects if you have more complex custom cookie logic. However, a feature toggle called Partitioned Cookies defaults to true - you can turn off this new behaviour there, but be sure to read the description carefully, as it is necessary for Page Designer and Toolkit when third-party cookies are disabled in the browser. ### Allow Duplicate Terms in Search Phrases > B2C Commerce search now accepts long-tail search phrases with duplicate search terms. When an exact match for a given phrase is found, the suggestion processor returns highly relevant search results. > > Previously, duplicate words in long-tail search phrases were autocorrected to slightly different versions. Autocorrecting terms in the search phrase can result in irrelevant search results. Improvements in the built-in search engine are always welcomed. A reliable search function across all channels enhances user experience and increases conversion rates. ### Get a Higher Level of Time Stamp Accuracy with Inventory > ProductInventoryRecord.AllocationResetDate now supports a higher level of accuracy in the database. The change is backward-compatible. When dealing with various sales channels that impact inventory, multiple stock modifications may occur within the exact second. Previously, we were unable to differentiate at the millisecond level, but that is no longer the case! With the database modification that allows for milliseconds in the timestamp instead of seconds, we can now more effectively handle this particular use case. #### XML Import example ```xml // example import with seconds <allocation-timestamp>2023-11-22T06:56:01Z</allocation-timestamp> // example import with milliseconds <allocation-timestamp>2023-11-22T06:56:01.567Z</allocation-timestamp> ``` #### OCAPI ```json // Request body example with millis { 'allocation': { 'amount': 17, 'reset_date': '2023-11-23T08:39:23.456Z' } } // Response always with millis .... 'reset_date': '2023-11-23T08:39:23.456Z' // Request body example with seconds { 'allocation': { 'amount': 17, 'reset_date': '2023-11-23T08:41:23Z' } } // Response always with millis .... 'reset_date': '2023-11-23T08:41:23.000Z' ``` ## Business Manager ### Specify a Date Format for Locales > You can now modify the date settings format in Business Manager so that the script API method dw.util.Calendar.getFirstDayOfWeek() returns the first day of the week in the date format used by your site locale. Previously, you couldn’t modify the date format to match the local or regional context. ![A screenshot of the date settings in a locale before the 24.2 release.](/a-look-at-the-salesforce-b2c-commerce-cloud-24-2-release/locale-date-settings-before-24-2-1107342948_hu_87d356e705bbcbf2.webp) Before 24.2, locale settings had no way to control the first day of the week. ![A screenshot of the date settings in a locale after the 24.2 release, showing the new start day of the week option.](/a-look-at-the-salesforce-b2c-commerce-cloud-24-2-release/locale-date-settings-after-24-2-ed26c6c56a_hu_ee454c37b83d4fdd.webp) After 24.2, locale settings finally let teams set the week start explicitly. ## Development ### Custom SCAPI Endpoints The promised helper functions have arrived with the new custom endpoints going GA, making creating scripts for your endpoints easier! - [https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/upcoming/scriptapi/html/index.html?target=class\_dw\_system\_RESTResponseMgr.html](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/upcoming/scriptapi/html/index.html?target=class_dw_system_RESTResponseMgr.html) ## OCAPI & SCAPI ### Custom SCAPI Endpoints Although this [option](https://developer.salesforce.com/docs/commerce/commerce-api/guide/custom-apis.html) has existed since September last year, this feature is now officially out of BETA and can be safely used in production environments. It is important to note that a few things have changed in this release that might break your current customisations, so verify that all endpoints still behave and work the way you intended. The [documentation](https://developer.salesforce.com/docs/commerce/commerce-api/guide/custom-apis.html) has been updated to include these changes. It’s time to read up! ### SLAS Updates > - Improved error handling for TSOB(Trusted system on Behalf) for “customer not found” user scenarios. > - Support added for using SAP Customer Data Cloud socialize REST endpoints. > - IDP configuration now allows the IDP client credentials to be added to the POST body. SLAS now supports OIDC client\_secret\_basic and client\_secret\_post for client authentication. > - Updated the /introspect endpoint to include a “sub” claim in the response. > - Improved validation in Session Bridge(SESB) flow by checking for the customer\_id and failing the request if the customer is already registered. > - Includes SLAS Admin UI and API bug fix to address the cache synchronization issue when a client is edited or deleted. SLAS updates this month include some critical changes. One of the issues that has been bothering me for the past year was the visual cache of the SLAS admin UI, which caused a lot of confusion by displaying outdated information. However, I’m happy to report that this issue has finally been fixed, dramatically improving UX. ## Account Manager ### 1.32.0 Release > - Security Fixes > - Bug Fixes > - Infrastructure Updates > - **UUID Tokens Switched to JWT Access Tokens**: As previously announced in June 2023, Account Manager no longer supports the use of UUID token formats. All new API Clients only support the JWT access token format. After quite a long warning beforehand, the [UUID](/the-deprecation-of-the-uuid-token-for-api-clients/) option is now wholly gone for new API clients! ## SFRA v7.0.0 - [https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/releases/tag/v7.0.0](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/releases/tag/v7.0.0) > **BREAKING CHANGE: SFRA v7.0.0 has been updated to support Node 18** > > - Setup Github Actions config by @shethj in #1337 > - Allow arbitrary-length TLDs by @wjhsf in #1352 > - Fix broken locale selector on Page Designer pages. by @wjhsf in #1354 > - Fix search with multiple refinements on PLP by @shethj in #1365 > - Bug: avoid XSS attacks in addressBook.js by @mjuszczyk1 in #1366 > - Update: seo friendly urls for search refinements by @sandragolden in #1331 > - Bug: fix transformations not being applied (W-8851964) by @wjhsf in #1183 > - Use standard ignore for generated files by @wjhsf in #1182 > - Bump version to v7.0.0 by @shethj in #1373 > - Add node18 release note by @shethj in #1374 A long-awaited update to SFRA is finally here with the long-promised update to node 18! > **Effort:** Do not underestimate upgrading your projects, as this update also means that libraries have been upgraded! [![package.json changes in SFRA 7.0.0](/a-look-at-the-salesforce-b2c-commerce-cloud-24-2-release/package-json-changes-7-0-0-cecd2c2e2d_hu_8b9d4d2a3e8c5513.webp)](package-json-changes-7-0-0-cecd2c2e2d.png) The 7.0.0 package changes show how much supporting tooling moved under the hood. ## PWA Kit v3.4.0 > **General** > > - Add support for node 20 #1612 > - Fix bug when running in an iframe #1629 > - Generate SSR source map with environment variable #1571 > - Display selected refinements on PLP, even if the selected refinement has no hits #1622 > - Added option to specify isLoginPage function to the withRegistration component. The default behavior is “all pages ending in /login”. #1572 > > **Accessibility** > > - Add correct keyboard interaction behavior for variation attribute radio buttons #1587 > - Change radio refinements (for example, filtering by Price) from radio inputs to styled buttons #1605 > - Update search refinements ARIA labels to include “add/remove filter” #1607 > - Improve focus behavior on my account pages, address forms, and promo codes #1625 > > **Storefront Preview** > > - We’ve added a new context input field for Customer Group. This is a text input for now but we imagine a dropdown in the future. > - We know many of you will bring third party CMS’s to the mix. We want you to be able to use Storefront Preview with these as well! On that note please check out our new guidance on Preview extensibility. Essentially you can forward context changes onto a third party to set their version of context in the given platform meaning your Previewed storefront can faithfully render all the content relevant to your context settings. - [https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.4.0](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.4.0) With smaller and larger updates, the 3.4 release is now equipped to support more use cases and stay current with the latest Node versions! ## Bugfixes Someone decided in January to do some cleanup, making it harder to make an overview, but here is a [link](https://issues.salesforce.com/#sortCriteria=%40sflast_modified_date_external__c%20ascending&f[sfcategoryfull]=Commerce%7CB2C%20Commerce) to make things easier! ## Updated Cartridges & Tools ### composable-storefront-pocs - [https://github.com/SalesforceCommerceCloud/composable-storefront-pocs](https://github.com/SalesforceCommerceCloud/composable-storefront-pocs) > This repo is a composable storefront implementation with various proof of concepts baked in. It otherwise closely tracks pwa-kit A big update to the POC library, such as live editing (custom editors) and Promotional/Sale/list pricing on PLP and PDP. ### plugin\_slas (v7.2.0) - [https://github.com/SalesforceCommerceCloud/plugin\_slas](https://github.com/SalesforceCommerceCloud/plugin_slas) > This cartridge extends authentication for guest users and registered shoppers using the Shopper Login and API Access Service (SLAS). - Node18 upgrade by [@alexvuong](https://github.com/alexvuong) in [#175](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/175) - Bump version to v7.2.0 by [@shethj](https://github.com/shethj) in [#177](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/177) --- ## Understanding Locale Fallback in SFCC Canonical URL: https://rhino-inquisitor.com/understanding-locale-fallback-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/understanding-locale-fallback-in-sfcc/index.md Content type: article Published: 2024-01-29T09:06:32Z Updated: 2024-01-31T08:11:45Z Summary: In today's digitally connected world, personalization and localization play a crucial role in delivering a tailored shopping experience. Categories: Salesforce Commerce Cloud, Technical Tags: localisation, sfcc, technical ## Key Takeaways - Explains how locale fallback works in SFCC when localized content is missing for a requested market or language - Shows the configurable fallback hierarchy and the restrictions that apply when setting locale relationships - Highlights the user-experience and development implications teams should understand when building international storefronts In today’s digitally connected world, personalization and [localization](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-localization.html) play a crucial role in delivering a tailored shopping experience. Salesforce B2C Commerce Cloud understands this and includes a powerful locale fallback mechanism to help businesses cater to various markets while managing content efficiently. In this deep-dive article, we will explore the locale fallback feature, its importance, configuration, and potential considerations for developers working on international storefronts. ## What is the Locale Fallback Locale fallback refers to the system’s ability to serve alternative content when localised data for a request is unavailable. On Salesforce B2C Commerce Cloud, the mechanism ensures that when dealing with multi-locale settings, the application server can source localisable attributes or properties from a predefined sequence of related locales. The default hierarchy handles locales by country first (e.g., `en_US` for United States English), then by language (`en` for English), and finally, referring to a default locale if necessary. ## Importance of Locale Fallback Locale fallback plays a critical role in maintaining a seamless user experience. Imagine a customer browsing an e-commerce website that lacks translation or specific data for their locale. Without fallback, this would lead to incomplete or inconsistent data, negatively impacting user experience and trust. With fallback, the store can still display relevant, albeit generic information, ensuring the site remains functional and informative. ### Manage Translations Thoroughly Ensuring a positive user experience on your site involves managing messages and translations; although a protection system is in place, this responsibility ultimately falls on you. ## How Locale Fallback Works ![Decision tree showing locale fallback from en_US to en and then default.](/understanding-locale-fallback-in-sfcc/locale-fallback-explained-bfdfc55392_hu_8963adab3aeadef1.webp) Is there a translation present? 1. A shopper from the United States with the locale `en_US` visits a product page. 2. The system first looks for product description, pricing, etc., data relevant to the `en_US` locale. 3. If that specific locale data is unavailable, it falls back to “en” (indicating the English language). 4. Should the `en` data also be missing, the system retrieves the default locale’s content. This hierarchy ensures that the user receives readable and relevant content despite gaps in localised information. ### Inconsistent Languages On A Single Page If you configure the fallback system differently, let’s say you have the German language option (`de_DE`) and the “default” locale is set as English. In this case, there is a possibility that a customer may see some parts of a webpage in German while others will appear in English. ## Configuring Locale Fallback ![Locale configuration screen in Administration and Global Preferences.](/understanding-locale-fallback-in-sfcc/sfcc-localisation-config-e5d2f27043_hu_359d17e71e449a60.webp) Locales and fallback can be configured at 'Administration > Global Preferences > Locales' Salesforce B2C Commerce Cloud allows for customized fallback configurations. You can skip levels in the fallback chain or even eliminate fallback entirely for particular locales, depending on your specific requirements. For the `en_US` example, the fallback chain by default is `en_US > en > default`. However, you could configure `en_US` to bypass the `en` step and go straight to `default`, or you might decide that `en_US` should not fallback at all. ### Fallback To A Different Language You are only allowed to fall back within the same language: - **Allowed:** `fr_FR > FR > Default` - **Allowed:** `fr_FR > Default` - **Allowed:** `fr_FR > Disabled` - **Not allowed:** `fr_FR > DE > Default` - **Not allowed:** `fr_FR > fr_BE > Default` - **Not allowed:** `fr_FR > de_DE > Default` ![Example locale fallback configuration for en-GB.](/understanding-locale-fallback-in-sfcc/locale-fallback-en-uk-bd32fc597d_hu_f44f604b483cb251.webp) The possible fallback options for en\_GB ## Things to Consider - **Disabling Locale Fallback:** You can disable fallback for individual locales. For instance, if the `en` locale’s fallback is disabled, and there’s no description for a product in the `en` dataset, then no description will be presented, unlike the usual fallback behavior where default text might be used. - **Content Types Affected:** The locale fallback mechanism applies primarily to subclasses of `PersistentObject`. This includes objects such as products but does not extend to ISML templates, web forms, resource files in cartridges, or static content such as images. - **Restrictions:** Configuring a locale as a fallback for another locale creates a dependency. Therefore, a locale that serves as a fallback cannot be deleted as long as another locale relies on it. This restriction ensures stability and consistency within your localizable content structure. ## Developer Implications Developers must carefully consider the implications of the fallback system when creating custom modules and localisable attributes. Aspects to keep in mind include: - **Implementation of Fallback Logic:** Developers need to incorporate logic that respects the fallback configurations when developing customisations involving localisable content. Generally, nothing needs to be done, but [workarounds](/fetching-data-in-a-locale-with-sfcc/) are required for some use cases. - **Testing:** Custom fallback configurations require thorough testing across different locales to ensure the expected behaviour and prevent content gaps. ## Conclusion The locale fallback mechanism in Salesforce B2C Commerce Cloud offers a powerful tool for businesses to effectively manage their international content strategy. By understanding and correctly configuring locale fallbacks, developers can ensure that their storefronts are localised and robust, providing a continuous flow of information across different regions and languages. As they advance in their Salesforce B2C journey, leveraging this feature will help create an inclusive shopping experience that [resonates](https://www.forbes.com/sites/forbesbusinesscouncil/2022/01/24/three-important-aspects-of-localization-often-overlooked-by-small-businesses/?sh=515ca5652847) with a global audience. --- ## Three Ways to Secure Your SFCC Environment Canonical URL: https://rhino-inquisitor.com/three-things-to-secure-sfcc/ Markdown URL: https://rhino-inquisitor.com/three-things-to-secure-sfcc/index.md Content type: article Published: 2024-01-15T17:47:00Z Updated: 2024-01-15T17:47:00Z Summary: Securing your Salesforce B2C Commerce Cloud environment is important, but sometimes neglected. These are 3 actions you can take immediately! Categories: Salesforce Commerce Cloud, Technical Tags: security, sfcc, technical ## Key Takeaways - Focuses on three immediate security actions teams can take in SFCC around user access, code quality, and third-party credentials - Reinforces the principle of least privilege for both Account Manager users and API-based integrations - Frames SFCC security as a shared customer responsibility rather than something the SaaS platform handles entirely on its own The importance of security in any digital environment can not be stressed enough. Even though [Salesforce Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/) is a SaaS solution, you are still in charge of your system and how some aspects are secured. A good example is user management; you securely handle access to different environments. Salesforce provides the tools to secure it, but you must use them correctly for optimal protection. There is no time like the present, so let us look at three things you can do today to secure your Salesforce B2C Commerce Cloud environment! ## Verify account manager access ![Someone on the stage of an opera house auditing the audience. This represents making account manager secure by doing regular audits.](/three-things-to-secure-sfcc/someone-auditing-an-audience-bcf9568dda_hu_85873e90d926123c.webp) As mentioned, user management is under your (or someone within your team) supervision. A few automations exist, [such as auto disabling of accounts](https://help.salesforce.com/s/articleView?id=sf.account_manager_rn_auto_disable_inactive_users_release.htm&type=5), but that doesn’t mean you shouldn’t have a look! So why not do an audit now? Look at all the accounts and what access rights they have. Ask the question: “Do they need access to this now?” They might have needed access to administer an environment at one point, but that was aeons ago. So why not restrict that access? You should always have a [system of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege), but mistakes happen - we are only human! Or off-boarding procedures that need to be correctly followed. So, an audit every once in a while is a good idea. But why do this, you might ask? Well, there are quite a few reasons for this: - People do administrative tasks in the wrong environment by accident, even though they have not been working on that project for weeks/months/years (it happens) - An account was hacked that had access to multiple projects they no longer worked on - Someone left the company on bad terms and decided to abuse their access - … and many more I am not saying that with a system of least privilege, all damage could have been prevented, but they could have done much less damage if the correct procedures had been adhered to. ## Check the code for security issues Just as user access is something you and your team are in charge of, so is the security quality of the code deployed to the environments. It might be a good idea to go and check out the repository and review the most sensitive areas, looking for security holes. Don’t know where to start? I wrote [an extensive article about security best practices](/secure-coding-in-salesforce-b2c-commerce-cloud/) to remember during development. ## Third-party access ![People grabbing keys from a treasure chest](/three-things-to-secure-sfcc/people-grabbing-keys-from-a-chest-728c293140_hu_f4dd625b37843f6a.webp) Next to user access to the business manager of the environments, there are also API Keys that allow administrative access to the system through REST endpoints and the [WebDAV](/a-beginners-guide-to-webdav-in-sfcc/). If you have systems that integrate with Salesforce B2C Commerce Cloud, document those systems and how they integrate. And again, make sure they work with a [Principle of Least Privilege](https://www.cisa.gov/uscert/bsi/articles/knowledge/principles/least-privilege). An excellent example of such an integration is an ERP system that updates orders via the OCAPI and uploads Price Book files to WebDAV. Verify that the ERP can only do those two things with the API Key it has been given. There may be an integration that is no longer active or an API key that has been replaced. Ensure these are removed from the configuration so no one can abuse them if they are accidentally shared outside your organisation. We always hope people who get these by accident bear no ill will, but that is not the world we live in. ## Get crackin’ These three items are just to get you started, there are many other things that you can check today to make sure your environments are secured. And make sure to check the documentation for helpful [tools that Salesforce provides](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/account_manager/b2c_account_manager_register_verification_methods_for_mfa.html) to make your life easier. --- ## Commerce Cloud 24.1 Release: A New Year Update Canonical URL: https://rhino-inquisitor.com/sfcc-24-1-release-a-new-year-update/ Markdown URL: https://rhino-inquisitor.com/sfcc-24-1-release-a-new-year-update/index.md Content type: article Published: 2024-01-08T09:10:13Z Updated: 2024-01-10T08:49:57Z Summary: A new year means release notes for the back end have started again! This time, we look at the January 2024 (24.1) release! Categories: Release Notes, Salesforce Commerce Cloud Tags: release notes, sfcc ## Key Takeaways - Highlights the most relevant 24.1 changes around DKIM support, temporary baskets in OCAPI, and Einstein log handling - Explains why temporary baskets matter for headless and mobile order flows without disturbing the main shopper basket - Calls out the related PWA Kit and tooling updates that teams should track early in the 2024 release cycle A new year means release notes for the back end have started again! This time, we look at the [January 2024 (24.1) release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_24_1_release.htm&type=5)! Are you interested in last year’s release notes? Read the [23.10 release overview](/salesforce-b2c-commerce-cloud-23-10-release-a-comprehensive-overview/). ## Platform ### DKIM Support for Emails ![Email Settings screen in Business Manager with the new DKIM option.](/sfcc-24-1-release-a-new-year-update/dkim-in-commerce-cloud-0dbe52d4a2_hu_2664bbf1d4d09e68.webp) Are you tired of missing out on important emails because they end up in your SPAM folder? We have great news for you! Commerce Cloud now comes with [DKIM](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) support, designed to significantly reduce the chances of your emails being marked as SPAM. PIG Only This option does not seem to be available on sandboxes. ### Improved log handling for Einstein Search Dictionaries and Einstein Predictive Sort > The error handling for Einstein Search Dictionaries and Einstein Predictive Sort log files no longer creates log errors when an updated dataset isn’t available. **How:** If you use Einstein Search Dictionaries or Einstein Predictive Sort, verify the Region setting in your staging instance. In **Business Manager** | **Administration** | **Operations** | **Einstein Status Dashboard** | **site**, set the Region to one of the following: - Americas - APAC - EU ## OCAPI & SCAPI ### Enable Temporary Baskets for Immediate Order Requests in OCAPI ![A person's hand touches a mobile phone, depicting multiple carts on top of it, representing the new Headless options for 'temporary baskets.'](/sfcc-24-1-release-a-new-year-update/carts-on-a-mobile-phone-022785d77e_hu_cd0a45254de3b622.webp) > OCAPI 23.4 includes support for temporary baskets. Temporary baskets allow for immediate order requests in B2C Commerce. For example, a shopper uses a Buy Now option to purchase an item. The temporary basket, which has a limited lifetime of 15 minutes, is populated with all the data required to ready the basket for checkout without affecting the regular shopper basket. **How:** Pass a query parameter temporaryBasket into POST baskets to create a temporary basket. With OCAPI 23.4 the basket document attribute isTemporary indicates a basket is temporary. The recent introduction of temporary basket access in Headless setups is a significant breakthrough! This new feature unlocks a world of possibilities for mobile applications and the PWA Kit. Have you ever received a request to allow only one product type in a single basket without allowing any combinations? Such requests were puzzling before [this feature was added](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_enable_temporary_basket.htm&type=5). Where do you store the current basket? What if the product goes out of stock in the meantime? Some things that you need to remember about these temporary baskets: - Basket lifetime is limited compared to shopper baskets. A temporary lifetime of 15 minutes is used for basket retention. - Limit is separate from shopper and agent basket limits. The shopper can have up to 4 temporary baskets. - Available to all shoppers, including guests. (unlike agent baskets) SCAPI It is unclear if this change translates to the SCAPI endpoint ([https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-baskets?meta=createBasket](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-baskets?meta=createBasket)). Currently, the new query parameter is not mentioned in the documentation. However, it is expected that development on the SCAPI will resume in January, and hopefully, this feature will be on the roadmap. ## PWA Kit v3.3.0 - [https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.3.0](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.3.0) Some love again for the PWA Kit, wit the release of v3.3.0. The main changes are: - Adding StorefrontPreview component ‘onContextChange’ property to prepare for future Storefront Preview release - Updating engine compatibility to include npm 10 - Replacing max-age with s-maxage to only cache shared caches - Improving pwa-kit-dev start command to accept CLI arguments for babel-node - Adding source-map-loader plugin to webpack configuration - Creating a flag to allow toggling behavior that treats + character between words as space in search query - Implementing gift option for basket - Updating extract-default-messages script to support multiple locales - Adding support for localization in icon component - Making various accessibility improvements and bug fixes ## Bugfixes - [Issue with High Scale Price Books feature and OCAPI Search Endpoint](https://issues.salesforce.com/issue/a028c00000suSwsAAE/issue-with-high-scale-price-books-feature-and-ocapi-search-endpoint) Only one fix was made in the current release. However, [many items](https://issues.salesforce.com/#sortCriteria=%40sflast_modified_date_external__c%20descending&f[sfcategoryfull]=Commerce%7CB2C%20Commerce) are marked as “Solution Scheduled” and “Solution Deploying”, which will hopefully be covered in next month’s release blog post! ## Updated Cartridges & Tools ### sgmf-scripts (3.x in the works) - [https://github.com/SalesforceCommerceCloud/sgmf-scripts/commits/master/](https://github.com/SalesforceCommerceCloud/sgmf-scripts/commits/master/) > This repository contains a collection of scripts that are useful for creating Storefront Reference Architecture overlay cartridges. All of the scripts are executable through CLI. I’ve noticed that someone is currently working on developing version 3.x of this library. This is an exciting update that many people have been eagerly waiting for. It will be interesting to see what changes and enhancements are made in this new version. --- ## Beginner's Guide to WebDAV in SFCC Canonical URL: https://rhino-inquisitor.com/a-beginners-guide-to-webdav-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/a-beginners-guide-to-webdav-in-sfcc/index.md Content type: article Published: 2024-01-01T17:06:50Z Updated: 2024-01-01T17:06:50Z Summary: File Management is critical and necessary in any project. How else can we work with mass data transfers or logging mechanisms? Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, technical, webdav ## Key Takeaways - Explains what WebDAV is and where it fits in Salesforce B2C Commerce Cloud - Covers common WebDAV use cases including file transfer, media, and logging - Compares Business Manager user authentication with API client permission setup File Management is critical and necessary in any project. How else can we work with mass data transfers or logging mechanisms? This blog post will explore WebDAV and its use in [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/). We’ll also discuss connecting to WebDAV using Basic Authentication and API Key. ## What is WebDAV? [Web Distributed Authoring and Versioning](https://nl.wikipedia.org/wiki/WebDAV), commonly known as WebDAV, is a robust protocol that extends HTTP to allow for creating, modifying, and managing files on remote servers. It’s a helpful tool that makes it easy to manage files over the internet, and it is widely used in content management systems, cloud storage platforms, and collaboration tools. The protocol was first introduced in 1996 by the Internet Engineering Task Force (IETF) as an extension to the HTTP/1.1 standard. Since then, it has become an integral part of the web infrastructure. WebDAV is beneficial when working with many files or when making frequent changes. Developers can easily upload and manage these files using WebDAV without using the platform’s user interface. In addition, WebDAV provides versioning capabilities (Not enabled on SFCC - as far as we know), enabling developers to track file changes over time. This can be useful for auditing purposes or rolling back changes if necessary. Many clients, including Cyberduck, Transmit, and FileZilla, support WebDAV. These clients provide a user-friendly interface for accessing and managing files remotely. ## How is WebDAV used in Salesforce B2C Commerce Cloud? WebDAV is a versatile technology that allows developers to manage files and data in Salesforce B2C Commerce Cloud. One of the main advantages of WebDAV is that it provides a standard HTTP-based protocol for remote file management, which makes it easy for developers to access and manipulate files. WebDAV has quite a few use cases in Salesforce B2C Commerce Cloud: - Thanks to WebDAV, developers can easily [manage](https://help.salesforce.com/s/articleView?id=cc.b2c_access_files_webdav.htm&language=en_us&release=2.0.1&type=5) product images on their online stores, including uploading, updating, and deleting images. - This file system can be used for importing and exporting data, which lets developers quickly [transfer data files](https://help.salesforce.com/s/articleView?id=cc.b2c_transferring_files_to_an_instance.htm&type=5) to and from the platform for analysis or backup purposes. - WebDAV provides a way to manage log files on the platform, including [debugging](https://help.salesforce.com/s/articleView?id=cc.b2c_secure_logging.htm&type=5), error logging, and security logging. It is a critical tool to monitor the platform’s health and [security](https://help.salesforce.com/s/articleView?id=cc.b2c_security_event_auditing.htm&type=5) and quickly identify and address any issues. - Developers can use it to [create](https://help.salesforce.com/s/articleView?id=cc.b2c_automating_file_transfer_through_scripts.htm&type=5) full or incremental backups of their online store data and files, ensuring they can recover from data loss or other catastrophic events. - WebDAV can temporarily store files when performing file operations on the platform, such as [transferring](https://help.salesforce.com/s/articleView?id=cc.b2c_transferring_files_to_an_instance.htm&type=5) files between servers. ## Authentication There are two main ways to connect to WebDAV: Basic Authentication and API Key. Basic Authentication is a straightforward way to connect to WebDAV, while API Key authentication provides a more secure way to connect to WebDAV. ### Authentication for Business Manager Users When the WebDAV client is a Business Manager user utilising a client application such as Cyberduck or FileZilla, Salesforce B2C Commerce Cloud resorts to Basic Auth authentication, which uses a username and password combination to grant access. It’s up to the merchant to [set this up through the configuration of authorisation rules](https://help.salesforce.com/s/articleView?id=cc.b2c_creating_roles.htm&type=5) specific to folders in the Business Manager. To manage these folder-specific permissions, navigate to the [Roles module in Business Manager](https://help.salesforce.com/s/articleView?id=cc.b2c_roles_and_permissions.htm&type=5) and adjust the settings in the `WebDAV Permissions` tab. Here, you can assign different access levels—read, write, or both—to various directories within WebDAV, ensuring Business Manager users only have access to the files necessary for their role. [![A screenshot of the business manager showing the WebDAV Permissions for the "eCom Manager".](/a-beginners-guide-to-webdav-in-sfcc/webdav-role-permissions-7d3baef818_hu_4fa8591bffee912d.webp)](webdav-role-permissions-7d3baef818.png) Role-level WebDAV permissions ### Authentication for API Clients API clients engage in machine-to-machine communication and authenticate through an authorisation token [generated in the Account Manager](https://help.salesforce.com/s/articleView?id=cc.b2c_generate_api_client_id.htm&type=5). To get this authorisation token, an API client must present its unique `client-id` and `client-secret`. After successful authorisation, WebDAV permissions for the API client can be configured in Business Manager in the `WebDAV Client Permissions` module. _Administration > Organization > WebDAV Client Permissions_ This configuration involves creating a JSON document that accurately represents each API client’s permissions over specific directories. For instance, an API client may have `read_write` permissions to the “`/impex/src/foo"` directory and `read` permission to the “`/impex/src/logs` and `/catalogs"` directories. The client\_id and permissions (each having path and operation) must be clearly defined in this JSON document. ```json { "clients":[ { "client_id":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "permissions":[ { "path":"/impex/src/foo", "operations":[ "read_write" ] }, { "path":"/impex/src/logs", "operations":[ "read" ] }, { "path":"/catalogs", "operations":[ "read" ] } ] }, { "client_id":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaab", "permissions":[ { "path":"/impex/", "operations":[ "read_write" ] } ] } ``` [![A screenshot of the WebDAV Client Application Permissions screen showing one configuration giving an API key access to the /impex folder and /cartridges folder.](/a-beginners-guide-to-webdav-in-sfcc/webdav-client-application-permissions-8757d150cc_hu_878e6c09d02eba3e.webp)](webdav-client-application-permissions-8757d150cc.png) WebDAV client permission mapping #### Things to keep in mind > **Note:** that the permission paths for different clients cannot intersect each other, meaning that if you configure one client with permissions for `/impex/src`, you can’t have another set for `/impex/src/foo`. This restriction is in place to prevent potential conflicts and overlaps in permissions. Salesforce B2C Commerce Cloud’s security measures don’t permit write operations in specific directories. For example, the `/securitylogs` directory can only be granted `read` permissions. You can maintain a secure and organised file system within Salesforce B2C Commerce Cloud by effectively authenticating WebDAV clients and meticulously configuring permissions. --- ## Moving from SiteGenesis and SFRA to Composable Storefront Canonical URL: https://rhino-inquisitor.com/the-move-from-sitegenesis-and-sfra-to-the-composable-storefront-as-a-developer/ Markdown URL: https://rhino-inquisitor.com/the-move-from-sitegenesis-and-sfra-to-the-composable-storefront-as-a-developer/index.md Content type: article Published: 2023-12-25T13:46:42Z Updated: 2023-12-25T13:46:42Z Summary: As a Salesforce B2C Commerce Cloud developer (starter or experienced), expanding your skill set and exploring new technologies is part of the job - it all Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, react, sfcc, technical ## Key Takeaways - Frames the move from SiteGenesis or SFRA to the composable storefront as a skills expansion rather than a full reset for SFCC developers - Highlights which existing JavaScript, commerce, and Commerce Cloud knowledge transfers well into React and PWA Kit work - Curates practical starting points for developers who want to begin learning the composable storefront stack As a Salesforce B2C Commerce Cloud developer (starter or experienced), expanding your skill set and exploring new technologies is part of the job - it all moves quickly. [One option](/sitegenesis-vs-sfra-vs-pwa/) that has become available in Salesforce B2C Commerce Cloud is React.JS, a JavaScript library for building user interfaces (maybe a Headless Storefront? 🙂). In this article, we will discuss the history of React.JS and the Salesforce PWA Kit, the transferable skills from SiteGenesis/SFRA to React.JS, and resources for getting started with learning this technology. ## A history lesson React.JS was first released in [2013 by Facebook](https://blog.risingstack.com/the-history-of-react-js-on-a-timeline/) and has since become one of the most popular front-end development tools in the industry. The library is based on the concept of reusable components, which allows developers to build complex user interfaces by breaking them down into smaller, manageable pieces. This approach promotes code reusability and makes it easier to reason about the structure of a user interface. React.JS quickly gained traction in the development community and has been adopted by many companies. Its popularity can be attributed to its ability to handle complex use cases, high performance, and ease of use. Salesforce (well … the [Mobify](https://www.digitalcommerce360.com/2020/09/09/salesforce-agrees-to-buy-headless-commerce-tech-firm-mobify/) team ) saw the potential in React.JS and decided to create the Salesforce Composable Storefront. The Salesforce Composable Storefront, or PWA Kit, is an open-source toolkit that can be used to create PWAs using React.JS and SFCC APIs. This toolkit empowers developers to use the power of React.JS to create fast, responsive and engaging customer experiences for the [Salesforce Commerce Cloud platform](/sitegenesis-vs-sfra-vs-pwa/). ## Transferrable Skills ![Illustration of a game controller and brain symbolizing transferable developer knowledge.](/the-move-from-sitegenesis-and-sfra-to-the-composable-storefront-as-a-developer/use-your-knowledge-98ac47c97d_hu_e9fc0b20cc811a36.webp) Skills built on SiteGenesis and SFRA — catalog, pricing, promotions, OCAPI — remain fully relevant in the Composable Storefront. ### Development (Duh…) As a SiteGenesis/SFRA developer, you are already familiar with native JavaScript and have a distinct advantage when learning React. JavaScript is the foundation of React.JS, and a solid understanding of the language will make it easier for you to understand and work with the library. One of the significant advantages of knowing native JavaScript is understanding how the underlying code works. This can be extremely useful when debugging and troubleshooting issues when working with React. Knowing JavaScript will give you more flexibility and control over your code, allowing you to optimise it for performance and scalability. (But React has its [quirks and behaviours](https://react.dev/reference/react/memo#skipping-re-rendering-when-props-are-unchanged) that you must also dig into!) Knowing native JavaScript can also give you a better understanding of the web development ecosystem. This knowledge will help you make informed decisions about your tools and technologies and how they interact. Taking the [JavaScript Developer I](/should-i-get-javascript-developer-i-certified/) certification is not such a bad idea, right? ### Commerce As a Salesforce B2C Commerce Cloud developer, you likely deeply understand how Commerce works. This knowledge can be transferable even when changing development languages (and platforms architectures). When building Commerce applications, certain fundamental concepts remain consistent regardless of the technology stack used. Understanding the flow of products, inventory management, customer data, and order fulfilment are all key concepts that apply regardless of the development language or framework used. Your understanding of business processes and the customer journey is valuable in designing and building user interfaces that provide a seamless experience for customers. Also, your knowledge of best practices and industry standards can be helpful. For example, understanding the importance of accessibility, SEO, and performance optimisation can help you to make informed decisions when building different channels. ### Commerce Cloud ![A person walking towards an office building with a Salesforce like logo and 'Commerce Cloud' written above the entrance.](/the-move-from-sitegenesis-and-sfra-to-the-composable-storefront-as-a-developer/commerce-cloud-as-a-building-16b551ef15_hu_b3349ae6afc26457.webp) B2C Commerce Cloud is still the back-end engine: the Composable Storefront changes the front door, not the foundation. A deep [understanding](/the-b2c-commerce-architect-certification/) of how Commerce Cloud functions in online and offline environments is vital. Furthermore, proficiency in utilising the platform is equally essential to succeed. Here are some articles that might come in handy: - [SFCC Architecture Explained](https://www.salesforceben.com/salesforce-b2c-commerce-cloud-architecture-explained/) - [The SFCC Environment](/the-salesforce-b2c-commerce-cloud-environment/) - [How to use OCAPI/SCAPI Hooks](/how-to-use-ocapi-scapi-hooks/) - [What is the OCAPI Session Bridge](/what-is-the-ocapi-session-bridge/) - [How to set up SLAS](/how-to-set-up-slas-for-the-composable-storefront/) ## Where to get started ![Books with documentation scattered on multiple piles, falling over.](/the-move-from-sitegenesis-and-sfra-to-the-composable-storefront-as-a-developer/documents-on-multiple-locations-5bb9c96f2b_hu_5bc0c01f94ded8b6.webp) Getting started with PWA Kit requires navigating docs spread across Salesforce Help, developer.salesforce.com, and GitHub. If you’re a regular reader of my articles, you probably know by now that I’m not a fan of reinventing the wheel or regurgitating something already done. I like to keep things fresh, like a smoothie made with the season’s best fruits. So, kudos to the Salesforce team for providing some tremendous getting-started documentation: - [Skills for Success](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/skills-for-success.html) - [Getting Started](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/getting-started.html) - [Community!!!!](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/community.html) --- ## Unravelling the mystery of dates in the OCAPI Canonical URL: https://rhino-inquisitor.com/unravelling-the-mystery-of-dates-in-the-ocapi/ Markdown URL: https://rhino-inquisitor.com/unravelling-the-mystery-of-dates-in-the-ocapi/index.md Content type: article Published: 2023-12-18T09:16:13Z Updated: 2023-12-18T09:16:13Z Summary: When we integrate third-party systems with Salesforce B2C Commerce Cloud using OCAPI or SCAPI, we often have the requirement to filter data based on date Categories: Salesforce Commerce Cloud, Technical Tags: headless, ocapi, sfcc ## Key Takeaways - Explains how to filter OCAPI and related API searches using date-based query constructs such as range, range2, bool, and term filters - Highlights the date-format requirements and endpoint-specific field support developers need to check before building queries - Acts as a practical guide for integrations that need incremental syncs or time-based record retrieval When we integrate third-party systems with [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/) using OCAPI or SCAPI, we often have the requirement to filter data based on date ranges or only retrieve data that has been modified after a certain time. But how can we achieve this? Are there any other options available? Let’s explore the various filtering and query options in detail. ### Querying Not all endpoints are alike, but within the OCAPI the way of searching for different objects remains the same: making use of Queries and Filtering options. Here are some of the example endpoints: - [Search Catalogs (OCAPI)](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/ocapi-data-api?meta=Search%2BCatalogs) - [Search Categories within a Catalog (OCAPI)](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/ocapi-data-api?meta=Search%2BCategories%2Bwithin%2Ba%2BCatalog) - [Search for customers in a customer list (OCAPI)](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/ocapi-data-api?meta=Search%2Bfor%2Bcustomers%2Bin%2Ba%2Bcustomer%2Blist) - [Search Products (SCAPI)](https://developer.salesforce.com/docs/commerce/commerce-api/references/products?meta=searchProducts) #### Attributes Make sure to check the documentation pages for the specific endpoint to view the supported attributes before building your query. #### Date Format When crafting these date filters, adherence to the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html#:~:text=Therefore%2C%20the%20order%20of%20the,27%2018%3A00%3A00.000.) date format (YYYY-MM-DDTHH:MM:SS.mmmZ) is essential for the API to parse the values correctly. Additionally, ensure that the field names, like `creation_date`, `valid_from`, `valid_to`, and others, correspond to your Salesforce Commerce Cloud data model’s actual date-related fields. ```text 2012-03-19T07:22:59Z // example ``` ## Range Filter ![Calendars and ruler illustration introducing OCAPI date-range filtering.](/unravelling-the-mystery-of-dates-in-the-ocapi/measuring-dates-7c1931cecc_hu_6792a9a3d8f1316b.webp) If you need to find records that fall within a specific date interval, the [range\_filter](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/ocapi-shop-api?meta=type%3Arange_filter) is your go-to option. This filter can find records with a date value sitting between a specified start (from) and end (to) date. ```json { "query": { "filtered_query": { "filter": { "range_filter": { "field": "creation_date", "from": "2020-03-08T00:00:00.000Z", "to": "2020-03-10T00:00:00.000Z" } }, "query": { "match_all_query": {} } } } } ``` ## Range2 Filter To deal with scenarios where you have two date fields and want to filter records with an overlapping date range, use the [range2\_filter](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/ocapi-shop-api?meta=type%3Arange2_filter). This allows the specification of a date range that overlaps the range between the two fields you are considering. A Range2Filter allows you to restrict search results to hits where the first range (`R1`), defined by a pair of attributes (e.g., `valid_from` and `valid_to`), has a specific relationship to a second range (`R2`), defined by two values (`from_value` and `to_value`). The relationship between the two ranges is determined by the `filter_mode`, which can be one of the following: - `overlap`: `R1` overlaps fully or partially with `R2` - `containing`: `R1` contains `R2` - `contained`: `R1` is contained in `R2` ```text "query" : { "filtered_query": { "filter": { "range2_filter": { "from_field": "valid_from", "to_field": "valid_to", "filter_mode":"overlap", "from_value": "2007-01-01T00:00:00.000Z", "to_value": "2017-01-01T00:00:00.000Z" } }, "query": { "match_all_query": {} } } } ``` ## Bool Filter ![A woman combining different blocks in a particular order.](/unravelling-the-mystery-of-dates-in-the-ocapi/combining-blocks-bc1da56e90_hu_c6e36443f7b524f0.webp) Sometimes, the need for complexity arises when constructing date-based queries. The [bool\_filter](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/ocapi-shop-api?meta=type%3Abool_filter) permits the combination of numerous filters for complex logical expressions. This filter is specifically helpful for creating compound date queries that may, for instance, combine status checks with date ranges. ```json { "query": { "filtered_query": { "query": { "match_all_query": {} }, "filter": { "bool_filter": { "operator": "and", "filters": [ { "term_filter": { "field": "status", "operator": "is", "values": ["open"] } }, { "range_filter": { "field": "creation_date", "from": "2023-01-01T00:00:00.000Z" } } ] } } } } } ``` ## Term Query For precision filtering, where a field must match an exact date, the [term\_query](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/ocapi-shop-api?meta=type%3Aterm_query) becomes the instrument of choice. This query matches records based on absolute equality with the specified date. ```json { "query": { "term_query": { "fields": ["creation_date"], "operator": "is", "values": ["2023-04-01T00:00:00.000Z"] } } } ``` ## Custom Endpoint It is currently not fully available / BETA, but you can create [custom GET endpoints](/creating-custom-ocapi-endpoints/) tailored entirely to your requirements. When creating these endpoints, it’s important to consider performance and caching - these are your responsibility when utilising this option. ## Conclusion The search API capabilities of OCAPI in Salesforce B2C Commerce Cloud offer robust and flexible options for date-related searches. You can customize your searches using `range_filter`, `range2_filter`, `bool_filter`, and `term_query` as per your requirements. It is important to use the correct date format and field names to make the most out of these tools. These data querying capabilities can help you segment promotional data, manage catalog validity, or filter orders based on dates, making your commerce data handling more streamlined. Happy coding! --- ## Why Bypassing SFCC Quota Limits Backfires Canonical URL: https://rhino-inquisitor.com/why-circumventing-sfcc-quota-limits-is-a-bad-idea/ Markdown URL: https://rhino-inquisitor.com/why-circumventing-sfcc-quota-limits-is-a-bad-idea/index.md Content type: article Published: 2023-12-11T08:21:33Z Updated: 2023-12-11T08:29:25Z Summary: Learn why bypassing SFCC quota limits creates technical and operational risk, and what safer alternatives teams should choose. Categories: Salesforce Commerce Cloud, Technical Tags: quota, sfcc, technical ## Key Takeaways - Uses a deliberately over-engineered UnlimitedArray example to show why bypassing SFCC quota limits is technically possible but strategically unwise - Explains the practical downsides of quota workarounds in terms of performance, maintainability, scalability, and platform stability - Reinforces that SFCC quota limits are governance mechanisms meant to steer teams toward safer and more sustainable solution design Salesforce B2C Commerce Cloud empowers developers to create robust and scalable e-commerce solutions. It is designed with certain [governance and quotas](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-governance-and-quotas.html) to maintain efficiency and stability across the platform. One such quota limit is on array sizes, which caps at 20,000 items to manage memory usage effectively. Despite these safeguards, developers may attempt to work around these limitations using custom code, like the “UnlimitedArray” I have created. While this approach is possible, it has significant implications we must consider. Let’s explore this “UnlimitedArray” I have created and discuss why I should be arrested (as implied by the image of this post) for doing so. ## Inside the “UnlimitedArray” Below is the code for the “UnlimitedArray,” a data structure designed to bypass Salesforce’s restriction on the number of elements in an array: ```javascript /** * A custom implementation of an array that can hold an unlimited number of elements. * * @constructor */ function UnlimitedArray() { this.listContainer = [[]]; this.currentListPosition = 0; } /** * The length of the array. * * @returns {number} The length of the array. */ Object.defineProperty(UnlimitedArray.prototype, 'length', { /** * The length of the array. * @returns {number} The length of the array. */ get: function () { return this.listContainer.reduce(function (totalLength, list) { return totalLength + list.length; }, 0); } }); /** * Adds an element to the end of the array. * * @param {*} value The element to add to the end of the array. * * @returns {number} The new length of the array. */ UnlimitedArray.prototype.push = function (value) { var currentList = this.listContainer[this.currentListPosition]; if (currentList.length === 20000) { currentList = []; this.currentListPosition += 1; this.listContainer.push(currentList); } currentList.push(value); return this.length; }; /** * Checks if the array contains the specified element. * * @param {*} value The element to check for. * @param {number} fromIndex The index to start checking from. * * @returns {boolean} True if the array contains the element, false otherwise. */ UnlimitedArray.prototype.includes = function (value, fromIndex) { var curFromIndex = fromIndex || 0; var correctedIndex = 0; for (var i = 0; i < this.listContainer.length; i++) { var currentList = this.listContainer[i]; var currentListLength = currentList.length; if (curFromIndex <= (correctedIndex + currentListLength)) { if (currentList.includes(value, curFromIndex - correctedIndex)) { return true; } } correctedIndex += currentListLength; } return false; }; /** * Returns the index of the specified element in the array. * If the element is not found, -1 is returned. * * @param {*} value The element to search for. * @param {number} fromIndex The index to start searching from. * * @returns {number} The index of the specified element in the array. */ UnlimitedArray.prototype.indexOf = function (value, fromIndex) { var curFromIndex = fromIndex || 0; var correctedIndex = 0; for (var i = 0; i < this.listContainer.length; i++) { var currentList = this.listContainer[i]; var currentListLength = currentList.length; if (curFromIndex <= (correctedIndex + currentListLength)) { var index = currentList.indexOf(value, curFromIndex - correctedIndex); if (index >= 0) { return correctedIndex + index; } } correctedIndex += currentListLength; } return -1; }; /** * Returns the element at the specified position in the array. * * @param {number} position The position of the element to return. * * @returns {*} The element at the specified position in the array. */ UnlimitedArray.prototype.get = function (position) { var currentTotalIndex = 0; for (var i = 0; i < this.listContainer.length; i++) { var list = this.listContainer[i]; var previousTotalIndex = currentTotalIndex; currentTotalIndex += list.length; if (currentTotalIndex > position) { return list[position - previousTotalIndex]; } } return null; }; ``` This construct “cleverly” uses nested arrays to exceed the Salesforce-imposed limit. However, it can result in inefficiencies when using methods such as push, get, includes, and indexOf, especially as the combined size of the nested arrays grows. ![A screenshot of the Business Manager. The system is warning that the quota limit for the array size has been reached.](/why-circumventing-sfcc-quota-limits-is-a-bad-idea/quota-limit-warning-7f7a47522c_hu_a5df654639356245.webp) We are at the edge, but never crossing the limit! ### A Closer Look at the “UnlimitedArray” The “UnlimitedArray” is a creative (but could probably be improved) solution to the B2C Commerce Cloud’s limitation on the size of arrays. Here’s how it operates: #### Initialization The “UnlimitedArray” starts as an object with a property called `listContainer`, which is an array that holds other arrays—effectively nesting arrays inside a container array. It also has a `currentListPosition`, which keeps track of the current working sub-array within the container. #### Managing Growth To circumvent the limit of 20,000 elements, when an individual sub-array in `listContainer` reaches this limit, the `UnlimitedArray` creates a new sub-array and continues adding elements to it. This gives the appearance of an array that can hold an “unlimited” number of elements without directly violating platform array size constraints. #### Push Operation When pushing an element, the function determines if the current sub-array has hit the 20,000 limit. If it has, it increments `currentListPosition`, creates a new sub-array, and appends the value there. Otherwise, it adds the value to the current sub-array. #### Length Computation The `length` getter provides the total count of elements within all sub-arrays in `listContainer`. It does this by reducing over the container and summing up the lengths of each sub-array. #### Retrieval and Search The `get`, `includes`, and `indexOf` functions iterate through each sub-array, keeping track of the offset to accurately retrieve elements or check for their existence based on their corrected position within the overall structure. ## Why You Should Think Twice ![A bear wearing an orange prison jumpsuit with a blue cloud logo on the back, walks into a prison with several guards waiting for it.](/why-circumventing-sfcc-quota-limits-is-a-bad-idea/cloud-prison-66083f6bcd_hu_12a9b59f2644f402.webp) No... you aren't going to get arrested 🤣 The performance penalty for using such a structure is significant — every additional layer of complexity can lead to longer execution times. For example, to determine the `length` of the “UnlimitedArray,” you must sum the lengths of all included sub-arrays. Similarly, operations like `push` may necessitate iterating through multiple arrays to find the right one to add a new element when the limit is reached. Searching for an element with `includes` or `indexOf` might require a linear search across all the nested arrays. ## The Case Against Circumventing Quota Limits While the “UnlimitedArray” and solutions like it is a testament to the creativity and skill of Salesforce Commerce Cloud developers, it exemplifies the pitfalls of attempting to bypass platform governance. The issues range from: 1. **Performance**: As the size of the combined data structure grows, performance can degrade, affecting user experience and increasing server resource consumption. 2. **Maintainability**: Maintaining a custom and complex data structure is inherently more challenging and can become burdensome over time as code bases evolve and scale. 3. **Scalability**: As e-commerce platforms typically handle a significant volume of transactions, any potential latency or performance issues can be magnified. 4. **Adherence to Best Practices**: Salesforce imposes quotas to steer developers toward building optimised, stable, scalable applications. Ignoring these guidelines may result in short-term gains but can endanger long-term success and platform health. ## Conclusion The “UnlimitedArray” module is a cautionary example of why circumventing Salesforce B2C Commerce Cloud’s quota limitations, while technically feasible, is inadvisable. Such workarounds may introduce performance bottlenecks, complex debugging, maintenance challenges, and risk platform stability. Instead, developers should focus on designing efficient solutions within established limits and best practices. By doing so, we ensure that our applications are performant, scalable, stable, and aligned with the vision of Salesforce’s robust and enterprise-ready ecosystem. --- ## Mastering Chunk-Oriented Job Steps in SFCC Canonical URL: https://rhino-inquisitor.com/mastering-chunk-oriented-job-steps-in-salesforce-b2c-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/mastering-chunk-oriented-job-steps-in-salesforce-b2c-commerce-cloud/index.md Content type: article Published: 2023-12-04T08:55:16Z Updated: 2025-06-25T11:58:01Z Summary: Salesforce B2C Commerce Cloud offers a robust, flexible Jobs framework vital for performing scheduled or on-demand tasks for e-commerce operations. Categories: Salesforce Commerce Cloud, Technical Tags: jobs, sfcc, technical ## Key Takeaways - Explains how chunk-oriented job steps process large datasets in manageable read-process-write segments - Shows the script-module and steptypes configuration needed to build a custom chunk-oriented job step - Highlights why chunk size and transaction strategy are central to performance and concurrency safety Salesforce B2C Commerce Cloud offers a robust, flexible Jobs framework vital for performing scheduled or on-demand tasks for e-commerce operations. One of the critical capabilities of this framework is the ability to define [custom job steps](https://trailhead.salesforce.com/content/learn/modules/b2c-admin-create-and-manage-jobs/b2c-admin-create-custom-job-steps), which can be either task-oriented or chunk-oriented. In this article, I’ll focus specifically on chunk-oriented job steps and how you can master them to enhance your platform’s performance. ## Understanding Chunk-Oriented Job Steps Chunk-oriented job steps are designed to handle lists of items by processing them in manageable segments called chunks. This technique is handy for operations that need to work with large sets of data, like processing orders, exporting data, or bulk updates. Each [chunk-oriented job](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-custom-job-steps.html) step involves reading, processing, and writing items. If the list contains more items than can be processed in a single chunk, the system starts a new chunk, and the cycle repeats until all items have been processed. ## Essential Components of a Chunk-Oriented Job Step When developing a chunk-oriented job step, you need to implement several functions: 1. **`read-function`:** Retrieves one item or null if no more items are left to process. 2. **Process function:** Applies business logic to each item, transforming it as necessary. 3. **`write-function`:** Writes the processed items, typically to a file or database. There are optional functions you can implement for further control: - `total-count-function`: Returns the total number of items available for processing. This can improve monitoring and progress feedback. - `before-step-function`: Executes logic before all chunks are processed. - `before-chunk-function`: Runs logic before each chunk is processed. - `after-chunk-function`: Invoked after each chunk is successfully processed. - `after-step-function`: Executes after all chunks have been processed. ### An example Salesforce provides a visualisation example in their documentation: [https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-custom-job-steps.html#chunk-oriented-script-module](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-custom-job-steps.html#chunk-oriented-script-module). ## Creating a Chunk-Oriented Script Module We will start with the script. If you need a `steptypes.json` reference as you go, see the [official example](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-step-types-json-example.html). ### Importing what you need Before writing our chunk-oriented script module, let’s ensure we have the required modules imported and variables set: ```js 'use strict'; var CustomerMgr = require('dw/customer/CustomerMgr'); var Transaction = require('dw/system/Transaction'); var ArrayList = require('dw/util/ArrayList'); var customerNoIterator; ``` ### before-step-function Let’s initialise our iterator to retrieve all customer numbers. ```js // Define the beforeStep function to initialize any resources before processing exports.beforeStep = function (parameters, stepExecution) { var customerNumbers = new ArrayList(['customer1', 'customer2', 'customer3']); // Example customer Numbers customerNoIterator = customerNumbers.iterator(); }; ``` ### read-function This function would retrieve the next customer profile to update. ```js // Mockup read function - replace with actual logic to retrieve customers exports.read = function (parameters, stepExecution) { if (customerNoIterator && customerNoIterator.hasNext()) { // If there's an existing iterator, return the next customer const customerNo = customerNoIterator.next(); return CustomerMgr.getCustomerByCustomerNumber(customerNo); } }; ``` ### process-function Here we would perform the business logic to update the custom attribute: ```js exports.process = function(customer, parameters, stepExecution) { // Update the 'myBoolean' custom attribute to a new value Transaction.wrap(function() { customer.custom.myBoolean = true; // set this to the desired value }); return customer; }; ``` ### write-function As the customer profile is updated in the process step within a transaction, the write function may not be necessary unless you log the updates or perform additional actions. If required, it could look like: ```js // Mockup write function - replace with actual logic if writing out exports.write = function(updatedCustomers, parameters, stepExecution) { // Optional: Log the update or perform other write operations var Logger = require('dw/system/Logger'); updatedCustomers.toArray().forEach(function(customer) { // For example, log each customer's update status Logger.debug('Updated customer: {0} with myBoolean set to: {1}', customer.getProfile().getCustomerNo(), customer.getProfile().custom.myBoolean); }); }; ``` ### Putting it all together ```js /** * Copyright 2022-2025 FORWARD SERVICES * Project: FastForward * * Description: The FastForward Business Manager Accelerator strives to enhance the Business * Manager's functionality by developing modules that efficiently improve its user-friendliness. * * Author: Thomas Theunen */ var CustomerMgr = require('dw/customer/CustomerMgr'); var Transaction = require('dw/system/Transaction'); var ArrayList = require('dw/util/ArrayList'); var customerNoIterator; // Define the beforeStep function to initialize any resources before processing exports.beforeStep = function (parameters, stepExecution) { var customerNumbers = new ArrayList(['customer1', 'customer2', 'customer3']); // Example customer Numbers customerNoIterator = customerNumbers.iterator(); }; // Mockup read function - replace with actual logic to retrieve customers exports.read = function (parameters, stepExecution) { if (customerNoIterator && customerNoIterator.hasNext()) { // If there's an existing iterator, return the next customer const customerNo = customerNoIterator.next(); return CustomerMgr.getCustomerByCustomerNumber(customerNo); } }; // Mockup process function - replace with actual logic for customer update exports.process = function (customer, parameters, stepExecution) { // Perform the update of 'myBoolean' custom attribute Transaction.wrap(function () { customer.getProfile().custom.myBoolean = true; // Sets 'myBoolean' to true }); // Return the customer for any further processing needed in write function return customer; }; // Mockup write function - replace with actual logic if writing out exports.write = function (updatedCustomers, parameters, stepExecution) { // Optional: Log the update or perform other write operations var Logger = require('dw/system/Logger'); updatedCustomers.toArray().forEach(function (customer) { // For example, log each customer's update status Logger.debug( 'Updated customer: {0} with myBoolean set to: {1}', customer.getProfile().getCustomerNo(), customer.getProfile().custom.myBoolean ); }); }; // Define the afterStep function to clean up resources after processing exports.afterStep = function (success, parameters, stepExecution) { // Clean up logic goes here if (customerNoIterator) { customerNoIterator = null; // Clear the iterator } }; ``` ### Adding the Chunk Size and Configuration Finally, don’t forget to define the custom job step in your [steptypes.json](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-step-types-json-example.html), including specifying the chunk size and the path to your custom module: ```js { "step-types": { "chunk-script-module-step": [ { "@type-id": "custom.MyCustomChunkScriptModuleStep", "@supports-parallel-execution": false, "@supports-site-context": true, "@supports-organization-context": false, "description": "My custom chunk script step type", "module": "my_cartridge/cartridge/scripts/steps/myChunkModule.js", "read-function": "read", "process-function": "process", "write-function": "write", "chunk-size": 10, "transactional": true, "parameters": { "parameter": [ { "@name": "MyParameter", "@type": "boolean", "@required": false, "description": "An optional boolean parameter." } // additional parameters... ] }, "status-codes": { "status": [ { "@code": "ERROR", "description": "Used when the step failed with an error." }, { "@code": "OK", "description": "Used when the step finished successfully." } // additional status codes... ] } } ] } } ``` Remember that the process function wraps the update code within a transaction using `Transaction.wrap()`. This ensures the integrity of your data update operation. Do you need to do my updates one by one? Of course not. The size of your commit is all up to you! Keep reading to get some insights into why the way you handle transactions is essential! Maybe that optional “after-chunk-function” can help us there 😊. Now you have a chunk-oriented job step to update the custom attribute `myBoolean` for a list of customers. This job step can be configured and run via the Business Manager in Salesforce B2C Commerce Cloud. ### Chunk Size The “Chunk Size” option refers to the number of data items processed in each chunk (part of the total). The chunk size parameter is crucial in optimising transaction performance and ensuring efficient handling of large datasets. The ideal chunk size for a script module depends on various factors, such as: - **The processing logic’s complexity:** Depending on the operations that must be done and other database objects that need to be fetched, we need to remember memory management. For example, choosing a smaller chunk size will allow the system to clean up more efficiently after processing each chunk. - **The data set’s size & the risk of optimistic locking:** When working with a “high risk” object such as profiles that can be modified at any time, setting a smaller chunk size and committing these immediately to the database will reduce the risk of running into [Optimistic Concurrency](https://help.salesforce.com/s/articleView?id=000393690&language=en_US&type=1) Exceptions! ### Transactional When setting a job to transactional, the job step executes as a single and potentially substantial transaction. This means that if there are any errors during the execution of the job step, the entire transaction will be rolled back (because of the Optimistic Concurrency mentioned in the previous section). This can be dangerous, primarily if the job processes a large amount of data. If the transaction is rolled back, all the data processed until that point will be lost. This can result in data consistency, integrity, and even performance issues. Keeping the default setting false is recommended to avoid this negative impact and allow for more granular transaction control. Instead, implement transaction handling within the job step using the “[dw.system.Transaction](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/index.html?target=class_dw_system_Transaction.html)” API. This API provides more transaction handling control and better error handling and recovery mechanisms. ## Using a Chunk-Oriented Script Module in Jobs Once your script module and `steptypes.json` are ready, upload them as part of your custom cartridge. You can then create a job in Business Manager with your custom chunk-oriented step to start processing data in chunks. [![Chunk-oriented job step configuration screen in Business Manager.](/mastering-chunk-oriented-job-steps-in-salesforce-b2c-commerce-cloud/configure-chunk-job-business-manager-ce41f2bdab_hu_d3eea0fb8d9b1202.webp)](configure-chunk-job-business-manager-ce41f2bdab.jpg) After uploading your cartridge, configure the custom chunk-oriented step in Business Manager to start processing data in batches. ### Advantages of “total-count” If you decide to implement the “`total-count-function`”, you can conveniently keep track of your job’s progress in the Business Manager. This feature is handy if you have a large dataset and need to estimate when the job will be completed or if you want to know how far along the job has progressed on the list. ![Job status view showing processed items when total-count is enabled.](/mastering-chunk-oriented-job-steps-in-salesforce-b2c-commerce-cloud/sfcc-job-status-total-count-chunks-299b79ade4_hu_b5b9e2a3c2b3ca6d.webp) Enabling total-count lets Business Manager show real-time job progress — essential for monitoring large dataset runs. ![Job status view without total-count information for comparison.](/mastering-chunk-oriented-job-steps-in-salesforce-b2c-commerce-cloud/sfcc-job-status-total-count-chunks-with-total-e82b2b178e_hu_f6c51ac6c89a7cb8.webp) Without total-count, the job status gives no indication of how much work remains. Using the “total-count-function,” we can determine the amount of processed records as well as the total number of records. ## Best Practices and Performance When working with chunk-oriented job steps, keep the following best practices in mind for optimal performance: - **Focus on memory management:** Only keep necessary items in memory and promptly discard references to processed items. - **Stream data when appropriate:** Avoid accumulating large amounts of data in memory. - **Utilise transactions strategically:** Wrap operations in transactions only when necessary to avoid locking resources for extended periods. - **Monitor and handle errors:** Ensure your job can gracefully handle and recover from errors. --- ## Leveraging Generic Mapping for Efficient Data Integration Canonical URL: https://rhino-inquisitor.com/leveraging-generic-mappings-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/leveraging-generic-mappings-in-sfcc/index.md Content type: article Published: 2023-11-27T09:29:26Z Updated: 2023-11-27T09:29:35Z Summary: See how generic mappings can simplify SFCC data integrations, reduce custom transformation code, and improve maintainability. Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, technical ## Key Takeaways - Explains how Generic Mapping supports fast key-value lookups for large SFCC integration datasets - Shows the full flow from CSV structure and import job setup to MappingMgr access in code - Highlights compound-key support, platform limits, and operational best practices for keeping mappings reliable [Salesforce B2C Commerce Cloud](/getting-to-know-sfra-as-a-developer/) offers many features that empower developers to build custom features on its platform. Generic Mapping are one feature that few use or have heard of. This enables developers to map keys to values stored in a high-performance data store—ideal for handling large datasets with speedy lookup times. In this article, we’ll dissect the inner workings of Generic Mapping, complemented by code examples and job configurations, to serve as a practical guide. ## Understanding Generic Mapping Generic Mapping is a powerful tool that allows you to establish a connection between different sets of data, even if they don’t share a standard format. For example, you can use Generic Mapping to link SKU numbers from a backend system to the corresponding SKU numbers within Salesforce B2C Commerce Cloud, even if formatted differently. This is especially useful when you are integrating third-party systems that may not be familiar with data formats used by B2C Commerce Cloud or if you have a large set of static information needed to make calculations or lookups. ## Steps to Utilize Generic Mapping ### Create the Mapping File The first task is to structure a .csv file that defines your mapping. The file should meet the following criteria: - Each line corresponds to one key-value pair, separated by commas. - The first row specifies property names that will serve as keys in the map retrieved by `MappingMgr.get(mapping, key).` - The rest of the file contains your data in the format (`<key>`\[,`<key2>`,…\],`<value1>`\[,`<value2>`,`<value3>`,…\])`.` - Any malformed records result in the import process being aborted. Here’s an example of how your CSV might look: ```text backendSKU,commerceCloudSKU 12345,67890 12346,67891 ... ``` #### Compound Keys ![This key is a unique representation of the 'Compound Key' system in Generic Mappings, crafted from multiple metal puzzle pieces. The key is striking in its design, with a complete key lying in the center, surrounded by unused pieces that were likely intended to be used for different variations of the key. The craftsmanship of the metal pieces is impressive, with intricate designs etched into each individual piece. The key itself appears to be the final piece in a complex puzzle, with the other pieces surrounding it serving as potential alternative solutions to unlocking whatever the key is meant to open. Overall, this key is a fascinating example of the ingenuity and creativity that goes into the design of complex systems like Generic Mappings.](/leveraging-generic-mappings-in-sfcc/a-key-created-with-puzzle-pieces-c01118782f_hu_1cb08b25686b292b.webp) Compound keys in a CSV file refer to combining multiple columns to create a unique identifier for the mapping entries. Unlike a simple key using a single data point, a compound key requires two or more data points to form a unique one. You might need to use a compound key when you cannot uniquely identify an item with a single-column value. Instead, you need to use a combination of values to ensure uniqueness. Here’s how you might define a mapping with compound keys in your `.csv` file: ```text productCode,locationCode,commerceCloudSKU PROD001,LOC001,CC_SKU_001 PROD001,LOC002,CC_SKU_002 PROD002,LOC001,CC_SKU_003 ... ``` This will affect how you do configurations in the following steps. I may be getting ahead of myself, but here are some essential things to remember: - In the Job configuration, the KeyCount is “key 🔑” here - In the code, the “[MappingKey](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_util_MappingKey.html)” class is there to make usage of Compound Keys easier ### Upload the Mapping File As with any file-based operation, to make the .csv mapping accessible, upload it to the B2C Commerce server. Use the Business Manager at `Administration > Site Development > Import & Export`, or upload it to the Impex directory via WebDAV or an HTTP client. Just to remind you, mappings are global and must be explicitly imported on each instance. ### Import the Generic Mapping Now, it’s time to create an automation job using the [`ImportKeyValueMapping`](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/jobstepapi/html/index.html) step: [![Job configuration showing the ImportKeyValueMapping step for generic mappings.](/leveraging-generic-mappings-in-sfcc/job-import-generic-mapping-2cce4b36aa_hu_180dd547bf1dac3a.webp)](/leveraging-generic-mappings-in-sfcc/job-import-generic-mapping-2cce4b36aa.jpg) Job Step Parameters: - **AfterImportFileHandling:** Determines what happens to the file post-import. Options include Keep, Delete, Archive, Archive Zipped (`AfterImportFileHandling: 'Archive'`). - **WorkingFolder:** The source folder of your files relative to IMPEX/src. (WorkingFolder: ‘customization’). - **FileNamePattern:** Regex to select import files (`FileNamePattern: '.*.csv'`). - **ImportFailedHandling:** How to handle failed imports—WARN skips, ERROR aborts (`ImportFailedHandling: 'WARN'`). - **KeyCount:** Leave this at one unless you use a Compound Key. (KeyCount: ‘1’) - **ImportMode:** Specifies how the import should proceed—Replace, Merge, Delete (`ImportMode: 'Replace'`). - **MappingName:** The name used to access the mapping (`MappingName: 'backend-to-web-skus'`). We will need this later in the code! ### Accessing Values in Code After the mapping is set up and the job is created, access the mappings in your script using the `dw.util.MappingMgr` class: ```js var MappingMgr = require('dw/util/MappingMgr'); var MappingKey = require('dw/util/MappingKey'); // Retrieving the entire map with all properties for a specific key var map = MappingMgr.get('backend-to-web-skus', new MappingKey('12345')); // Accessing the B2C Commerce SKU associated with a backend SKU var commerceCloudSKU = map.get('commerceCloudSKU'); ``` #### Advanced Usage: Iterators and Mapping Names Iterate over all keys or list all known mappings to enable more dynamic and adaptive script implementations: ```js var iterator = MappingMgr.keyIterator('backend-to-web-skus'); while (iterator.hasNext()) { var key = iterator.next(); var value = MappingMgr.getFirst('backend-to-web-skus', key); // Processing code here } ``` ## Best Practices and Limitations - Mappings should be planned carefully as they’re global and can impact all sites within an instance. - Single `.csv` files are limited to 20 MB, roughly translating to 1 million records of 20 bytes each. - A maximum of 20 mappings are supported to prevent performance degradation. - Clean and consistent data is crucial before uploading .csv files to prevent mapping inaccuracies and operational problems. - Maintain consistency across all environments and communicate updates to stakeholders by carefully managing changes to your key-value mappings and keeping a detailed change log. - Maintaining backups of your mapping files and having a disaster recovery plan to restore them in case of data loss or corruption is important. --- ## Slicing versus Variation Groups in Commerce Cloud Canonical URL: https://rhino-inquisitor.com/slicing-versus-variation-groups-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/slicing-versus-variation-groups-in-sfcc/index.md Content type: article Published: 2023-11-20T11:08:09Z Updated: 2023-11-20T11:59:10Z Summary: Learn the difference between slicing and variation groups in Commerce Cloud, and when each model fits your product setup best. Categories: Documentation, Salesforce Commerce Cloud Tags: sfcc ## Key Takeaways - Compares slicing and variation groups as two ways to model product variation in SFCC catalogs - Argues that variation groups are usually the stronger option for merchandising, SEO stability, promotions, and composable storefront support - Highlights the operational and quota implications teams should understand before choosing a product-modeling strategy Clarity and efficiency are key in the strategic display and management of products in your online store. In an age where various product options and variations dominate e-commerce, [we must grasp the organisational tools at our disposal](/getting-to-know-sfra-as-a-developer/). Today, we’re thoroughly examining two tools provided by Salesforce B2C Commerce Cloud: ‘Slicing’ and ‘Variation Groups’. Both are an option in product management, but which is your best bet? In this article (and I am giving away already which option blows the other out of the window), I hope to help you prepare to understand these concepts in depth and learn why, more often than not, Variation Groups may be your best bet for an exceptional online catalog management system. ## What is slicing ![Cartoon robot slicing a cake decorated as a t-shirt on a cutting board](/slicing-versus-variation-groups-in-sfcc/a-robot-slicing-a-tshirt-27ef2248fc_hu_e817e63c875895da.webp) Figure 1: Slicing—A legacy method of separating product variants by a single attribute Slicing is a method of catalog management that hinges on separating product variants according to one attribute. It simplifies the distinct appearance of products by isolating them based on a characteristic like colour or size. For a while, this approach was quite popular as it provided a clear-cut way to handle product variations, particularly in systems with large counts of SKUs. The idea was that each variant stands alone, making it easy to list and manage inventory. But simplicity comes at a price. When a variant sells out, it vanishes from the storefront, leaving a gap in your catalog and potentially disrupting the customer’s shopping experience. What’s more, this can be detrimental to your site’s search engine ranking as each variant has its URL that might get indexed, and having this URL disappear can undo SEO optimisations. From an operational standpoint, slicing demands that you replicate this process for each category your product fits into, escalating manual work and the likelihood of human error in maintaining a cohesive store experience. ## What are variation groups ![Diagram showing hierarchy of Base Product containing Variation Groups (color) which contain Variants (size)](/slicing-versus-variation-groups-in-sfcc/base-variation-group-variant-explained-ed19da17b7_hu_4fcf49addf42507d.webp) Figure 2: Modern Architecture—Base Product, Variation Group, and Variant hierarchy system The “Master Product” has been renamed to “Base Product” to be more inclusive. [Variation Groups](https://help.salesforce.com/s/articleView?id=cc.b2c_managing_variation_groups.htm&type=5) present a more refined and flexible approach to managing product variants. Think of a digital catalog where products are not sorted based on one characteristic, but rather, traits can mix and match across different features. This allows you to easily find a specific combination of products, like “all blue items in any size” or “small size in any colour.” Variation Groups are what make this possible. These are groups of different versions of a product, all based on a central Variation Base, that are arranged in logical combinations that shoppers often look for. Variation Groups are really useful because they help to show a product line in a complete way. They take information about the inventory from a group of SKUs, which makes it easier to keep track of the amount of each product you have and to show the products consistently. With Variation Groups, you can also choose specific products based on certain attributes like color and size, and place them in your store in a way that makes sense. Variation Groups also make it possible to tag products to promotions, which gives you more control over sales. This is something that is difficult to do with traditional product organization methods. Variation Groups are really helpful in situations where you have lots of products that need to be managed carefully, and where you need to make sure that everything looks and works well together. ## Why use Variation Groups over Slicing [The leap from slicing to Variation Groups](/slicing-versus-variation-groups-in-sfcc/b2c-commerce-variation-group-guide.pdf) feels natural when considering the modern expectations of both merchants and customers online: - **Enhanced Control Over Display:** Variation Groups give you exacting authority over how products are presented in the store. Attributes maintained at the Group level contribute to a refined attribute value fallback system for variants, ensuring that variations adhere to predefined display rules without constant manual adjustments. - **Merchandising with Precision:** By assigning specific colours or sizes to content slots on grid or landing pages or curating sets by attributes within Variation Groups, you can create an aesthetically pleasing and user-friendly browsing experience. - **SEO and Inventory Consistency:** Since Variation Groups are indexed as a single entity, they avoid the SEO pitfalls of slicing, where individual out-of-stock variants negatively impact search visibility. Variation Groups stand sturdily in search engine results, maintaining a stable presence. - **Promotional Dexterity:** Variation Groups offer nuanced promotional capabilities, syncing effectively with seasonal or flash sales without needing individual product-level discounts, streamlining the promotional mechanics and adding value to the customer journey. - **Simple Category Management:** Variation Groups allow for reordering product displays in the view, which is invaluable for visual merchandising and alleviating the daily grind of category management. Conversely, slicing necessitates individual attention for [each product within categories](https://help.salesforce.com/s/articleView?id=cc.b2c_variation_slicing_by_category.htm&type=5). - **Composable Storefront:** Although SFRA and SiteGenesis supported slicing, the PWA Kit has never been tested with slicing and solely supports Variation Groups out of the box. - **Slicing is kind of deprecated:** Although the [Trailhead Module](https://trailhead.salesforce.com/content/learn/modules/b2c-catalog-category-product/b2c-configure-variation-groups-slicing) and documentation no longer show a deprecation message (I somehow remember it visible in more places), it is a deprecated feature (proved by the previous point). ![ProductSearchHit API documentation showing deprecation warning for slicing in favor of variation groups](/slicing-versus-variation-groups-in-sfcc/sfcc-slicing-deprecated-42f8438771_hu_905055ea468c33b8.webp) Figure 3: Slicing Deprecation Notice—Official warning in SFCC ProductSearchHit class documentation One location still has the deprecation message. ## Quota Limits ![Salesforce documentation showing quota limits for maximum number of variations per base product](/slicing-versus-variation-groups-in-sfcc/variations-quota-limit-sfcc-00862ef947_hu_cb16aeb61b101c9f.webp) Figure 4: Variation Quota Limits—Critical maximum variations constraint for large catalogs When dealing with variations, it is crucial to be mindful of a single quota limit - the maximum number of variations per base product, similar to slicing. However, this limit is generally more lenient than other platforms, like [Shopify](https://help.shopify.com/en/manual/products/variants/add-variants) and [Commercetools](https://docs.commercetools.com/learning-composable-commerce-administrator/product-modeling/products#:~:text=A%20Product%20can%20only%20have%20100%20Product%20Variants.), which restrict the number of variations to only 100. ## Conclusion While slicing provided a rudimentary structural approach to product management, Variation Groups currently embody the sophistication required in the fast-paced, multifaceted world of e-commerce. They offer fluid merchandising, robust category management, and a cohesive approach to inventory and promotion strategies, aligning with the needs and behaviours of online shoppers. By leveraging Variation Groups within Salesforce B2C Commerce Cloud, merchants gain a competitive edge, ensuring their storefronts are adaptable, customer-centric, and optimised for operational excellence. As your digital storefront evolves, remember that Variation Groups are more than just a feature; they are a strategic stepping stone towards a more elegant, intuitive, and successful online retail presence. --- ## New APIs and Features for a Headless B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/new-apis-and-features-for-a-headless-sfcc/ Markdown URL: https://rhino-inquisitor.com/new-apis-and-features-for-a-headless-sfcc/index.md Content type: article Published: 2023-11-13T09:54:35Z Updated: 2023-11-15T12:18:11Z Summary: Review the new SCAPI and headless platform features in Salesforce B2C Commerce Cloud, and see which updates matter most for composable storefront teams. Categories: Release Notes, Salesforce Commerce Cloud Tags: headless, sfcc ## Key Takeaways - Highlights headless-focused platform updates across Managed Runtime, PWA Kit, and SCAPI - Explains why Storefront Preview and URL Resolution are important gaps being closed for composable storefront teams - Calls out new logging, CSP, and Store APIs that affect real-world headless implementation work The holiday period was quiet for a long time regarding [Salesforce B2C Commerce Cloud releases](/category/release-notes/). This was because the monolithic system required the deployment of all components, which carried the risk of bugs. However, more options are now available with multiple “layers” in the Headless architecture. Each layer can have its release schedule, and some layers are more modular than others, allowing for finer-grained releases that will not impact the rest (at least in theory). Major new releases are happening for the first time during the holiday season. And it’s pretty exciting! ## Managed Runtime ### Storefront Preview [Storefront Preview demo video](/new-apis-and-features-for-a-headless-sfcc/storefront-preview-demo.mp4) The “Shop the Future” feature seems to have been on the Wishlist since the release of the PWA Kit. This feature was highly sought-after by merchandisers as it allowed them to set up promotions and content in advance and see how they would appear on the site. However, it can be challenging to implement this feature without the right APIs in a Headless or Composable Commerce setup. Fortunately, this challenge can be overcome with the “[Shop the Future](https://developer.salesforce.com/docs/commerce/commerce-api/guide/shopper-context-api-future.html)” and “[Shopper Context](https://developer.salesforce.com/docs/commerce/commerce-api/guide/shopper-context-api-personalized.html)” options provided by the SCAPI. This is a big win for any project already on or going to the Composable Storefront! [Here is a guide to get you started on setting it up](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/storefront-preview.html). ### Changes for the future [Runtime Admin changes demo video](/new-apis-and-features-for-a-headless-sfcc/runtime-admin-changes.mp4) Headless and Composable architectures bring great flexibility for the future but pose particular challenges in monitoring and analytics. One of the significant challenges is consolidating data from multiple entities. Salesforce has now made it mandatory to specify the back-end you connect from your storefront. This will eliminate guesswork and ensure correct logging is sent to the [Log Center](https://help.salesforce.com/s/articleView?id=cc.b2c_log_center.htm&language=en_US&type=5) linked to the respective environment. Automatically forwarding logs to the Log Center offers multiple benefits to Salesforce support and users of the Composable Storefront. With this feature, logs for HTTP requests made on production-marked environments are automatically sent, enabling them to anticipate better and troubleshoot any issues that may arise. ## PWA Kit v3.2.1 With the changes happening in the managed runtime, two new releases have happened in the past month of the PWA Kit: - [3.2.0](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.2.0) - [3.2.1](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.2.1) Besides the Storefront Preview feature, there are changes to how “[Content-Security-Policy](/secure-coding-in-salesforce-b2c-commerce-cloud/)” is managed in this release. Be sure to review the changes as they are significant. ## OCAPI & SCAPI ### Shopper SEO - Headless URL Resolution There is a new API in town. SiteGenesis and SFRA have had the ability forever to resolve any type of URL that you configured in the Business manager, and automatically redirect the user to the right place! But for the PWA Kit or Headless projects, that piece of magic was always missing - until now! Meet the new [URL Resolution API](https://developer.salesforce.com/docs/commerce/commerce-api/guide/url-resolution.html)! Performance I suggest following the best practices mentioned in the documentation and using your routing system as the primary option. This API should only be used as a backup. Keep in mind that making an API call involves network hops that can potentially slow down your application. _I believe that in the future, we will witness endpoints to address some of the gaps that exist compared to SFRA. I have also learned that an upcoming feature will enable direct resolution to the SCAPI payload rather than just the relative ObjectID._ ### Stores ![A drawing of retail stores connected by lines; in this case, the lines are Ethernet cables referencing the REST APIs to fetch the store data in Headless applications.](/new-apis-and-features-for-a-headless-sfcc/connected-stores-22cea94a19_hu_eff7bc5cfad66523.webp) Figure 1: A drawing of retail stores connected by lines; in this case, the lines are Ethernet cables referencing the REST APIs to fetch the store data in Headless applications If you remember, the SCAPI release included a “Shopper Stores” group that allowed developers to build their own Store Locator in Headless scenarios. Unfortunately, this feature was short-lived and disappeared soon after. However, with the Stores API now back in action, developers can again use the “Shopper Stores” group to create custom store locators that meet their specific needs. This significant development will be welcomed by those eagerly waiting for [this functionality](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-stores?meta=Summary) to return. I only question how quickly this will make it into the PWA Kit priority-wise. Maybe this could become one of the more extensive community contributions. Who knows? ### More on the horizon? I received some exciting news about new APIs that Salesforce is currently developing. A custom object API and site preferences API are in active development and are expected to be released in the next cycle. What APIs would you like to see? Maybe it is … (_slowly walks over to the next section_) ## Time for Feedback Have you ever felt helpless when you couldn’t provide feedback on a product? Worry no more! Salesforce is looking for your valuable feedback on their Composable Storefront. They want to hear your honest opinion - the good, the bad, and everything in between. Your feedback will help them improve their product and make it even better. What are you waiting for? [Share your thoughts and help Salesforce build a product that meets your needs!](https://docs.google.com/forms/d/e/1FAIpQLSdLgfMBo9UnjF84h9sj5UxWm9em1nL0ApTRpRgiDXWWBJKpDQ/viewform) --- ## Life is about choices Canonical URL: https://rhino-inquisitor.com/life-is-about-choices/ Markdown URL: https://rhino-inquisitor.com/life-is-about-choices/index.md Content type: article Published: 2023-11-06T17:31:55Z Updated: 2023-11-06T17:32:02Z Summary: Have you ever wondered how some people seem to have it all together? How do they manage to balance work, family, and personal interests? Categories: Community Tags: event, ohana ## Key Takeaways - Reflects on how career, family, community work, and personal interests compete for the same limited time - Explains the trade-offs behind prioritizing family and Salesforce community involvement over other hobbies - Argues that the visible highlights of a public career often hide real sacrifices and deliberate choices Have you ever wondered how some people seem to have it all together? How do they manage to balance work, family, and personal interests? I often get asked this question, and it’s a valid one. Life is full of choices, and we must decide how we want to spend our time. In this article, I will share my experience of finding the time to do what I love and the choices I’ve made along the way. ## Family & Salesforce As the Head of Commerce at Forward, I have a deep passion for everything Salesforce, specifically [Salesforce B2C Commerce Cloud](https://www.salesforce.com/nl/campaign/sem/commerce-cloud/?d=7013y000000ZiZWAA0&utm_source=google&utm_medium=sem&utm_campaign=nl_alllobcon&utm_content=_7013y000000ZiZWAA0&soc=Google-commerce-cloud&ef_id=Cj0KCQjw-pyqBhDmARIsAKd9XIN5JEeCyJb-jki0mVkSNGsVjJRRwZzvvahGq5KearIHpTEixKnOtzoaAophEALw_wcB:G:s&s_kwcid=AL!7501!3!442529105175!p!!g!!salesforce%20b2c%20commerce&&mkwid=s&pcrid=442529105175&pkw=salesforce%20b2c%20commerce&pmt=p&pdv=c&gad_source=1&gclsrc=ds) (duh). I’ve worked with Salesforce for a long time and have built a wealth of knowledge and experience in the field. I’ve also been an active member of the Salesforce Ohana, contributing to the community and sharing my knowledge to help others succeed. But my passions don’t stop there. I am also a proud father of two wonderful children, and being a dad is one of the most rewarding experiences of my life. I always make time for my family, which is the most important thing to me. ![Comic-style family portrait at the zoo underscoring the family-priority theme.](/life-is-about-choices/img-0051-979cd7bd1c_hu_4256c5e60d8a85d6.webp) Prioritising family over career milestones is one of the defining choices that shapes a developer's journey. However, this balance means I have had to choose how to spend my time. That meant prioritising my family and Salesforce over other personal interests. It’s not always easy, but it’s a decision that I am happy with. By following my passion for Salesforce and being there for my family, I can be the best version of myself. I understand that it’s not possible to have it all, but I’m content with my choices and focus on what truly matters to me. ## Goodbye games and fitness ![A comic book of three panels depicting someone running slowly transitioning to someone in a corporate office behind a desk working. This is the result of choices made!](/life-is-about-choices/img-0050-470298895d_hu_656008c1b790f1b8.webp) Trading active hobbies for a desk career is a trade-off many developers make without realising the long-term cost. Ok… I never had this kind of physique… Doing all this also means less time for sports and fitness. I used to be very active and enjoyed doing sports. It was a big part of my life and helped me stay in shape, but now my time is limited. I am also a big fan of video games and anime. I would spend hours playing my favourite games and watching One Piece, immersing myself in different worlds and enjoying the challenge of overcoming obstacles. I found it a great way to relax and unwind after a long day at work. I enjoyed playing a variety of games, from first-person shooters to RPGs. But, as they say, everything comes with a cost, and the joy and love that my children bring far outweigh any sacrifices I’ve made. ## Events Being a part of the Salesforce Ohana has allowed me to attend many exciting events, such as [Dreamforce](/chasing-clouds-catching-up-with-the-commercecrew-at-dreamforce-2023/). These events are an excellent opportunity for me to connect with other Salesforce enthusiasts, learn from industry leaders and experts, and stay updated with the latest Salesforce ecosystem developments. However, attending these events also means being away from my family and putting additional responsibility on my wife to take care of the kids by herself (with the help of our parents). This is why I must carefully decide which [events](/community-salesforce-events-and-commerce-cloud/) to attend, considering the cost and the impact on my family. As my children get older, I plan to find a way to combine these events and holiday trips. But for now, that is not always really a possibility. ## Beneath the glamour In life, we are constantly faced with choices and decisions. Whether deciding between a career move, starting a family, attending an event, staying home with loved ones or going out with friends. These choices shape our lives and shape who we are. ![Split-scene illustration contrasting visible career success with unseen sacrifices at home.](/life-is-about-choices/img-0058-3f3716c170_hu_e00c1de480926cae.webp) The highlight reel of career success rarely shows the family time and personal health sacrificed behind the scenes. The life you see versus the part you don’t. This may be an over-dramatic representation… Everyone is fighting battles you don’t know about. It’s easy to get caught up in the highlight reel of life on social media, where people constantly post about their successes and accomplishments. But we often don’t see the sacrifices and failures people endured to get to this point. _Just make sure you are happy with the future you are forming for yourself! Sacrifices and failures are part of the journey…_ --- ## Getting to know SFRA as a developer Canonical URL: https://rhino-inquisitor.com/getting-to-know-sfra-as-a-developer/ Markdown URL: https://rhino-inquisitor.com/getting-to-know-sfra-as-a-developer/index.md Content type: article Published: 2023-10-30T09:57:46Z Updated: 2023-10-31T09:11:09Z Summary: SFRA in Salesforce B2C Commerce can be quite daunting. This blog post will guide you through all of the content of Commerce Cloud SFRA! Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, sfra, technical ## Key Takeaways - Organizes a practical learning path for developers who are new to SFRA and SFCC - Points readers to sandbox setup, platform fundamentals, and official SFRA learning resources - Connects self-study, partner training, and certification prep into one onboarding path So, you are new to Salesforce Commerce Cloud and have begun your journey with SFRA! Congratulations, and welcome to the [community](https://unofficialsfcc.com/) of SFCC developers! But where to start? Quite a bit of information is available, but where you should start is unclear. Not to worry. Let’s get that information organised for you! ## Get to know B2C Commerce Cloud You can’t just start developing immediately on Salesforce B2C Commerce Cloud. The platform is just too big for that. I wish it were that easy, but SFCC is an enterprise platform with many out-of-the-box features and options you must learn about first. ### Get your own playground Watching webinars and reading online texts can get tedious. Being able to apply what you learn immediately on a Sandbox is a lot more engaging and fun to do. I wrote a separate post before explaining how to get your sandbox [in this guide to getting your sandbox](/how-to-get-a-salesforce-b2c-commerce-cloud-sandbox/). Just a word of warning: if you are not working for a partner or customer - you might end up disappointed at the end of the article. ### Learn Commerce Cloud ![Archived Learn Commerce Cloud landing page.](/getting-to-know-sfra-as-a-developer/learn-commerce-cloud-67eab48d9b_hu_e18fffe82cf3c6ec.webp) - [https://help.salesforce.com/s/articleView?language=en\_US&id=cc.b2c\_getting\_started.htm&type=5](https://help.salesforce.com/s/articleView?language=en_US&id=cc.b2c_getting_started.htm&type=5) - [PDF Version of the old Learn Commerce Cloud Site](/getting-to-know-sfra-as-a-developer/learn-commerce-cloud-site.pdf) Your first starting point in your journey into Salesforce B2C Commerce Cloud as a platform. This site is not built with developers in mind but for everyone new. It serves as a guide into the ecosystem using: - Trailheads - Webinars - Documentation It also touches on all different aspects of commerce in general: - Getting to know Commerce Cloud - UX/UI Best Practices - Personalization - Product Management - Search Management (Search, Sorting, and Refining) - Promotions & Campaigns - Einstein and AI That is a lot of ground this single site covers! And be sure that it will keep you busy for a couple of days, and you won’t be writing a single line of code…sorry, not sorry. 😋 **Note:** Be sure to have your sandbox ready so you can try out some of the concepts in your environment. Not everything can be done on a Sandbox (like Einstein), but most of it is. ### Storefront Reference Architecture (SFRA) Overview - [Webinar](https://salesforce.vidyard.com/watch/rgvLUk97rk1Kg58nYVcuy9?) - [Slide Deck](https://org62.my.salesforce.com/sfc/p/#000000000062/a/3y000001RUL7/WABOD.HWfTOAp9saRlAVkrc7QesnH26Xj6mb_IkPk0M) This webinar provides an overview of the positioning of SFRA and its features. Since this is what you will be developing in, it is a must-watch! ## On to development This is the part you have been waiting for right? Getting your hands “dirty” in the SFRA code, figuring out how to customize that storefront, and integrating some third-party systems! ### SFRA Developer Guide - [https://developer.salesforce.com/docs/commerce/sfra/guide/sfra-overview.html](https://developer.salesforce.com/docs/commerce/sfra/guide/sfra-overview.html) The developer website of Commerce Cloud is targeted at you (yes, you. It says developer in the URL, right?) This website will tell you how to get started with your SFRA implementation with: - Information about SFRA in general - UX Deep Dive - Technical Deep Dive - SFRA Fast Path webinars (development webinars) - A list of tools and how to get access to GitHub repositories of SFRA - Much more! ### Partner Learning Camp ![Partner Learning Camp catalog showing the B2C Commerce Foundations course.](/getting-to-know-sfra-as-a-developer/b2c-foundations-2daffad6c6_hu_ab5a13ebf6115f2a.webp) - [https://partnerlearningcamp.salesforce.com](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=5iuux101vYk2UQtOkwn9%2BpFhmsL%2F5jynd8uOnEFtSg4JjoBEe8yyDv9MajFikOJe) This website is only available if you are a partner of Salesforce; if you are a customer, you will not be able to access this content (sorry). Here you will find a complete self-study-guided course into Salesforce B2C Commerce Cloud SFRA development. It starts at setting up your environment (sandbox) and slowly moves you through all of the different concepts of SFRA development: - Cartridges - Controllers - Models - ISML - Client-Side Javascript in SFRA - Forms - Transaction Management (Database) - Jobs Framework - OCAPI ## Certification If you’re considering pursuing certification, congratulations! It’s a great way to demonstrate your expertise and stand out. To help you prepare, I’ve compiled [a comprehensive list of valuable topics to study](/preparing-for-the-b2c-commerce-developer-certification/). By taking the time to delve deep into these subjects, you’ll expand your knowledge and better position yourself for success. ## That’s not all folks The contents above will keep you busy for days and weeks (depending on whether you sleep.) But much more content is available to be seen, read, and heard! In [a previous post](/salesforce-b2c-commerce-cloud-documentation/), I listed more sites you can use in your journey! --- ## SFCC Global Functions Overview Canonical URL: https://rhino-inquisitor.com/an-overview-of-sfcc-global-functions/ Markdown URL: https://rhino-inquisitor.com/an-overview-of-sfcc-global-functions/index.md Content type: article Published: 2023-10-23T12:06:05Z Updated: 2023-10-23T12:06:05Z Summary: Explore the server-side global functions available in SFCC, when to use them, and how they can simplify day-to-day development work. Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, technical ## Key Takeaways - Surveys the most useful server-side global functions available in SFCC - Explains where encoding, parsing, emptiness, and numeric helpers are practical - Warns that eval is deprecated and risky in server-side Commerce Cloud code In development, it’s essential to have access to useful functions that can make your work more efficient. [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/) offers several global functions which are helpful when working on the server side. These functions have a range of capabilities, from encoding and decoding characters in a URI to executing JavaScript code from a string. This article will explore these functions in detail and discuss how developers can use them to streamline their development process. ## encodeURI and encodeURIComponent ```javascript encodeURI('https://mozilla.org/?x=шеллы'); // https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B encodeURIComponent('шеллы'); // ?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B ``` These functions are used to escape characters in a URI or URI component. The encodeURI function escapes characters in a URI, while the encodeURIComponent function escapes characters in a URI component. Both functions take a string that contains a URI or URI component and return a copy of the input string with certain characters replaced by hexadecimal escape sequences. ## decodeURI and decodeURIComponent ```javascript decodeURI('https://www.google.com/search?q=decodeuri%20example%20%C3%A5%D0%B5%D0%BB'); // https://www.google.com/search?q=decodeuri example åел decodeURIComponent('query=?/learning tō dėcōdė'); //query=?/learning tō dėcōdė ``` These functions are used to unescape characters in a URI component. The [decodeURI](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_global.html?resultof=%22%67%6c%6f%62%61%6c%22%20%22%63%6c%61%73%73%22%20#TopLevel_global_decodeURI_String_DetailAnchor) function unescapes characters in a URI, while the [decodeURIComponent](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_global.html?resultof=%22%67%6c%6f%62%61%6c%22%20%22%63%6c%61%73%73%22%20#TopLevel_global_decodeURIComponent_String_DetailAnchor) function unescapes characters in a URI component. Both these global functions take a string that contains an encoded URI or URI component and return a copy of the input string with any hexadecimal escape sequences replaced with the characters they represent. ## empty ```javascript empty('') // true empty([]); // true empty('a string'); // false ``` The [empty](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_global.html?resultof=%22%67%6c%6f%62%61%6c%22%20%22%63%6c%61%73%73%22%20#TopLevel_global_empty_Object_DetailAnchor) function is used to test whether a given object is empty. The interpretation of empty is the following: null is always empty: - undefined is always empty - a string with zero length is empty - an array with no elements is empty - a collection with no elements is empty. - an object returns true if the object is interpreted as empty. ## escape and unescape ![A drawing of a jail cell with a man in orange.](/an-overview-of-sfcc-global-functions/global-function-escape-drawing-a5cb04538d_hu_5c1defba55847709.webp) ```javascript escape("äöü"); // "%E4%F6%FC" unescape("%E4%F6%FC"); // "äöü" ``` The [escape](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_global.html?resultof=%22%67%6c%6f%62%61%6c%22%20%22%63%6c%61%73%73%22%20#TopLevel_global_escape_String_DetailAnchor) function encodes a string by replacing characters with hexadecimal escape sequences. The [unescape](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_global.html?resultof=%22%67%6c%6f%62%61%6c%22%20%22%63%6c%61%73%73%22%20#TopLevel_global_unescape_String_DetailAnchor) function decodes an escaped string by replacing hexadecimal character sequences with Unicode characters. Both global functions take a string as a parameter and return a copy of the input string with characters encoded or decoded. ## eval > Executing JavaScript from a string is an enormous security risk. It is far too easy for a bad actor to run arbitrary code when you use eval(). ```javascript eval('2 + 2'); // 4 ``` The [eval](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_global.html?resultof=%22%67%6c%6f%62%61%6c%22%20%22%63%6c%61%73%73%22%20#TopLevel_global_eval_String_DetailAnchor) function is used to execute JavaScript code from a string. However, **it is deprecated because it can be a potential security risk for server-side code injection**. The function takes a string that contains the JavaScript expression to be evaluated or the statements to be executed and returns the value of the executed call or null. ## isFinite and isNaN ![Infinity-themed illustration introducing the isFinite and isNaN global functions.](/an-overview-of-sfcc-global-functions/the-infinity-of-space-5e44ec8ec6_hu_54be878f4ea933bb.webp) ```javascript isFinite(1000 / 0); // false isFinite(100 / 1); // true isNaN('100F'); // true isNaN('0.0314E+2'); // false ``` The [isFinite](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_global.html?resultof=%22%67%6c%6f%62%61%6c%22%20%22%63%6c%61%73%73%22%20#TopLevel_global_isFinite_Number_DetailAnchor) function is used to determine whether a specified number is finite. It takes a number as a parameter and returns true if the specified number is finite, false otherwise. The [isNaN](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_global.html?resultof=%22%67%6c%6f%62%61%6c%22%20%22%63%6c%61%73%73%22%20#TopLevel_global_isNaN_Object_DetailAnchor) function tests the specified value to determine if it is not a number. It takes an object as a parameter and returns true if the object is not a number. ## parseFloat and parseInt ```javascript parseFloat('28.695307297889173'); // 28.695307297889173 parseInt('28.695307297889173'); // 28 ``` The [parseFloat](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_global.html?resultof=%22%67%6c%6f%62%61%6c%22%20%22%63%6c%61%73%73%22%20#TopLevel_global_parseFloat_String_DetailAnchor) function is used to parse a string into a floating-point number. It takes a string as a parameter and returns the float as a number. The [parseInt](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_global.html?resultof=%22%67%6c%6f%62%61%6c%22%20%22%63%6c%61%73%73%22%20#TopLevel_global_parseInt_1_String_DetailAnchor) function uses the specified radix to parse a string into an integer number. If no radix is specified, the function automatically determines the radix based on the input string. These functions return the integer as a number. ## Other global functions Not all global functions that are available are described in this article, but the most important (and used) ones are. Interested in what these functions are? Then have a look at [the documentation](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/index.html?target=class_TopLevel_global.html)! --- ## Using Custom Preferences in SFCC Canonical URL: https://rhino-inquisitor.com/custom-preferences-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/custom-preferences-in-sfcc/index.md Content type: article Published: 2023-10-16T12:01:58Z Updated: 2023-10-16T18:11:19Z Summary: Learn how SFCC custom preferences support configurable storefront behavior, governance, and safer environment-specific settings. Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, technical ## Key Takeaways - Explains when to use global preferences, site preferences, or code config files in SFCC - Shows how preference scope affects governance, reuse, and environment-specific behavior - Highlights practical tips like defaults, descriptions, and change-history troubleshooting [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/) uses custom preferences to store configurable settings for a storefront. These settings can be anything from feature settings to loyalty calculations. Custom preferences can be created at two levels: - global (organisation) - site As a Salesforce B2C Commerce Cloud developer, you must understand the differences between Global Preferences and Site Preferences and use each appropriately. ## Global Custom Preferences [Global Preferences](https://help.salesforce.com/s/articleView?language=en_US&id=cc.b2c_global_preferences.htm) are organisation-level preferences that any site within the environment can access. These preferences are ideal for settings that are common across all sites. For example, if all sites in an organisation use the same preference value, using a global value is your best bet. This can help reduce code duplication and make maintaining and updating settings across multiple sites more accessible. Global Preferences can be accessed using the System Preferences API: ```js var System = require('dw/system'); var orgPrefs = System.getPreferences(); var myCustomPreference = orgPrefs.getCustom().myCustomPreference; ``` To add your preferences on this global level, head here in the Business Manager: `Administration > Site Development > System Object Types > OrganizationPreferences` ## Site Specific Custom Preferences [Site Preferences](https://help.salesforce.com/s/articleView?language=en_US&id=cc.b2c_site_preferences.htm) are site-level preferences that can only be accessed by the site to which they belong. These preferences are ideal for settings that are specific to a site. For example, if a site has a particular loyalty program calculation not used by any other site, use Site Preferences. This can help ensure that settings are only applied to the site they belong to and do not affect other sites in the organisation. Site Preferences can be accessed using the Site API: ```js var Site = require('dw/system/Site'); var sitePrefs = Site.getCurrent().getCustom(); var loyaltyEnabled = sitePrefs.loyaltyEnabled; ``` To add your preferences on this site level, head here in the Business Manager: `Administration > Site Development > System Object Types > Site Preferences` ## Code Config Files Using a config file can be a better alternative to Custom Preferences. A config file is a file that stores application-specific settings that should not be modifiable in the Business Manager. This can be useful for settings that are not expected to change frequently, such as project-specific settings. ```js // config.json { "loyaltyCalculation": "simple" } // Using the config var config = require('path/to/config.json'); if(config.loyaltyCalculation === 'simple') { // Do some things } ``` Cartridge Overrides Like script files, using “\*” in the path to allow overrides according to the set cartridge path is possible. ## Tips & Tricks ### Custom Attributes If you have reviewed the sample code, you may have noticed that these preferences are similar to how you use custom attributes. That’s because they are custom attributes on System Objects, just like any other extensible object within the [data model](/salesforce-b2c-commerce-cloud-erd/). ### Default Values Luckily, we have the option to set default values for our preferences. This will make it easier if you have a large set of sites, but only one uses a different value than the one you have in mind as the default. Another advantage of setting this default is that your preference will have a preset value right after deployment! Booleans Booleans are an “odd beast” within Salesforce B2C Commerce Cloud. You would expect the default value of a Boolean always to exist and be “false”, but this is not the case. The default value of a Boolean is: “null”! ### Add Descriptions When creating preferences in the business manager, add proper names and descriptions. This will make it easier for users and other developers to understand the purpose of this preference. Without it, it is like having a complication function in the code with no documentation to explain what it is up to! ### Getting to the truth Have you ever encountered a feature in Production that suddenly stopped working due to a preference update, leaving you scratching your head? Fear not! The “[Change History](https://help.salesforce.com/s/articleView?language=en_US&id=cc.b2c_change_history.htm&type=5)” feature is here to save the day! It can help you track down the exact moment and preference that caused the chaos. 7 Days The Change History only shows changes from the past seven days. ## SCAPI Right now, there is no SCAPI endpoint available to fetch site preferences. Only OCAPI endpoints are available to fetch this information. ## Conclusion ![A decision diagram of when to use which type of storage, visualising the article.](/custom-preferences-in-sfcc/global-preferenves-vs-site-specific-3a997fcbab_hu_bfd322d26cd1070a.webp) Figure 1: A decision diagram of when to use which type of storage, visualising the article Using the appropriate type of preference can help ensure that settings are applied correctly and efficiently. Each option has pros and cons, and make sure to weigh in roles and users in making these decisions! --- ## Create External Orders in SFCC with createOrders Canonical URL: https://rhino-inquisitor.com/the-createorders-api-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/the-createorders-api-in-sfcc/index.md Content type: article Published: 2023-10-09T09:54:18Z Updated: 2023-11-18T07:43:19Z Summary: Learn how to use the createOrders API in SFCC to create external orders safely and fit it into existing order workflows. Categories: Salesforce Commerce Cloud, Technical Tags: headless, sfcc, technical ## Key Takeaways - Explains what the createOrders API is for and where it fits best in external-order and social-commerce scenarios - Highlights the validation, pricing, payment, and inventory responsibilities that stay with the origin system using the API - Walks through the SLAS trusted-system authentication flow required before creating orders on behalf of shoppers In this article, we will discuss the [createOrders API](https://developer.salesforce.com/docs/commerce/commerce-api/references/orders?meta=createOrders) used to create orders in the Commerce Cloud platform. The createOrders API is designed to create a fully calculated, paid, or authorised order on the fly in the Commerce Cloud platform. But how does it work? ## When to use the createOrders API With this API, creating an order is a breeze as it eliminates the need to go through the various steps required to create a basket, including authorisation, guest information, managing addresses, payment, and inventory management. One of the most common scenarios where this API comes in handy is selling on social channels and offering in-app purchases. The API enables you to send the entire order to be shipped without going through the usual steps. A third-party provider managing recurring orders can use this API to streamline their processes. The potential use cases for this API are numerous and diverse, and it’s a valuable tool for developers and architects! ## Things to keep in mind If you plan to use this API, know it relies on the origin system that creates the order. This means you must ensure that all the necessary checks and verifications are done in the third-party system before transferring the order into B2C Commerce Cloud. So, what kind of checks are we talking about? Well, a few things need to be verified before the order can be processed. For example, the address to which the order is being shipped must be validated and corrected if there are any errors. You wouldn’t want the package to end up at the wrong address. Another thing that needs to be verified is the payment information. This is important to ensure the transaction is legitimate and the customer can pay for the order. Nobody wants to deal with fraudulent transactions; verifying the payment information is one way to prevent that. Some technical things must be handled - For instance, the order price needs to be calculated accurately. And, if there’s limited inventory for the item being ordered, the stock must be reserved and released promptly. These checks and verifications are essential to ensure that the order is processed correctly and that the customer is satisfied with their purchase. Selling products on a third-party channel is one thing, but you don’t want them to get stuck in the process! ## Implementation ### Getting a SLAS API key We can’t have just anyone pushing orders in our system, do we? So the first step is to create an API key in SLAS! In this case, we will be creating a private client. Using a visual UI to make things easier is possible, [which I explain in a different post](/how-to-set-up-slas-for-the-composable-storefront/). There are a few key differences: - **Which App Type will be used?:** “BFF or Web App”.Choosing this option will create a “private” client. - **Do you want the default shopper scopes?:** Unchecked - **Enter custom shopper scopes:** `sfcc.orders.rw sfcc.ts_ext_on_behalf_of` After you are done, click “Submit” and save the generated Secret that will appear in a message at the top of the page. Server to Server This integration is a server-to-server type, and never make your secret publically visible (browser), as orders can be pushed to your system knowing these credentials. You do not want unknown parties pushing in the wrong data and getting free orders! ### Authenticating Before we can start pushing in orders for anonymous or registered users, we need to get a [Trusted System Access Token](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-login?meta=getTrustedSystemAccessToken). With this token, we will allow our third-party system to act on behalf of a guest or registered user without knowing their credentials. Short Code & Organization ID You can get this information via “Administration > Site Development > Salesforce Commerce API Settings” - **URL:** [Trusted-system token endpoint](https://%7bshortCode%7d.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/%7borganizationId%7d/oauth2/trusted-system/token) - **Authorisation:** Basic Authentication - **Authorisation Format:** `{SLAS Client}:{SLAS Secret}` - **Body:** `application/x-www-form-urlencoded` ```text // guest grant_type:client_credentials hint:ts_ext_on_behalf_of login_id:guest idp_origin:ecom channel_id:RefArchGlobal ``` Within this body, we are authenticating a **guest** customer via “ecom” (B2C Commerce Cloud) for our site “**RefArchGlobal**”. ![Trusted-system extension authentication flow used before calling createOrders.](/the-createorders-api-in-sfcc/slas-ts-ext-on-behalf-of-authentication-3803569585_hu_e9843cc2c0312d89.webp) When submitting your request, the following response should pop out! ```json { "access_token": "JWT TOKEN", "id_token": "", "refresh_token": "A-dhgTIz-WCGVDrt5OwVb4lWD3f2-KmkCAI7e4", "expires_in": 1800, "token_type": "BEARER", "usid": "0884d762-9f45-46e2-812a-2f9cd1d89", "customer_id": "abkbE2leo1lHgRmuwYlqlKsW", "enc_user_id": "", "idp_access_token": null } ``` And with our **access\_token** we can continue our journey and push an order into Commerce Cloud! ### Creating an order Almost there! Now we have everything to start creating our order (except the order itself). We need to do a second API call using the bearer token we generated in the previous step, linking us to that specific customer. - **URL:** [createOrders endpoint](https://%7bshortCode%7d.api.commercecloud.salesforce.com/checkout/orders/v1/organizations/%7borganizationId%7d/orders) - **Authorisation:** Bearer token - **Body:** ```json { "billingAddress": { "address1": "43 Main Rd.", "city": "Burlington", "firstName": "Jane", "lastName": "Doe" }, "channelType": "instagramcommerce", "currency": "USD", "orderNo": "0000019373", "orderTotal": 66.91, "taxTotal": 12.39, "paymentInstruments": [ { "paymentMethodId": "PAYPAL", "paymentTransaction": { "amount": 66.91, "transactionId": "abc13384ajsgdk1" } } ], "productItems": [ { "basePrice": 30.98, "grossPrice": 61.96, "netPrice": 49.57, "productId": "black-shoe_29347-38", "productName": "special edition shoe women 38", "quantity": 2, "shipmentId": "shipment1", "tax": 12.39 } ], "shipments": [ { "shipmentId": "shipment1", "shippingAddress": { "address1": "43 Main Rd.", "city": "Burlington", "firstName": "Jane", "lastName": "Doe" }, "shippingMethod": "EXPRESS", "shippingTotal": 4.95, "taxTotal": 0 } ] } ``` After submitting this request we should get an empty response with status [201](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#201) (CREATED). And with that, our order is visible in the Business Manager! [![SLAS: createOrders API request result](/the-createorders-api-in-sfcc/slas-order-on-behalf-order-4b978450f7_hu_87aba3b64d341cf4.webp)](/the-createorders-api-in-sfcc/slas-order-on-behalf-order-4b978450f7.jpg) ## GMV The method outlined above impacts the [GMV](https://help.salesforce.com/s/articleView?id=cc.b2c_gmv.htm&type=5), which can lead to higher licensing costs. But don’t worry: that’s where negotiation with Salesforce comes in. --- ## SFCC 23.10 Release Overview Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-23-10-release-a-comprehensive-overview/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-23-10-release-a-comprehensive-overview/index.md Content type: article Published: 2023-10-02T12:35:45Z Updated: 2023-10-02T12:35:58Z Summary: It's a yearly tradition not to release major updates during the holiday season to maintain platform stability, so here we are with the final release of Categories: Release Notes, Salesforce Commerce Cloud Tags: release notes, sfcc, technical ## Key Takeaways - Highlights the most notable 23.10 changes such as temporary baskets, managed eCDN certificate renewal, and SCAPI query parameter support - Explains how the release improves both platform capabilities and headless extensibility for modern storefront teams - Calls out related Account Manager and PWA Kit changes that affect operations, compliance, and composable storefront delivery It’s a yearly tradition not to release major updates during the holiday season to maintain platform stability, so here we are with the final release of 2023. This time, we look at the [October 2023 (23.10) release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_23_10_release.htm&type=5)! Are you interested in last month’s release notes? Read the [23.9 release overview](/a-look-at-the-23-9-commerce-cloud-release/). ## Temporary Baskets > You can now create temporary baskets for immediate order requests in B2C Commerce. For example, a shopper uses a Buy Now option to purchase an item. The temporary basket, which has a limited lifetime of 15 minutes, is populated with all the data required to ready the basket for checkout without affecting the regular shopper basket. **How**: Use the basket script API to enable temporary baskets. The supported basket functions include pricing, promotions, coupons, inventory, shipping methods, order creation, and reopening an order. The new feature that allows for multiple baskets is a game-changer. I recall the hassle of having to manipulate transactions frequently to perform real-time calculations without interfering with the current basket, or having to work with custom objects. But now, those days are behind us! Here are the new APIs: - [BasketMgr.createTemporaryBasket()](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/upcoming/scriptapi/html/api/class_dw_order_BasketMgr.html#dw_order_BasketMgr_createTemporaryBasket_DetailAnchor) - [BasketMgr.deleteTemporaryBasket()](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/upcoming/scriptapi/html/api/class_dw_order_BasketMgr.html#dw_order_BasketMgr_deleteTemporaryBasket_Basket_DetailAnchor) - [BasketMgr.getTemporaryBasket()](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/upcoming/scriptapi/html/api/class_dw_order_BasketMgr.html#dw_order_BasketMgr_getTemporaryBasket_String_DetailAnchor) - [BasketMgr.getTemporaryBaskets(](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/upcoming/scriptapi/html/api/class_dw_order_BasketMgr.html#dw_order_BasketMgr_getTemporaryBaskets_DetailAnchor) The SCAPI/OCAPI have not received any updates despite the official documentation still stating the same: > Each customer can have just one open basket. When a basket is created, it is said to be open. It remains open until either an order is created from it or it is deleted. But I hope this will be changed with standard APIs in the future, or once we have full access to the custom API option for POST/PUT/…, we can build them ourselves! ## Platform ### Get Einstein Recommendations for Large Product Catalogs ![Einstein is standing in the middle of a warehouse lane, looking at the camera.](/salesforce-b2c-commerce-cloud-23-10-release-a-comprehensive-overview/einstein-standing-in-a-warehouse-1c76aa5ec5_hu_faedb8b9afd25ae6.webp) > Commerce Cloud Einstein now generates recommendations for product catalogs that exceed 3 million product SKUs. Einstein Product Recommendations enable you to create and manage recommenders and assign strategies that predict the most relevant products to promote to individual shoppers. **How**: If you have a product catalog that exceeds 3 million product SKUs, Commerce Cloud Einstein compiles a reduced list of 3 million product SKUs by default–no action required. To compile the list, Einstein uses sorting and filtering logic based on pre-defined criteria. Einstein recommendations are generated from this list. If your catalog exceeds 3 million product SKUs, and you want to ensure that products matching specific criteria appear in the reduced product list, contact Commerce Cloud Support. Having a large catalog and providing the right recommendations can be challenging. This change supports an even larger catalog, making it an excellent improvement. ### Renew eCDN Certificates in Business Manager [![A screenshot of the new eCDN screen in the 23.10 release of Salesforce B2C Commerce Cloud](/salesforce-b2c-commerce-cloud-23-10-release-a-comprehensive-overview/ecdn-renewable-certificates-ae09665c51_hu_9fc2d2edd00cc6b7.webp)](/salesforce-b2c-commerce-cloud-23-10-release-a-comprehensive-overview/ecdn-renewable-certificates-ae09665c51.png) > You can now use Business Manager to auto-renew up to five proxy zone eCDN certificates per realm. The new feature simplifies the annual renewal for eCDN certificates. If you use custom certificates, you can easily switch to auto-renewing certificates in the Business Manager UI. When you create a CDN zone, you can select to use eCDN Managed certificates. Is that [Let’s Encrypt](https://letsencrypt.org/) in the screenshot? This new feature will make life a lot easier! Forgetting to upload a certificate can have serious repercussions - so having this automated (for supported services) is a welcome change! ## OCAPI & SCAPI ### Updated infrastructure layers and routing > Updated infrastructure layers and routing rules for SCAPI requests to use fewer hops in the network. Recently, there has been some “architectural refactoring” which involved removing and changing some components. Unfortunately, there isn’t much information available about this. However, this is happening on the v1 of the APIS and it doesn’t require any action from the customers’ end. But if you notice any new bugs or peculiarities - report them! ### Custom Query Parameters in SCAPI > Introduction of new custom query parameters: `c_[yourparameter]` can now be defined on SCAPI requests and is routed end to end. Parameters are available in hooks for custom control logic. A highly requested feature to expand the possibilities of custom hooks has been added, providing greater flexibility and supporting more use cases in headless. ### Update Main Product Variants for a Bundled Line Item > You can now update a main product variant in a bundled line item. This change allows shoppers to select a main product variant when adding a bundled line item to a cart. For example, a product bundle contains a belt and a T-shirt. The T-shirt is a main product with red, blue, and green variations. When the shopper adds the product bundle to a basket, the belt and T-shirt are added as bundled items, and the shopper can select a T-shirt color, one of the T-shirt variants. Previously, the API didn’t support selecting a main product variant when a main product was included in a line item bundle. You can update these properties using (PATCH /baskets/\[basketId\]/items/\[itemId\]) . > > - productId > - isGift > - giftMessage > - Custom properties The support for headless scenarios is essential as the Composable Storefront gains more prominence in customer projects. Therefore, it is a great addition. However, it is unclear whether this support is for the OCAPI, the SCAPI, or both. Since the SCAPI has a different release log, it is suspected that the support is for the OCAPI, which flows through to the SCAPI as it is a layer on top of the OCAPI. Does someone care to experiment and let me know? ## Account Manager ### Email Notification of Changes to Inactive User Settings > As part of the Auto Disable Inactive Users feature, an email notification is sent to users when the Inactive User settings are activated or deactivated. An email is also sent when the Days Before Deletion settings are changed on the organization detail page. The email is sent to the email address entered in the Contact Users field on the organization detail page. There isn’t much to say about this feature, but it’s important for users to be aware of its automatic nature. ### Enable Read Only Account Manager Access > The Read Only Account Administrator role is now available in Account Manager. The role provides users read-only access to view details about their organization, API clients, and users. The role doesn’t include permissions to make updates. The new role is useful for auditors who want to confirm compliance with their company policies. High-privilege roles such as Account Administrator or API Administrator override the new role. A new feature in the Account Manager allows viewing of critical configuration without editing access. A great new addition to the roles in my opinion! ## PWA Kit v3.1.1 - [GitHub](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.1.1) This minor release is packed with enhancements and bug fixes to help you build better commerce experiences. **@salesforce/commerce-sdk-react@1.0.2** - Updated commerce-sdk-isomorphic to v1.10.4 for improved performance and stability. - Streamlined the development process by moving typedoc-related dependencies to dev dependencies (Issue #1425). **@salesforce/retail-react-app@2.0.0** - Fixed a critical issue with the Checkout Card Number in V3 (Issue #1424). - Cleaned up incorrect import paths for the page-designer component (Issue #1441). - Modularized the country code source for targeting via extensibility (Issue #1445). - Exported an icon helper function for targeting via overrides (Issue #1420). - Migrated Page Designer core types to commerce-sdk-react (Issue #1441). **@salesforce/pwa-kit-dev@3.1.1** - Resolved a performance issue caused by webpack stats in V3 (Issue #1391). --- ## Dreamforce 2023 Recap with the CommerceCrew Canonical URL: https://rhino-inquisitor.com/chasing-clouds-catching-up-with-the-commercecrew-at-dreamforce-2023/ Markdown URL: https://rhino-inquisitor.com/chasing-clouds-catching-up-with-the-commercecrew-at-dreamforce-2023/index.md Content type: article Published: 2023-09-25T10:29:00Z Updated: 2023-09-25T11:43:07Z Summary: For those of you who have been wondering about my whereabouts some time ago, I enjoyed this massive gathering in San Francisco. Categories: Community Tags: dreamforce, sfcc ## Key Takeaways - Recaps the key community moments, meetups, and interviews from Dreamforce 2023 - Highlights how AI dominated the event narrative across sessions and conversations - Notes the trade-off between strong community energy and limited standalone B2C innovation For those of you who have been wondering about my whereabouts some time ago, I enjoyed this massive gathering in San Francisco. It is always invigorating to be part of the Dreamforce experience! This time around, I am recounting my journey of attending in 2023. Dreamforce never fails to impress - but truthfully, I believe 2023’s edition went above and beyond! Although the start of my journey could have gone a tad better… ## Starting Dreamforce with a Flight Fiasco ![A group of people enjoying a coffee at Brussels Airport, just before leaving to Dreamforce](/chasing-clouds-catching-up-with-the-commercecrew-at-dreamforce-2023/09309824-40a7-4126-9473-fb00fb2fa185-1-105-c-56dbfbf8ca_hu_1ba69d51dd3ec1de.webp) The trip started the same way many conference weeks do: coffee, travel, and catching up. Our journey began Monday morning on a slightly chaotic note. We missed our initial flight due to our connecting one getting delayed - something that swiftly transformed all relaxed nerves into jittery ones. However, it proved to be a minor hiccup. Before we knew it, we were put on the next flight out and made our touchdown by 8 PM. Because of this, we missed a lot of welcome receptions, but it could have been worse. The adventurous start did nothing to deter our enthusiasm – instead, it added an adrenaline surge that prepped us more than anything else could have! ## A Welcoming Tuesday ![Three people smiling on a picture at a breakfast meeting in San Francisco including Thomas Theunen and Amalia Murray.](/chasing-clouds-catching-up-with-the-commercecrew-at-dreamforce-2023/04cd6b21-12ba-4307-9ce5-3a60768e6ba0-1-105-c-c78a87bbb3_hu_965e79573d00a47c.webp) Tuesday began with an early #CommerceCrew breakfast before the Dreamforce rush fully started. We kicked off day two (and the first day of Dreamforce) with gusto; the early bird catches the worm indeed! Tuesday commenced with breakfast with the #CommerceCrew (a big thank you being in order for Amalia!). The keynote right after gave an opportunity to reveal a new [Shirtforce](/commerce-cloud-t-shirts-on-shirtforce/) t-shirt, specially designed for [Charlie](https://twitter.com/charlieisaacs) to celebrate his relentless efforts within Salesforce’s ever-evolving community ecosystem. ![A group of people all wearing a 'Charlie's Sailblazer' t-shirt at the Dreamforce 2023 keynote.](/chasing-clouds-catching-up-with-the-commercecrew-at-dreamforce-2023/7a6c01d9-e903-4479-ad6e-fb8b41445d64-1-105-c-90a3bbafe3_hu_a825000f2c8323cb.webp) The keynote also became the moment to unveil Charlie's special Shirtforce t-shirt. No time for food comas here; post-lunch called for participation on my behalf in a session revolving around AI and its ethical impact. Explorer at heart, I reveled delving deep into generative AI - indeed quite an informative afternoon. ## Wednesday: Swags and Rock n Roll! ![Thomas Theunen sitting in between studio lights with a camera pointed at him. Multiple screens show his face.](/chasing-clouds-catching-up-with-the-commercecrew-at-dreamforce-2023/372a213b-a01b-47e2-9157-022c8d8baa65-1-105-c-89c973c920_hu_bbcd5630b3bea8bf.webp) Midweek included studio time, interviews, and the kind of event chaos that makes Dreamforce memorable. The arrival of Wednesday brought with it a flurry of excitement and anticipation as I prepared for several interview opportunities. As the day progressed, I sat in front of numerous camera lenses. Despite the pressure, I felt invigorated as I answered intriguing questions about the fascinating world of AI, the effect of Salesforce events and community, and how they positively impact my businesses and day-to-day activities. The day wasn’t just about putting on a serious face, as it also entailed my eagerly anticipated SWAG hunt! Fun fact: A hunt for cool goodies is an incredible icebreaker among participants. Just as we thought the day couldn’t get any better, Dreamfest kicked off with an epic concert by none other than the Foo Fighters! Trust me; it was nothing short of a fantastic evening in San Francisco. Talk about going out with a bang! We went on an epic quest to find the mystical entrance to the ground floor, but alas, it remained shrouded in mystery. After much fruitless searching and getting rejected at every turn, we realised that perhaps we were not the chosen (e.g. not a customer) ones destined to enter. Maybe we just needed better directions. Or did I just have to flaunt my [Golden Hoodie](/events-and-the-golden-hoodie/)? ![A picture of the concert of the Foo Fighters at Dreamfest 2023, taken high above the stage.](/chasing-clouds-catching-up-with-the-commercecrew-at-dreamforce-2023/1832c203-32d4-4a5b-922a-218cf2ecf468-1-102-a-d53635718f_hu_8338ecce29a74173.webp) Dreamfest capped the day with the Foo Fighters and the usual scramble for a good view. ## Thursdays Meant for Mingling ![The Unofficial SFCC slack admins below a tree at Dreamforce in dim blue lighting.](/chasing-clouds-catching-up-with-the-commercecrew-at-dreamforce-2023/a8d30ee3-509b-4c90-8901-5689d3a08b38-1-102-o-949f4d4034_hu_2f1c216c3bea146c.webp) By Thursday, the best part was simply reconnecting with the people behind the community. Thursday was comparatively calmer but every bit exciting in its unique way. It began with an [insightful meetup of CommerceCrew](https://youtu.be/qtqLrpH8Zm4) which followed the spirit of community building and offered people a rare chance to come together amidst the bustling event. The rest of the day shadowed opportunities to connect and exchange ideas among peers culminating in an intimate discussion revolving around AI in a cozy setup - the perfect unwinding activity after three days of intense power walking. ## In closing… As someone privileged to attend Dreamforce’23, I was amazed by the remarkable presence of generative AI in various sessions and keynotes. However, I couldn’t help but feel a little disappointed that there weren’t more B2C Commerce Cloud innovations that didn’t require other products in the Salesforce range. While I understand the reasoning behind this, not every customer wants to invest in other products. Nonetheless, it was a time to celebrate community spirit and foster relationships while embracing AI’s power. After an intense journey of knowledge exchange, I now sign off with mixed feelings, eagerly anticipating the next remarkable ride at Dreamforce. See you there? --- ## Helpful Salesforce B2C Commerce Cloud CLI tools Canonical URL: https://rhino-inquisitor.com/helpful-salesforce-b2c-commerce-cloud-cli-tools/ Markdown URL: https://rhino-inquisitor.com/helpful-salesforce-b2c-commerce-cloud-cli-tools/index.md Content type: article Published: 2023-09-11T17:19:00Z Updated: 2023-09-18T12:33:59Z Summary: In this article we will be looking at some helpful CLI tools to make our lives in Salesforce B2C Commerce a little bit easier. Categories: Salesforce Commerce Cloud, Technical Tags: cli, sfcc, technical ## Key Takeaways - Introduces useful SFCC CLI tools for sandbox management, migrations, and catalog reduction - Explains where sfcc-ci and b2c-tools fit into daily development and automation workflows - Highlights complementary community tooling that can speed up sandbox and catalog preparation Although Salesforce B2C Commerce Cloud is a ‘niche’ developer space, there is no shortage of [open-source solutions](/community-repositories/) available to make our lives a little bit easier. In this article, we will list a few of these and provide information on their uses. ## sfcc-ci - [GitHub Repository Link](https://github.com/SalesforceCommerceCloud/sfcc-ci) People who have been working with Salesforce B2C Commerce Cloud as a developer or in a similar technical role will have come into contact with this project. This tool provides you with a [CLI](https://en.wikipedia.org/wiki/Command-line_interface) (Command Line Interface) and a library to use within your projects to connect to a Salesforce B2C Commerce environment. It provides you with some handy commands that we will go over in more detail. ### Sandbox Management You will most likely know SFCC-CI for its [Sandbox management capabilities](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/sandboxes/b2c_developer_sandboxes.html). It provides commands to create, delete, start, stop, and many more. This project paves the way for setting up Continuous Integration and Continuous Deployment. You could potentially set this up to create a sandbox for automated testing that would destroy the instance at the end. ### Site Import/Export & Jobs The second set of commands allows you to manage your [Site Import & Exports](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/import_export/b2c_site_import_export.html). ### SLAS One of the more recent additions is a complete set of commands to manage SLAS (Shopper Login And API Access Service.) [This set of Headless APIs](https://developer.commercecloud.com/s/api-details/a003k00000VWfNDAA1/commerce-cloud-developer-centershopperloginandapiaccessservice?tabset-888ee=2) is not the easiest to set up, and SFCC-CI has made a set of commands available to help set this up (and possibly even automate once you get a feel for how it works.) ### Many more and growing There are still more commands available, but I will not review them all. ## b2c-tools ![B2C Tools CLI graphic illustrating migration support between environments.](/helpful-salesforce-b2c-commerce-cloud-cli-tools/b2c-tools-ff2c3df29f.svg) - [GitHub Repository Link](https://github.com/SalesforceCommerceCloud/b2c-tools) A relatively new repository (January 2022) made its way into GitHub. It is a CLI & Library project meant to be complementary to SFCC-CI. B2C Tools mainly focus on allowing you to script import/export tasks and migration between environments. ## Catalog Reducer - [GitHub Repository Link](https://github.com/SalesforceCommerceCloud/catalog-reducer) A super-fast sandbox and an extensive product catalog are usually not two things you hear together in a single sentence. When working on a project as a developer, you like to have a representative environment to reproduce issues that arise [in the Primary Instance Group](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/getting_started/b2c_demandware_instances.html). However, getting a good amount of products from production to a sandbox is not easy. The “Catalog Reducer” project gives you a CLI to convert an extensive catalog to a smaller one containing only what you want/need. Using a JSON configuration file, you determine how many masters, variants, and products with a particular attribute should be included in a filtered file. And since this is a CLI, you can combine this with sfcc-ci or b2c-tools to create an automated process to update sandboxes! I’m starting to see a common thread here! **Note:** This particular library does not handle huge files well. It loads the entire source XML into memory, which will cause Out-Of-Memory exceptions rather quickly. ## SFCC Catalog Pricebook - [GitHub Repository Link](https://github.com/redvanworkshop/sfcc-catalog-pricebook) If you have already looked around GitHub for Salesforce B2C Commerce Cloud cartridges and tools, you will probably have run into [Red Van Workshop](https://redvanworkshop.com/). They have released quite a few handy cartridges and tools, so be sure to check out [their organization](https://github.com/redvanworkshop/) on GitHub. This CLI tool is complimentary to “Catalog Reducer.” It takes in a Product Catalog and pushes out a Price Book based on your configuration (randomized prices based on rules). ## And many others These are only a few examples of tools you will find from the Salesforce B2C Commerce Cloud community. Have one that you think needs some love? Feel free to leave send me a slack message! --- ## Where to Start with SFCC Development Canonical URL: https://rhino-inquisitor.com/where-to-start-when-you-are-new-to-salesforce-b2c-commerce-cloud-development/ Markdown URL: https://rhino-inquisitor.com/where-to-start-when-you-are-new-to-salesforce-b2c-commerce-cloud-development/index.md Content type: article Published: 2023-09-04T13:57:05Z Updated: 2023-09-05T12:19:54Z Summary: Getting started with Salesforce B2C Commerce Cloud development can be confusing and daunting. Where do you start? Find out here! Categories: Salesforce Commerce Cloud, Technical Tags: ohana, sfcc, technical ## Key Takeaways - Gives newcomers a practical starting path for learning Salesforce B2C Commerce Cloud development without getting overwhelmed - Highlights the importance of understanding the platform first, getting access to a sandbox, and using the right learning resources - Points new developers toward the broader Commerce Cloud community as a key support channel while they learn Welcome to the exciting world of Salesforce B2C Commerce Cloud Development! If you’re new to the game, don’t worry - we’ve all been there. But let’s be honest: Salesforce B2C Commerce Cloud can initially be overwhelming. With so many features and capabilities, it can be hard to know where to begin. But don’t let that discourage you! Think of it like a puzzle - each piece is essential, but you must start somewhere. And that’s what we’re here for - to help you figure out where to start. So, get ready to roll up your sleeves and dive in! The path may be challenging, but trust us, the end result will be worth it. Plus, it’s a great conversation starter at parties (just kidding…, or are we?). So, let’s get started and make some eCommerce magic happen! ## Get to know the platform ![A private investigator looking through books, reading about Salesforce Commerce Cloud development](/where-to-start-when-you-are-new-to-salesforce-b2c-commerce-cloud-development/wading-through-the-sfcc-documentation-20db11f9d3_hu_ab3952c1d186a377.webp) Alright, before you dive into the fun stuff (coding, building, and creating), it’s important to first get to know the Salesforce B2C Commerce Cloud platform like the back of your hand. Think of it like a blind date - you wouldn’t want to show up unprepared, would you? Knowing what’s available out of the box is just as important as knowing how to build custom features. So, take the time to [get to know the platform](/sitegenesis-vs-sfra-vs-pwa/), and you’ll be ready to tackle any eCommerce challenge that comes your way. And what better way than to use the [public documentation](/where-is-the-new-sfcc-documentation/). Mastering the art of navigating through it is a skill of its own! Another starting point can be [this introductory blog post](https://osapishchuk.medium.com/how-to-understand-salesforce-commerce-cloud-78d71f1016de). ## Get yourself a sandbox Before diving headfirst into the Salesforce B2C Commerce Cloud development world, there’s one essential tool you need to have in your arsenal - a Sandbox. It’s like a secret weapon for developers, allowing you to test and experiment with new ideas, configurations, and even mistakes without real-world consequences. A Sandbox is essentially a mini version of your production environment, where you can try out different features, configurations, and customisations without affecting the live site. It’s a safe space for developers where you can test and iterate on your ideas (or development of project tickets) without any risk of disrupting the customer experience. So, before you start coding away, set up your Sandbox and experiment with confidence. _**A word of warning**: If you are not part of a partner or customer company, getting one can be challenging._ [Find out here how to get your hands on one!](/how-to-get-a-salesforce-b2c-commerce-cloud-sandbox/) ## Get started ![A diver looking at code below the water. The code is illegible, but represents diving into SFCC development.](/where-to-start-when-you-are-new-to-salesforce-b2c-commerce-cloud-development/diving-into-sfcc-development-4a0ef8622e_hu_3ecc29e2b64ff8ca.webp) Now that you’ve got your Sandbox set up, it’s time to dive into the fun part: coding! Depending on your situation and experience, the journey to becoming a Salesforce B2C Commerce Cloud pro may vary. But don’t worry; plenty of resources are available to help you along the way. For starters, the [Salesforce Partner Learning Camp](https://partnerlearningcamp.salesforce.com/s/learner-dashboard) offers a variety of courses to help developers master the platform. And if you’re not a partner, don’t fret - plenty of [documentation and resources](/salesforce-b2c-commerce-cloud-documentation/) are still available to help you learn the ropes. If you’re looking for a comprehensive guide that covers all the essential topics for SFCC development, I highly recommend checking out the [Certification Guide](/preparing-for-the-b2c-commerce-developer-certification/) I put together. It’s like a roadmap for your journey to becoming a Salesforce B2C Commerce Cloud master! Ok Ok… I might be tooting my own horn a bit here. ## You are not alone [![Graphic promoting the unofficial SFCC Slack community.](/where-to-start-when-you-are-new-to-salesforce-b2c-commerce-cloud-development/sfcc-unofficial-slack-c73cdc0350_hu_d57ef963f55c49a8.webp)](https://unofficialsfcc.com/) One of the best things about the Salesforce ecosystem is the #Ohana, a community of users, developers, architects, and enthusiasts passionate about helping each other succeed. And in the Commerce Cloud space, we’ve got the “Commerce Crew” - a group of fellow Commerce Adventurers willing to support each other and share knowledge. If you ever feel lost or stuck on your journey to becoming a Salesforce B2C Commerce Cloud pro, don’t hesitate to contact the Commerce Crew. They’re always happy to answer questions, provide guidance, and lend a helping hand. The community is an excellent resource for developers of all skill levels, and you will find passionate people about the same things as you. And if you’re looking for a friendly and supportive community, look no further than the Commerce Crew! So, don’t hesitate to join the crew and start getting help and help others today at [https://unofficialsfcc.com/](https://unofficialsfcc.com/) --- ## SFCC 23.9 Release Highlights and SCAPI Updates Canonical URL: https://rhino-inquisitor.com/a-look-at-the-23-9-commerce-cloud-release/ Markdown URL: https://rhino-inquisitor.com/a-look-at-the-23-9-commerce-cloud-release/index.md Content type: article Published: 2023-08-28T07:35:34Z Updated: 2023-08-28T07:35:45Z Summary: We are getting closer to the holiday period, and also one of the last releases of the year! This time we look at the September 2023 (23.9) release! Categories: Release Notes, Salesforce Commerce Cloud ## Key Takeaways - Explains why custom SCAPI endpoints are the headline feature in 23.9 - Highlights platform changes affecting search, profiling, and shopper identity - Calls out temporary SLAS token behavior and roadmap timing to plan around We are getting closer to the holiday period, and also one of the last releases of the year! This time we look at the [September 2023 (23.9) release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_23_9_release.htm&type=5)! Are you interested in last month’s release notes? Read the [23.8 release overview](/what-is-new-in-the-23-8-commerce-cloud-release/). ## Custom SCAPI endpoints in 23.9 This update is truly a game-changer for Commerce Cloud customers! With the introduction of custom endpoints, we can fully customise Headless use cases, allowing for even more flexibility and control. AND without [using a workaround](/creating-custom-ocapi-endpoints/)! Previously, [hooks](/how-to-use-ocapi-scapi-hooks/) were the only way (through tweaking existing endpoints). But now, the possibilities are endless! And the best part? An open beta is available before the update freeze, so we can start exploring and testing this new feature immediately. ### Development ![Custom endpoint file structure with mapping, script, and schema artifacts.](/a-look-at-the-23-9-commerce-cloud-release/sfcc-custom-endpoints-138d76b101_hu_577a1832a4333227.webp) Custom SCAPI endpoints follow the same file-based convention as hooks—a mapping file, a script file, and a service schema—plus built-in versioning support for backwards compatibility. The development of custom endpoints will look a lot similar to how we build hooks: - A mapping file (like hooks.json) - A script file (Development is similar to controllers and hooks) - A service schema file (The contract) Another big thing to mention is that, if you look carefully at the screenshot, you can easily version your services for backwards compatibility! ### Roadmap (Forward Looking Statement) V1 BETA - September 2023 (23.9) The ability to create custom **GET** endpoints is released together with the documentation. V1 GA - January 2024 (24.1) The feature is officially released and recommended by Salesforce to be used in Production use cases (long story short, wait until the holiday period is over before releasing your production use cases). V2 GA - March 2024 (24.3) or a later release Support is added for PUT, PATCH, POST and DELETE functions to support any headless use case. Besides supporting more methods, some other features will be added: - Caching - Script API helper functions - Code generation for artefacts - AM OAuth - [TSOB](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-login?meta=getTrustedSystemAccessToken) & [TAOB](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-trusted-agent.html) ### Paving the way for a Headless future From a Headless perspective, Salesforce Commerce Cloud had much to catch up on compared to other platforms (which shall not be named 😎). But this area is rapidly evolving, and it was a necessary one. As customers interact with many different channels than just the storefront, other channels need to have a way of interacting with the platform - and usually that is through an API! Giving developers and customers the freedom to customise is powerful. It also simplifies third-party integrations with Composable Storefront, and I expect more movement to happen in that area after this release! As a bystander, it is noticeable that all “the rest” is not getting much attention, looking at the release notes of the past two months. But, understandably, decisions of priority have to be made. ## Platform ### Improve Product Search Result in Japanese > You can now enable a new language analyzer for Japanese locales in B2C Commerce. The new analyzer supports advanced methods for search query tokenization. This enhancement provides more relevant search results for product searches in the Japanese language. It also reduces the merchandising effort to optimize storefront search for Japanese locales. For example, setting up additional synonyms and search dictionary entries. **How:** To enable the new analyzer, in Business Manager, select site | Merchant Tools | Search | Search Indexes | Language Options. Select Japanese-Improved as the language analyzer for Japanese locales. An index rebuild is NOT required after this update. To change the analyzer setting requires the permission to update a Business Manager Search Indexes module ![Language Options menu showing the Japanese Improved analyzer.](/a-look-at-the-23-9-commerce-cloud-release/sfcc-japanese-improved-search-fb4e7c018a_hu_854880f5ddfebf6d.webp) The Japanese-Improved analyzer reduces tokenization problems without requiring an index rebuild. A new and exciting addition for Japanese customers. It is important to find the right product to ensure good conversion rates and improve customer experience. ## Business Manager ### Improve Code Profiler Tracking > The Code Profiler Script API calls (shown as SCRIPT\_API) are no longer measured when using Production Mode. This change improves code profiler tracking without causing performance issues. ![Code Profiler output from before the 23.9 Production Mode change.](/a-look-at-the-23-9-commerce-cloud-release/sfcc-script-profile-productionmode-before-23-9-35fed622ef_hu_35e9c5a4b898d6fd.webp) The 23.9 profiler fix removes Production Mode overhead from SCRIPT\_API measurement. Having “Production Mode” with less impact on performance will positively affect the TTFB (Time To First Byte), though it is not stated anywhere how much this will affect the storefront percentage-wise. You can still access this information in other modes within 23.9, which are more useful for performance debugging. ## OCAPI & SCAPI ### Custom Shopper Login IDPs (SLAS) > - Default IDP configuration allows for SSO/OIDC configuration with other IDPs outside the list of SLAS supported IDPs. Configuration can be performed via the Admin API or Admin UI. For more information, see Configure a Default IDP. > - Preferred IDP configuration cleanup and functionality added to Admin UI. This is a massive update to IDP support in SLAS and a very welcome one. Before, we were limited to integrating with IDPs [officially supported](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-identity-providers.html) by SLAS, [but now it is possible to bring your own](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-default-idp.html)! ### Shopper Login (SLAS) > - Addressed a limitation in plugin\_slas integration with SLAS around Merge Cart for Guest to Registered flow. > - For the getSessionBridgeAccessToken endpoint, the returned TokenResponse now correctly includes the enc\_user\_ id attribute. > - As part of our efforts to scale the SLAS service for temporary holiday volume, registered shopper refresh tokens (new and existing) are valid for only 45 days beginning the week of August 7. This applies to shopping apps integrated with SLAS, and to shoppers who have not returned to the shopping app at least one time in the last 45 days. This temporary state ends on September 15. After September 15, registered shopper login tokens resume their full 90-day standard duration. Ideally, customers should be Shopper Guest sessions, and B2C Commerce basket retention is not affected in any way. The **SLAS sessions will be limited to 45 days until September 15th**, which was also mentioned in last month’s release notes - and a very important one to take note of. ## PWA Kit Nightly Builds If you want to know what is cooking, check out the nightly builds that are now available! [https://github.com/salesforceCommerceCloud/pwa-kit#%EF%B8%8F-nightly-builds](https://github.com/salesforceCommerceCloud/pwa-kit#%EF%B8%8F-nightly-builds) ## Updated Cartridges & Tools ### b2c-crm-sync (v3.0.3) - [https://github.com/SalesforceCommerceCloud/b2c-crm-sync](https://github.com/SalesforceCommerceCloud/b2c-crm-sync) > Salesforce B2C Commerce / CRM Sync is an enablement solution designed by Salesforce Architects to teach Salesforce’s B2C Customer Data Strategy for multi-cloud use-cases. The solution demonstrates a contemporary approach to the integration between Salesforce B2C Commerce and the Cloud products running on the Salesforce Customer 360 Platform. - Rename lib/\_common/request/\_ createOCAPIAUthRequestDef.js by [@jbachelet](https://github.com/jbachelet) in [#235](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/235) - Fix/173 by [@jbachelet](https://github.com/jbachelet) in [#237](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/237) - Change b2ccrm\_syncResponseText from set-of-string to JSON to reduce the performance impact on high-scale brands by [@jbachelet](https://github.com/jbachelet) in [#251](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/251) - Bump word-wrap from 1.2.3 to 1.2.4 by [@dependabot](https://github.com/dependabot) in [#250](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/250) ### sfra-webpack-builder (v3.4.5) - [https://github.com/SalesforceCommerceCloud/sfra-webpack-builder](https://github.com/SalesforceCommerceCloud/sfra-webpack-builder) > Webpack can be cumbersome to setup, especially in multicartridge projects for SFRA. This plugin let you bundle all your js, scss and jsx files out of the box. - configure release it bumber ([becbeab](https://github.com/SalesforceCommerceCloud/sfra-webpack-builder/commit/becbeabc3c1757daf6b4b11b7e2964874cbe389b)) - chore: init release it ([7816af8](https://github.com/SalesforceCommerceCloud/sfra-webpack-builder/commit/7816af8aca32340aa6e769d37373525a108acb45)) - Fix: Deprecate node-sass in favor of sass (dart) Upgrade dependencies Fixes [#96](https://github.com/SalesforceCommerceCloud/sfra-webpack-builder/issues/96) ([58de1a0](https://github.com/SalesforceCommerceCloud/sfra-webpack-builder/commit/58de1a08b600c260cea6f186c4f35d5c5f714c18)) - Merge pull request [#95](https://github.com/SalesforceCommerceCloud/sfra-webpack-builder/pull/95) from SalesforceCommerceCloud/main ([9c4a8f5](https://github.com/SalesforceCommerceCloud/sfra-webpack-builder/commit/9c4a8f5ad2e0e7257a771deef65904c83c5c915e)) --- ## Salesforce B2C Commerce Cloud Governance and Quotas Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-governance-and-quotas/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-governance-and-quotas/index.md Content type: article Published: 2023-08-21T06:58:00Z Updated: 2024-01-08T18:17:38Z Summary: Salesforce Platform Limits and Quotas are not new and exist for a reason. But why? And are there limits that are not documented? Categories: Salesforce Commerce Cloud, Technical Tags: quota, sfcc, technical ## Key Takeaways - Explains what SFCC quotas are, why they exist, and how they compare to broader SaaS platform governor limits - Shows where documented quotas live, how enforced limits surface, and why monitoring them matters in production - Highlights practical quota-related pitfalls such as request limits, response size, disk space, and garbage-collection pressure One of the things that developers (not all) love about a SaaS platform is that all of the server management and setup is taken out of their hands by the vendor - in our case, this is Salesforce. The downside to this setup is that we have less control over this setup - and the other way around, Salesforce can not control what custom code we throw at the platform… or can they? By introducing a system called “Quotas”, there is a way! But what is this? Are they documented? Can we work around them? Let us have a look and answer these questions! ## Similar to the core platform Those who have joined from the force.com platform can compare these so-called “Quotas” to the “[Salesforce Governor Limits](https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_apexgov.htm).” You will run into this system with many SaaS solutions, but each one will have a different term or name for them. ## What are they You can view them as restrictions on data volume and API usage set by the platform. They come in many forms and are placed on [different levels within the Salesforce B2C Commerce Cloud’s stack](/the-salesforce-b2c-commerce-cloud-environment/). A basic example of a limit would be the maximum time a single request is allowed to take or how many elements you can put in an [Array](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/index.html?target=class_TopLevel_Array.html). ## Where are they documented Luckily a large percentage of these limits are documented and categorised per type: - [Object Quotas](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/quota/html/Object_Quotas.html) (Data Volume) - [API Quotas](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/quota/html/API_Quotas.html) (Code) More platform governance is in place, but some are not documented. Over the years, I have encountered several of these undocumented quotas. But don’t fret - I’m sharing them later in this article! ## What does “enforced” mean ![Quota Status screen showing an enforced quota in Business Manager.](/salesforce-b2c-commerce-cloud-governance-and-quotas/sfcc-enforced-quota-a495bb4270_hu_3004e97c313925b0.webp) Quota Status in Business Manager Enforced quotas will throw an unrecoverable exception if you hit them. Translation: **Someone sees an error page**! So if you hit an enforced quota on production, this needs to be resolved as soon as possible! But even if the quota is not enforced, you must investigate the code causing you to hit this limit. People might be experiencing lousy performance because of it and possibly abandoning their purchase (worst case). ### There is another Besides this screen, you will also find [logs](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-log-files-overview.html?q=log) on the WebDAV. And these can contain messages along these lines: ```text Quota api.queryObjects@JOB (internal, limit 0): limit exceeded 5 time(s) ``` Notice the word “**internal”.** These are unenforced quotas that Salesforce uses for statistical purposes (maybe it will become a quota in the future). So you can ignore them! ## But why ![Illustration reacting to the frustration of hitting a platform quota.](/salesforce-b2c-commerce-cloud-governance-and-quotas/but-why-91f791a77c_hu_a2016586ab4c0115.webp) Those who have run into these “limits” have probably already asked themselves this question. Why is this quota here? Why wasn’t it just one higher? Why do I have to work three days longer on this ticket because I ran into it? Well, there are a few good reasons for these to exist. ### Keep the platform efficient and stable The imposed “quotas” keep us, the user, from overloading the platform. These limitations concern: - Memory Usage (Don’t fill up the memory with too much data that the system needs to clean later) - Resource Consumption (Keep the CPU free to make sure people can buy without delay) - Business Object limits (Only store within SFCC what needs to be stored) If you dig deeper into these Quotas, you will find that they are pretty forgiving, and some will require a large enterprise customer to reach. And even then, there are solutions available! ### It keeps us from taking the easy way out Talking from experience, sometimes, as a developer, you want to take the easy route to save time. But in many cases, some decisions will work for low volumes of data but fail once you hit production-level amounts of transactions. These quota limits will inform you of this oversight (if you hit them). A good example would be the external API limit, which used to be at 8 - and is now 16. Is it a good idea to do 16 or more external API calls in a single request? If you need to do this many requests in the front end, consider revisiting the architecture. ### It compels us to consider performance and security Even though this will not solve all performance issues, some imposed quotas prevent you from doing insecure operations or writing code that will negatively impact performance. Examples of these are: - **api.dw.catalog.ProductInventoryRecord.update():** No front-end request can manipulate the inventory records, meaning that someone with bad intentions will never have a route to abuse. - **api.jsArraySize:** We can only store 20.000 items in a single array. This will keep us from filling up the memory and wasting resources filling up this array and reading from it in large volumes. - **api.dw.catalog.PriceBookMgr.assignPriceBookToSite(PriceBook, String):** This API is used only for management purposes and has no business in the storefront. This will force developers to find an alternative ([and better)](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_catalog_PriceBookMgr.html?resultof=%22%70%72%69%63%65%62%6f%6f%6b%6d%67%72%22%20#dw_catalog_PriceBookMgr_setApplicablePriceBooks_PriceBook_DetailAnchor) way to build the appropriate behaviour. Let me be clear: You can still easily write insecure and inadequate performant code without hitting any of the quotas. **_Always keep security and performance in mind when writing custom features!_** ## Monitoring Salesforce will not monitor your quota limitations but has provided enough tools to take care of it yourself. The Business Manager has a monitoring page, which will give you the total overview and allow you to subscribe to warnings. “Administration > Operations > Quota Status” ![Quota alert subscription settings in Business Manager.](/salesforce-b2c-commerce-cloud-governance-and-quotas/sfcc-quota-alerts-7f9e795d58_hu_9090ff660bbc434.webp) Subscribe It is highly recommended to subscribe with multiple people to these alerts. Remember to do this in various environments, not just Production! ## I hit a quota, and can’t work around it Don’t panic! You can always ask for support to temporarily (or permanently) relax a quota. But you better be fully prepared to defend your case and give a good reason why you deserve to have this relaxation. And if there is a long-term solution, plan it as soon as possible! ## Other documented and “Undocumented” quotas ### Response Size Limit Although you can build some pretty large pages, there is a limit: of 10MB, to be exact. It is not easy to run into, but if you work with files like PDF - you probably already know this one… If you look well in the documentation, you will find the information on [this page](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-dev-best-practices.html) under “Template Support”! This page has some other platform limitations documented too: - Emails are limited to 3MB - Video files are limited to 20MB - The default Script Timeout is 30 seconds But again, you need to look around to find this information as it is [scattered](/where-is-the-new-sfcc-documentation/) all over. ### Rate limit on Storefront Requests Suppose you have a script that causes many requests. For example, each product tile does an asynchronous call - you will start receiving errors from the system that you send too many requests. This is the error “**[429: Too Many Requests](https://support.cloudflare.com/hc/en-us/articles/115003014512-4xx-Client-Error#).”** ### Request Timeout I already mentioned this one above, but the default timeout of a request is 30 seconds. If you have written an infinite loop in the storefront, no worries! Salesforce will cut off the request after the script timeout. ### Shared Disk Space on ODS ODS disk space is also a [documented](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-developer-sandboxes.html) quota. But an important one to keep in mind! - **M:** 10 GB - **L:** 20 GB - **XL:** 50 GB In a lot of cases, this is enough. But you could get in trouble if you work with many images on your Sandboxes. ### Garbage Collection ![Duke mascot illustration used to introduce garbage collection.](/salesforce-b2c-commerce-cloud-governance-and-quotas/duke-cleaning-up-garbage-7e114dc018_hu_ba4e5158a98e1730.webp) An important thing to keep in mind is that Salesforce B2C Commerce Cloud runs on Java. And an essential part of Java is its [garbage collection](https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html) process. I have seen Garbage Collection having to do so much work that it brought down the storefront to a crawl, with CPU usage being maxed out for hours on end. To keep the “garbage” as empty as possible, there are a few things you can do a few things. (The best practices below are not just for garbage collection, they will also improve performance in general). #### Do not access objects unnecessarily Accessing or fetching objects and not doing anything will cause extra cleanup! Below is an example of things to keep in mind. ```js /** * An example of a function that does many things you should not do... */ function doUnnecessaryCalls() { var ProductMgr = require('dw/catalog/ProductMgr'); // Do we really need all products? var allMyProducts = ProductMgr.queryAllSiteProducts(); /** * We are going to be accessing all of the products in the catalog, which is a lot of data * that garbage collection is going to have to clean up! */ while (allMyProducts.hasNext()) { // Do not fetch the object again, you already had it in the SeekableIterator var product = ProductMgr.getProduct(allMyProducts.next().ID); // It would have been better to use the Search Index (if the attribute is indexed) if (product.custom.myAttr === true) { // Do something } } allMyProducts.close(); } ``` #### Good Cache Hit Ratio Improve cache hit ratio on lister and product detail pages (including content) to reduce server requests and cleanup. #### Location of your requires Do ‘requires’ inside the functions that use them, rather than declaring them globally - unless each function uses them. When a file is parsed/accessed, it will execute all of the global requires, which will also execute their global requires. This will continue until we reach the end of the chain. The shorter the chain, the better the performance and the less garbage collection. ```js /** * Logs forbidden access requests to Sentry. If a user is logged in, the customer number is logged. */ server.prepend('Forbidden', function (req, res, next) { if (req.currentCustomer.profile) { // Only do the require when necessary var Sentry = require('*/cartridge/scripts/Sentry'); var message = 'Forbidden access for customer ' + req.currentCustomer.profile.customerNo; Sentry.captureException(new Error(message)); } next(); }); ``` ### Maximum Images Per Folder [Rsync](https://en.wikipedia.org/wiki/Rsync) is used behind the scenes for file replication from Staging to Development or Production, and that information can help you find best practices around image management. One of them is limiting the number of files in a single folder. From a support ticket, I have received the limitation of around 100.000 files max in a folder. …but it makes sense to stay well below this amount. ### Static / Dynamic Mappings Static and dynamic mappings are managed in the business manager in a single multiline text field. The maximum data you can submit is around 2MB before it throws an exception of too much data being submitted. This is [documented](https://help.salesforce.com/s/articleView?language=en_US&id=cc.b2c_static_mappings.htm) here, and the workaround is to use the Site Import functionality. ### Parallel OCAPI Requests ![Slack note documenting the per-session OCAPI parallel-request limit.](/salesforce-b2c-commerce-cloud-governance-and-quotas/img-0054-72b5b079a0_hu_1e355f6b8c4e9a52.webp) Although there is no rate limit in place on the OCAPI, there is a limit on how many parallel requests one can make. --- ## Dates, Calendars, and Time Zones in SFCC Canonical URL: https://rhino-inquisitor.com/navigating-dates-calendars-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/navigating-dates-calendars-in-sfcc/index.md Content type: article Published: 2023-08-14T17:27:04Z Updated: 2023-08-15T07:44:20Z Summary: Learn how SFCC handles dates, calendars, and time zones so you can avoid subtle scheduling bugs and localization issues in production. Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, technical ## Key Takeaways - Explains the roles of JavaScript Date and dw.util.Calendar when handling time in SFCC - Shows how to work with instance and site time zones and retrieve those settings in code - Helps developers avoid subtle localization and scheduling bugs caused by timezone and API differences In today’s world, managing dates, calendars, and time zones is expected for any e-commerce platform. [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/) is no exception, and this article will explore the intricacies of working with dates and calendars in SFCC, focusing on the JavaScript Date object, the Java Calendar class. By understanding these concepts, you can ensure that your code works seamlessly across different regions and time zones. ## Date (JavaScript) The JavaScript Date object is a built-in object that represents and manipulates dates and times. It provides [a range of methods](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/upcoming/scriptapi/html/index.html?target=class_TopLevel_Date.html) for parsing, formatting, and performing calculations with dates and times. The Date object can be instantiated with or without arguments, representing either a specific date and time or the current date and time by default. Example 1: Creating a Date object and displaying the current date and time ```js const currentDate = new Date(); console.log("Current date and time:", currentDate.toString()); ``` Example 2: Calculating the difference between two dates ```js const startDate = new Date("2023-01-01"); const endDate = new Date("2023-12-31"); const timeDifference = endDate - startDate; const daysDifference = timeDifference / (1000 * 60 * 60 * 24); console.log("Days between the two dates:", daysDifference); ``` ## Calendar (Rhino / Java) The [Rhino Engine](https://en.wikipedia.org/wiki/Rhino_%5c%28JavaScript_engine%5c%29) is a JavaScript runtime that allows Java classes to be used within JavaScript code, enabling developers to leverage Java’s powerful features in their scripts. One such Java class is the [Calendar](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/index.html?target=class_dw_util_Calendar.html), which provides advanced functionality for working with dates and times. The Calendar class offers methods for converting between different date and time representations. It also enables developers to work with timezones, a crucial aspect of managing dates and times globally. Different than Java Even though it has been exposed, some differences exist, such as how to instantiate a Calendar. e.g. “Calendar.getInstance()” in Java vs “new Calendar()” in the Rhino Engine. Example 1: Creating a Calendar instance and setting the date ```js var Calendar = require('dw/util/Calendar'); var calendarInstance = new Calendar() calendarInstance.set(2023, Calendar.JANUARY, 1); ``` Example 2: Adding days to a Calendar instance with a particular timezone and converting to a JavaScript Date object ```js var Calendar = require('dw/util/Calendar'); var calendarInstance = new Calendar(); calendarInstance.setTimeZone( "Etc/GMT+1" ); calendarInstance.add(Calendar.DATE, 10); var dateInstance = calendarInstance.getTime(); ``` But in this use case, “odd things” happen. Watch for the “pitfalls” section at the end of this article! ## Working with timezones In the previous section, we discussed how to work with time zones in the Calendar class. But there are multiple functions available to manipulate the zones, such as: 1. **Setting the timezone:** You can set the timezone for a Calendar instance using the [setTimeZone()](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_util_Calendar.html#dw_util_Calendar_setTimeZone_String_DetailAnchor) method, which accepts a TimeZone object as its argument. 2. **Getting the timezone:** To retrieve the timezone of a Calendar instance, use the [getTimeZone()](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_util_Calendar.html#dw_util_Calendar_getTimeZone_DetailAnchor) method, which returns a TimeZone object. 3. **Converting between timezones:** To convert a date and time between different timezones, you can create a new Calendar instance with the desired timezone and set its time using the [setTime()](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_util_Calendar.html#dw_util_Calendar_setTime_Date_DetailAnchor) method. ### Configuring timezones If you didn’t know already, it is possible to configure what time zone your instance uses and what time zone your sites are in. - [Setting your Instance Time Zone](https://help.salesforce.com/s/articleView?id=cc.b2c_instance_time_zone.htm&language=en_us&release=2.0.1&type=5) - [Setting your Site Time Zone](https://help.salesforce.com/s/articleView?id=cc.b2c_site_time_zone.htm&language=en_us&release=2.0.1&type=5) ### Getting the configured values Once you have these configured, you kind of hope that there is some way to access these settings in the code (not everything is available after all). Example 1: Getting the Instance Time Zone ```js var System = require('dw/system/System'); var instanceTimeZone = System.getInstanceTimeZone(); ``` - [Function Documentation](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_System.html#dw_system_System_getInstanceTimeZone_DetailAnchor) Example 2: Getting the Site Time Zone ```js var Site = require('dw/system/Site'); var siteTimeZone = Site.getCurrent().getTimezone(); // Get it as a Calendar with the timezone set. var siteTimeZoneCalendar = Site.getCalendar(); ``` - [Function Documentation](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_Site.html#dw_system_Site_getTimezone_DetailAnchor) ### List of zone IDs To get the list of supported zones, I executed some Java code: ```text import java.util.TimeZone; public class HelloWorld { public static void main(String []args) { String [] zones = TimeZone.getAvailableIDs(); for ( String zone : zones) { System.out.println(zone); } } } ``` Which results in this list: ```text Africa/Abidjan Africa/Accra Africa/Addis_Ababa Africa/Algiers Africa/Asmara Africa/Asmera Africa/Bamako Africa/Bangui Africa/Banjul Africa/Bissau Africa/Blantyre Africa/Brazzaville Africa/Bujumbura Africa/Cairo Africa/Casablanca Africa/Ceuta Africa/Conakry Africa/Dakar Africa/Dar_es_Salaam Africa/Djibouti Africa/Douala Africa/El_Aaiun Africa/Freetown Africa/Gaborone Africa/Harare Africa/Johannesburg Africa/Juba Africa/Kampala Africa/Khartoum Africa/Kigali Africa/Kinshasa Africa/Lagos Africa/Libreville Africa/Lome Africa/Luanda Africa/Lubumbashi Africa/Lusaka Africa/Malabo Africa/Maputo Africa/Maseru Africa/Mbabane Africa/Mogadishu Africa/Monrovia Africa/Nairobi Africa/Ndjamena Africa/Niamey Africa/Nouakchott Africa/Ouagadougou Africa/Porto-Novo Africa/Sao_Tome Africa/Timbuktu Africa/Tripoli Africa/Tunis Africa/Windhoek America/Adak America/Anchorage America/Anguilla America/Antigua America/Araguaina America/Argentina/Buenos_Aires America/Argentina/Catamarca America/Argentina/ComodRivadavia America/Argentina/Cordoba America/Argentina/Jujuy America/Argentina/La_Rioja America/Argentina/Mendoza America/Argentina/Rio_Gallegos America/Argentina/Salta America/Argentina/San_Juan America/Argentina/San_Luis America/Argentina/Tucuman America/Argentina/Ushuaia America/Aruba America/Asuncion America/Atikokan America/Atka America/Bahia America/Bahia_Banderas America/Barbados America/Belem America/Belize America/Blanc-Sablon America/Boa_Vista America/Bogota America/Boise America/Buenos_Aires America/Cambridge_Bay America/Campo_Grande America/Cancun America/Caracas America/Catamarca America/Cayenne America/Cayman America/Chicago America/Chihuahua America/Coral_Harbour America/Cordoba America/Costa_Rica America/Creston America/Cuiaba America/Curacao America/Danmarkshavn America/Dawson America/Dawson_Creek America/Denver America/Detroit America/Dominica America/Edmonton America/Eirunepe America/El_Salvador America/Ensenada America/Fort_Nelson America/Fort_Wayne America/Fortaleza America/Glace_Bay America/Godthab America/Goose_Bay America/Grand_Turk America/Grenada America/Guadeloupe America/Guatemala America/Guayaquil America/Guyana America/Halifax America/Havana America/Hermosillo America/Indiana/Indianapolis America/Indiana/Knox America/Indiana/Marengo America/Indiana/Petersburg America/Indiana/Tell_City America/Indiana/Vevay America/Indiana/Vincennes America/Indiana/Winamac America/Indianapolis America/Inuvik America/Iqaluit America/Jamaica America/Jujuy America/Juneau America/Kentucky/Louisville America/Kentucky/Monticello America/Knox_IN America/Kralendijk America/La_Paz America/Lima America/Los_Angeles America/Louisville America/Lower_Princes America/Maceio America/Managua America/Manaus America/Marigot America/Martinique America/Matamoros America/Mazatlan America/Mendoza America/Menominee America/Merida America/Metlakatla America/Mexico_City America/Miquelon America/Moncton America/Monterrey America/Montevideo America/Montreal America/Montserrat America/Nassau America/New_York America/Nipigon America/Nome America/Noronha America/North_Dakota/Beulah America/North_Dakota/Center America/North_Dakota/New_Salem America/Nuuk America/Ojinaga America/Panama America/Pangnirtung America/Paramaribo America/Phoenix America/Port-au-Prince America/Port_of_Spain America/Porto_Acre America/Porto_Velho America/Puerto_Rico America/Punta_Arenas America/Rainy_River America/Rankin_Inlet America/Recife America/Regina America/Resolute America/Rio_Branco America/Rosario America/Santa_Isabel America/Santarem America/Santiago America/Santo_Domingo America/Sao_Paulo America/Scoresbysund America/Shiprock America/Sitka America/St_Barthelemy America/St_Johns America/St_Kitts America/St_Lucia America/St_Thomas America/St_Vincent America/Swift_Current America/Tegucigalpa America/Thule America/Thunder_Bay America/Tijuana America/Toronto America/Tortola America/Vancouver America/Virgin America/Whitehorse America/Winnipeg America/Yakutat America/Yellowknife Antarctica/Casey Antarctica/Davis Antarctica/DumontDUrville Antarctica/Macquarie Antarctica/Mawson Antarctica/McMurdo Antarctica/Palmer Antarctica/Rothera Antarctica/South_Pole Antarctica/Syowa Antarctica/Troll Antarctica/Vostok Arctic/Longyearbyen Asia/Aden Asia/Almaty Asia/Amman Asia/Anadyr Asia/Aqtau Asia/Aqtobe Asia/Ashgabat Asia/Ashkhabad Asia/Atyrau Asia/Baghdad Asia/Bahrain Asia/Baku Asia/Bangkok Asia/Barnaul Asia/Beirut Asia/Bishkek Asia/Brunei Asia/Calcutta Asia/Chita Asia/Choibalsan Asia/Chongqing Asia/Chungking Asia/Colombo Asia/Dacca Asia/Damascus Asia/Dhaka Asia/Dili Asia/Dubai Asia/Dushanbe Asia/Famagusta Asia/Gaza Asia/Harbin Asia/Hebron Asia/Ho_Chi_Minh Asia/Hong_Kong Asia/Hovd Asia/Irkutsk Asia/Istanbul Asia/Jakarta Asia/Jayapura Asia/Jerusalem Asia/Kabul Asia/Kamchatka Asia/Karachi Asia/Kashgar Asia/Kathmandu Asia/Katmandu Asia/Khandyga Asia/Kolkata Asia/Krasnoyarsk Asia/Kuala_Lumpur Asia/Kuching Asia/Kuwait Asia/Macao Asia/Macau Asia/Magadan Asia/Makassar Asia/Manila Asia/Muscat Asia/Nicosia Asia/Novokuznetsk Asia/Novosibirsk Asia/Omsk Asia/Oral Asia/Phnom_Penh Asia/Pontianak Asia/Pyongyang Asia/Qatar Asia/Qostanay Asia/Qyzylorda Asia/Rangoon Asia/Riyadh Asia/Saigon Asia/Sakhalin Asia/Samarkand Asia/Seoul Asia/Shanghai Asia/Singapore Asia/Srednekolymsk Asia/Taipei Asia/Tashkent Asia/Tbilisi Asia/Tehran Asia/Tel_Aviv Asia/Thimbu Asia/Thimphu Asia/Tokyo Asia/Tomsk Asia/Ujung_Pandang Asia/Ulaanbaatar Asia/Ulan_Bator Asia/Urumqi Asia/Ust-Nera Asia/Vientiane Asia/Vladivostok Asia/Yakutsk Asia/Yangon Asia/Yekaterinburg Asia/Yerevan Atlantic/Azores Atlantic/Bermuda Atlantic/Canary Atlantic/Cape_Verde Atlantic/Faeroe Atlantic/Faroe Atlantic/Jan_Mayen Atlantic/Madeira Atlantic/Reykjavik Atlantic/South_Georgia Atlantic/St_Helena Atlantic/Stanley Australia/ACT Australia/Adelaide Australia/Brisbane Australia/Broken_Hill Australia/Canberra Australia/Currie Australia/Darwin Australia/Eucla Australia/Hobart Australia/LHI Australia/Lindeman Australia/Lord_Howe Australia/Melbourne Australia/NSW Australia/North Australia/Perth Australia/Queensland Australia/South Australia/Sydney Australia/Tasmania Australia/Victoria Australia/West Australia/Yancowinna Brazil/Acre Brazil/DeNoronha Brazil/East Brazil/West CET CST6CDT Canada/Atlantic Canada/Central Canada/Eastern Canada/Mountain Canada/Newfoundland Canada/Pacific Canada/Saskatchewan Canada/Yukon Chile/Continental Chile/EasterIsland Cuba EET EST5EDT Egypt Eire Etc/GMT Etc/GMT+0 Etc/GMT+1 Etc/GMT+10 Etc/GMT+11 Etc/GMT+12 Etc/GMT+2 Etc/GMT+3 Etc/GMT+4 Etc/GMT+5 Etc/GMT+6 Etc/GMT+7 Etc/GMT+8 Etc/GMT+9 Etc/GMT-0 Etc/GMT-1 Etc/GMT-10 Etc/GMT-11 Etc/GMT-12 Etc/GMT-13 Etc/GMT-14 Etc/GMT-2 Etc/GMT-3 Etc/GMT-4 Etc/GMT-5 Etc/GMT-6 Etc/GMT-7 Etc/GMT-8 Etc/GMT-9 Etc/GMT0 Etc/Greenwich Etc/UCT Etc/UTC Etc/Universal Etc/Zulu Europe/Amsterdam Europe/Andorra Europe/Astrakhan Europe/Athens Europe/Belfast Europe/Belgrade Europe/Berlin Europe/Bratislava Europe/Brussels Europe/Bucharest Europe/Budapest Europe/Busingen Europe/Chisinau Europe/Copenhagen Europe/Dublin Europe/Gibraltar Europe/Guernsey Europe/Helsinki Europe/Isle_of_Man Europe/Istanbul Europe/Jersey Europe/Kaliningrad Europe/Kiev Europe/Kirov Europe/Kyiv Europe/Lisbon Europe/Ljubljana Europe/London Europe/Luxembourg Europe/Madrid Europe/Malta Europe/Mariehamn Europe/Minsk Europe/Monaco Europe/Moscow Europe/Nicosia Europe/Oslo Europe/Paris Europe/Podgorica Europe/Prague Europe/Riga Europe/Rome Europe/Samara Europe/San_Marino Europe/Sarajevo Europe/Saratov Europe/Simferopol Europe/Skopje Europe/Sofia Europe/Stockholm Europe/Tallinn Europe/Tirane Europe/Tiraspol Europe/Ulyanovsk Europe/Uzhgorod Europe/Vaduz Europe/Vatican Europe/Vienna Europe/Vilnius Europe/Volgograd Europe/Warsaw Europe/Zagreb Europe/Zaporozhye Europe/Zurich GB GB-Eire GMT GMT0 Greenwich Hongkong Iceland Indian/Antananarivo Indian/Chagos Indian/Christmas Indian/Cocos Indian/Comoro Indian/Kerguelen Indian/Mahe Indian/Maldives Indian/Mauritius Indian/Mayotte Indian/Reunion Iran Israel Jamaica Japan Kwajalein Libya MET MST7MDT Mexico/BajaNorte Mexico/BajaSur Mexico/General NZ NZ-CHAT Navajo PRC PST8PDT Pacific/Apia Pacific/Auckland Pacific/Bougainville Pacific/Chatham Pacific/Chuuk Pacific/Easter Pacific/Efate Pacific/Enderbury Pacific/Fakaofo Pacific/Fiji Pacific/Funafuti Pacific/Galapagos Pacific/Gambier Pacific/Guadalcanal Pacific/Guam Pacific/Honolulu Pacific/Johnston Pacific/Kanton Pacific/Kiritimati Pacific/Kosrae Pacific/Kwajalein Pacific/Majuro Pacific/Marquesas Pacific/Midway Pacific/Nauru Pacific/Niue Pacific/Norfolk Pacific/Noumea Pacific/Pago_Pago Pacific/Palau Pacific/Pitcairn Pacific/Pohnpei Pacific/Ponape Pacific/Port_Moresby Pacific/Rarotonga Pacific/Saipan Pacific/Samoa Pacific/Tahiti Pacific/Tarawa Pacific/Tongatapu Pacific/Truk Pacific/Wake Pacific/Wallis Pacific/Yap Poland Portugal ROK Singapore SystemV/AST4 SystemV/AST4ADT SystemV/CST6 SystemV/CST6CDT SystemV/EST5 SystemV/EST5EDT SystemV/HST10 SystemV/MST7 SystemV/MST7MDT SystemV/PST8 SystemV/PST8PDT SystemV/YST9 SystemV/YST9YDT Turkey UCT US/Alaska US/Aleutian US/Arizona US/Central US/East-Indiana US/Eastern US/Hawaii US/Indiana-Starke US/Michigan US/Mountain US/Pacific US/Samoa UTC Universal W-SU WET Zulu EST HST MST ACT AET AGT ART AST BET BST CAT CNT CST CTT EAT ECT IET IST JST MIT NET NST PLT PNT PRT PST SST VST ``` ## Pitfalls ![A shadow in front of a gigantic clock, wondering about the intricacies of dates and times.](/navigating-dates-calendars-in-sfcc/a-shadow-in-front-of-a-clock-e925bae223_hu_af099b1e547a7d7c.webp) Date and time handling in SFCC has subtle pitfalls that trip up even experienced developers. As we all know, with development, we run into some unexpected results and requirements that require thorough investigation and thought. To help you on your way in this process, here is a list of some of the pitfalls to think about. ### Daylight Saving Time (DST / Summer Time) > Summertime, also known as Daylight Saving Time, is a system of uniformly advancing clocks to extend daylight hours during conventional waking time in the summer months. In countries in the Northern Hemisphere, clocks are usually set ahead one hour in late March or April and are set back one hour in late September or October. The primary purpose of Daylight Saving Time is to make better use of daylight. The practice of advancing clocks by one hour during warmer months so that darkness falls at a later clock time is known as Summer Time. This is fun and all, but that also means that some time zones change how many hours they are ahead or behind during this period! Which can be confusing and a source of many bugs! ### Conversion I put a warning up earlier, didn’t I, with the Calendar - Date conversion? Well, now is the time to explain myself! The first thing I would recommend to anyone is to read the documentation carefully because it contains a very clear warning! ![Documentation warning about Calendar constructor dates being interpreted in GMT.](/navigating-dates-calendars-in-sfcc/calendar-constructor-warning-83ef0dcd2b_hu_175e2687d03dd342.webp) The official docs warn explicitly: Calendar constructor dates are interpreted as GMT, not your configured timezone. ![Documentation warning that Calendar.toDate loses the configured time zone and returns GMT.](/navigating-dates-calendars-in-sfcc/calendar-to-date-warning-a652a2a931_hu_bc6bc4762b7adc80.webp) Calendar.toDate() silently discards your timezone setting and returns a GMT Date — a common source of timezone bugs. ### Caching It is crucial to remember that the Page Cache does not maintain individual caches for each Time Zone when presenting data. In certain situations, it may be necessary to rely on client-side JavaScript to accurately calculate data based on the current user’s Time Zone. ### Storefront Toolkit We mentioned the function to get the Calendar automatically in the Site timezone before: “[Site.getCalendar()](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_Site.html#dw_system_Site_getCalendar_DetailAnchor)”. To ensure your code incorporates the toolkit, it is necessary to utilise this function. To provide a more precise understanding, I have recorded a video demonstrating this behaviour: [Storefront Toolkit calendar demo recording](/navigating-dates-calendars-in-sfcc/storefront-tookit-and-calendars.mp4) ### Is there a third-party way Funny you should ask 😉, a few years ago, I asked myself the same question [and got the crazy idea of making well-known libraries compatible with the Rhino Engine](https://github.com/taurgis/salesforce-commerce-cloud-libraries). One of those libraries was [date-fns](https://date-fns.org/), a library with modular, efficient, and reliable date and time functionalities for projects. It promotes a function-per-file approach to avoid unnecessary bloat in projects. --- ## Should I get JavaScript Developer I certified? Canonical URL: https://rhino-inquisitor.com/should-i-get-javascript-developer-i-certified/ Markdown URL: https://rhino-inquisitor.com/should-i-get-javascript-developer-i-certified/index.md Content type: article Published: 2023-08-07T12:51:32Z Updated: 2023-08-07T12:53:11Z Summary: JavaScript is part of the day-to-day business in Salesforce B2C Commerce Cloud. But should you try to get the certification? Categories: Certification Tags: ohana, sfcc, trailhead ## Key Takeaways - Argues that JavaScript Developer I can be a worthwhile complement for SFCC developers who want stronger vanilla JavaScript fundamentals - Explains the trade-off that the certification path also requires exposure to the broader Salesforce core platform - Provides practical preparation resources for developers deciding whether to pursue the credential JavaScript is integral to Salesforce B2C Commerce Cloud development in both the back and front ends. And with the addition of the [Composable Storefront](/what-does-the-composable-storefront-mean-for-sfcc-developers/), your knowledge of the basics will help you continue your path within the B2C ecosystem as a developer. But no actual certification for SFCC that tests your knowledge of JavaScript. Or is there? Maybe the title was a bit of a giveaway 😅. ## Why should you get it Knowledge of vanilla JavaScript is essential. There are a lot of free courses for React, Angular, and Vue available, and you will be able to get your first JavaScript-based application/site up and running in no time. But if this is how you learned JavaScript, there are many “basics” that you might not be aware of. And knowing those basics is what lets you understand why things React (pun intended) the way they do in these libraries. The [JavaScript Developer I](https://trailhead.salesforce.com/en/credentials/javascriptdeveloperi) exam will test you on that “vanilla” knowledge. And even if you already actively use it, you might learn something new along the way. ## Broaden your “JavaScript” horizons ![Superbadge prerequisites shown for the JavaScript Developer I certification path.](/should-i-get-javascript-developer-i-certified/superbadge-prerequisites-34c7470102_hu_a9003f937d8eaa7f.webp) You must be prepared to dig into the Salesforce platform when interested in this certification. It wasn’t explicitly designed for Salesforce B2C Commerce developers, but for [Lightning Web Component](https://developer.salesforce.com/docs/component-library/documentation/lwc) developers on the force.com platform. And you can’t get it by just doing the certification exam on [Webassessor](https://www.webassessor.com/). You also need to complete a [Superbadge](https://trailhead.salesforce.com/en/content/learn/superbadges/superbadge_lwc_specialist), which does not have a strict timeline. > Superbadges are domain-based credentials that allow you to apply your Salesforce skills in a specific area (think: process automation or app customization) to hands-on, real-world business problems Salesforce ## No Salesforce CRM experience ![A group of Salesforce Mascots at a Salesforce event. Are they JavaScript Certified, I wonder?](/should-i-get-javascript-developer-i-certified/mascots-statues-4150ee8fae_hu_d49c8577567f037a.webp) No worries, It’s not rocket science! You will spend some time getting this [Superbadge](https://trailhead.salesforce.com/en/content/learn/superbadges/superbadge_lwc_specialist), but see it as a way to discover other opportunities within the Salesforce ecosystem. Looking at what has happened for the past years, it is clear that some knowledge of other Salesforce products will get you a long way. More and more “tight” integrations are working their way into the Salesforce B2C Commerce Cloud world. Look at the Salesforce OMS (Order Management System), which has a productised connection. It is also why [OCI](https://developer.salesforce.com/docs/commerce/commerce-api/references?meta=inventory-availability:Summary) (Omnichannel Inventory) has made its way into SFCC, being part of the license. More and more projects are also integrating with Service and Sales Cloud (though not through a productised connection). ## Some preparation materials Since the certification is about vanilla JavaScript, there is a lot of content to get you on your way. But, there is also content available specifically for those who want this certificate on their belt. - [Salesforce Ben](https://www.salesforceben.com/javascript-developer-i-certification-guide-tips/) - [Salesforce Developers](https://www.youtube.com/playlist?list=PL4uWMJo2sZ6zq6cMTWb5Ns4_f932ANj_-) - [SFDCPanther](https://www.youtube.com/playlist?list=PLV3ll8m0ZlprmG4FT-G5Ak34ps1IO_UUG) - [Salesforce Troop](https://www.youtube.com/playlist?list=PLSWzWO4OqYAqQ8i16aIMakTW7InVuMTZF) - [Trailmix](https://trailhead.salesforce.com/en/users/strailhead/trailmixes/prepare-for-your-salesforce-javascript-developer-i-credential) - [Focus On Force: Practice Exams (Paid)](https://focusonforce.com/salesforce-javascript-developer-1-certification-practice-exams/) - [Github: JavaScript Questions](https://github.com/lydiahallie/javascript-questions) --- ## Fetch Data in Another Locale with SFCC Canonical URL: https://rhino-inquisitor.com/fetching-data-in-a-locale-with-sfcc/ Markdown URL: https://rhino-inquisitor.com/fetching-data-in-a-locale-with-sfcc/index.md Content type: article Published: 2023-07-31T08:40:09Z Updated: 2023-07-31T08:43:08Z Summary: In some use cases, you have to fetch data in a different language than the locale you are currently in. But how do you do that? Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, technical ## Key Takeaways - Shows how request locale controls localized data retrieval in SFCC server-side code - Explains the simple locale-switch pattern and why restoring the original locale matters - Contrasts the server-side approach with locale handling in headless storefront APIs SFCC provides a [built-in system to manage different aspects of the data](/the-salesforce-b2c-commerce-cloud-environment/) in multiple languages. But sometimes, you want to show something in a specific locale outside the current session context. How can this be done? ## tl;dr solution For those in a hurry: ```javascript // Store the current situation to re-set it later var currentLocale = request.getLocale(); request.setLocale('xx_XX'); /* * Do your thing */ // Reset the request language to the original request.setLocale(currentLocale); ``` ## How does it work? Ultimately, the solution is quite simple - the Salesforce B2C Commerce Cloud systems take care of the “hard stuff” for us. We have to tell it at the right time in what language we want our object to be returned. ### The request takes point The system will look at the current request’s language preference (or setting) whenever an object is fetched through its appropriate function (and it has localised attributes). The request is always available in every context under the global variable “[request](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_system_Request.html)”. It is always there, no matter where you are: - Storefront request - Business Manager request - Job Step - [OCAPI / SCAPI Hook](/how-to-use-ocapi-scapi-hooks/) ### Changing the language before fetching data To fetch data in a specific language, we must modify the current request before doing the “get”. If we want to fetch an attribute in a specific language, we can do something like this: ```javascript var ProductMgr = require('dw/catalog/ProductMgr'); var product = ProductMgr.getProduct('my_sku'); request.setLocale('zh_CN'); var cnName = product.name; request.setLocale('en_US'); var enName = product.name; ``` No re-fetching of the entire record is required! Always think about performance, and do not needlessly fetch the same object when it is not necessary. ### Restoring the locale if necessary Remember to restore the original language after the data has been fetched in the alternate language. If this is forgotten, all the data fetched after will be in the incorrect language! ## Use cases ![A map of the world representing all locale in the world.](/fetching-data-in-a-locale-with-sfcc/people-around-the-world-551b94bfa5_hu_3321553550127dae.webp) Figure 1: A map of the world representing all locale in the world Some might ask, why would you need to do such a thing? Well, there are a few reasons which will cause you to resort to fiddling with the request: - Fetching a content asset in a different language, a language selection popup, for example. - Generating a single-file feed with multiple languages - Fetching a translation from a resource bundle in a specific language - … and many more ## What about the Composable Storefront? The system of working with locales within the [PWA Kit](/sitegenesis-vs-sfra-vs-pwa/) is entirely different, which should be no surprise as this is a Headless Storefront in React. The composable storefront uses the ‘[commerce-sdk-isomorphic](https://github.com/SalesforceCommerceCloud/commerce-sdk-isomorphic)’ package, which accepts a locale parameter passed on to the endpoint as a URL parameter: ```text https://{shortCode}.api.commercecloud.salesforce.com/product/shopper-products/v1/organizations/{organizationId}/products/{id}?siteId=SiteGenesis&locale=en-US" ``` This means you can easily fetch something in a specific language by doing a REST API call, with the downside of having the fetch the entire record (unless it supports property selection). You could resort to [custom hooks](/how-to-use-ocapi-scapi-hooks/) or even [a custom endpoint](/creating-custom-ocapi-endpoints/) in certain use cases. --- ## How to filter JSDoc in Storybook Autodocs Canonical URL: https://rhino-inquisitor.com/how-to-filter-jsdoc-in-storybook-autodocs/ Markdown URL: https://rhino-inquisitor.com/how-to-filter-jsdoc-in-storybook-autodocs/index.md Content type: article Published: 2023-07-28T07:53:53Z Updated: 2023-07-28T13:57:31Z Summary: Over the past few months, I have grown to love Storybook as it gives me all the tools necessary to expose my components for testing and documentation. Categories: React Tags: storybook, technical ## Key Takeaways - Explains why default Storybook Autodocs output can render JSDoc poorly for component docs - Shows how to override the docs page and replace Description with a filtered custom component - Demonstrates a targeted fix that keeps only the descriptive JSDoc text before parameter blocks Over the past few months, I have grown to love [Storybook](https://storybook.js.org/) as it gives me all the tools necessary to expose my components for testing and documentation. One of its features, called “[Autodocs](https://storybook.js.org/docs/7.0/react/writing-docs/autodocs)”, has been a real help to speed up getting these components exposed inside of Storybook. Recently, I ran into an issue related to using JSDoc with Storybook. JSDoc was being printed out as Markdown but was erroneously formatted. Further, it was trying to execute the @example code, which led to console errors. I want to share how I resolved the issue through this blog post. ![Storybook Autodocs before filtering, showing excessive JSDoc output.](/how-to-filter-jsdoc-in-storybook-autodocs/storybook-jsdocs-before-90d7cc5222_hu_6f7392d0ec62eea6.webp) Before ![Storybook Autodocs after filtering, showing only the cleaned description.](/how-to-filter-jsdoc-in-storybook-autodocs/storybook-jsdocs-after-8063d0ff66_hu_6d1aa6709c3fa0f5.webp) After ## The problem Autodocs aims to take all of the “hard” work out of your hands and let you focus on more important things. And that is all fine until it does something that just doesn’t comply with your way of developing. The problem primarily lay in how `<Description/>` was utilised in preview.js. As we were utilising PropTypes, we didn’t need to get anything beyond the description. ## Modifying Autodocs to play nice with JSDoc ### Override the template Luckily storybook allows us to customise the page templates by setting the “page” rendering function in preview.js(x). ```html // .storybook/preview.jsx import { Title, Subtitle, Description, Primary, Controls, Stories } from '@storybook/blocks'; export default { parameters: { actions: { argTypesRegex: '^on[A-Z].*' }, controls: { matchers: { color: /(background|color)$/i, date: /Date$/, }, }, docs: { page: () => ( <> <Subtitle /> <Description /> <Primary /> <Controls /> <Stories /> </> ), }, }, }; ``` And the component of interest in this override is the `<Description />`!\` ### Create a custom description component To create our component, I decided to dig into the Storybook source code to see what is necessary: 1. The description 2. Our own component #### Getting the description After digging into the code I found this function: ```js const getDescriptionFromResolvedOf = (resolvedOf) => { switch (resolvedOf.type) { case 'story': { return resolvedOf.story.parameters.docs?.description?.story || null; } case 'meta': { const { parameters, component } = resolvedOf.preparedMeta; const metaDescription = parameters.docs?.description?.component; if (metaDescription) { return metaDescription; } return ( parameters.docs?.extractComponentDescription?.(component, { component, parameters, }) || null ); } case 'component': { const { component, projectAnnotations: { parameters }, } = resolvedOf; return ( parameters.docs?.extractComponentDescription?.(component, { component, parameters, }) || null ); } default: { throw new Error( `Unrecognized module type resolved from 'useOf', got: ${(resolvedOf).type}` ); } } }; ``` This function will extract the description based on what page we are looking at! #### CustomDescription component Now we need our own component to utilise this function: ```js const ModifiedDescription = (props) => { const { of } = props; if ('of' in props && of === undefined) { throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?'); } const resolvedOf = useOf(of || 'meta'); // if @param exists, only show description up to @param let description = getDescriptionFromResolvedOf(resolvedOf); if (description) { description = description.split('@param')[0]; } return ( {description} ) } ``` Here, we use Storybook’s built-in Markdown to display the content by removing everything after ‘@param’. This results in displaying only the description we wanted. #### Replace the default component Next, we replace the `<Description/>` in the Docs.page of Storybook with our custom `<ModifiedDescription/>` component. ```html const preview = { parameters: { docs: { page: () => ( <> <Subtitle /> <ModifiedDescription /> <Primary /> <Controls /> <Stories /> </> ) }, }; ``` ## Putting it all together ```html import { Title, Subtitle, Primary, Controls, Stories, useOf, Markdown } from '@storybook/blocks'; const getDescriptionFromResolvedOf = (resolvedOf) => { switch (resolvedOf.type) { case 'story': { return resolvedOf.story.parameters.docs?.description?.story || null; } case 'meta': { const { parameters, component } = resolvedOf.preparedMeta; const metaDescription = parameters.docs?.description?.component; if (metaDescription) { return metaDescription; } return ( parameters.docs?.extractComponentDescription?.(component, { component, parameters, }) || null ); } case 'component': { const { component, projectAnnotations: { parameters }, } = resolvedOf; return ( parameters.docs?.extractComponentDescription?.(component, { component, parameters, }) || null ); } default: { throw new Error( `Unrecognized module type resolved from 'useOf', got: ${(resolvedOf).type}` ); } } }; const ModifiedDescription = (props) => { const { of } = props; if ('of' in props && of === undefined) { throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?'); } const resolvedOf = useOf(of || 'meta'); // if @param exists, only show description up to @param let description = getDescriptionFromResolvedOf(resolvedOf); if (description) { description = description.split('@param')[0]; } return ( {description} ) } /** @type { import('@storybook/react').Preview } */ const preview = { parameters: { docs: { page: () => ( <> <Subtitle /> <ModifiedDescription /> <Primary /> <Controls /> <Stories /> </> ) } }, }; export default preview; ``` --- ## What is new in the 23.8 Commerce Cloud release? Canonical URL: https://rhino-inquisitor.com/what-is-new-in-the-23-8-commerce-cloud-release/ Markdown URL: https://rhino-inquisitor.com/what-is-new-in-the-23-8-commerce-cloud-release/index.md Content type: article Published: 2023-07-27T13:28:13Z Updated: 2023-07-29T20:05:35Z Summary: Review the 23.8 Commerce Cloud release and the platform changes teams should understand before holiday readiness work ramps up. Categories: Release Notes, Salesforce Commerce Cloud Tags: scapi, sfcc, technical ## Key Takeaways - Highlights the 23.8 release as a mostly infrastructure- and scalability-focused update ahead of holiday readiness - Calls out the most relevant changes around PWA Kit cookie support, SLAS session behavior, and Account Manager security controls - Explains why teams should still review quieter releases carefully when the main impact is operational rather than feature-heavy Everyone knows that getting ready for the holiday season starts in the summer in the Commerce Cloud world! And looking at the [23.8 release notes,](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_23_8_release.htm&type=5) this is apparent. Are you interested in last month’s release notes? [Read the 22.6 release notes](/salesforce-b2c-commerce-the-22-6-release/)! ## Infrastructure and Scaling Those who have reviewed the release notes may not notice many new additions to explore in the 23.8 release. However, upon closer inspection, it becomes apparent that the emphasis has been placed on improving infrastructure and scalability, which could account for the absence of fresh features. Let’s take a look! ## PWA Kit (3.1.0) > The latest release of the PWA Kit now allows for the conditional enabling of cookies within Managed Runtime. Previously, cookies were not allowed on SSR requests, optimising performance but limited use cases where cookie data was required. With this new functionality, you can enable cookies per environment and modify their application logic and response via ssr.js. This means that after a customer logs in, the experience can be altered by setting the cache control header to private and leveraging the cookie on the response. To enable cookies, set the allow\_cookies attribute on an environment with the projects\_target\_partial\_update endpoint and use PWA Kit version 3.1.0 or greater. With this new update, we get more flexibility to support use cases! It is crucial, however, to think about performance, as this can potentially **lower your cache-hit ratio**! [Cookie support demo recording](/what-is-new-in-the-23-8-commerce-cloud-release/cookie-support-demo.mp4) ## OCAPI & SCAPI ### Get Accurate Allocation Amounts with a Null Allocation Payload > PATCH and PUT /product\_inventory\_records/{product\_id} now supports a null allocation payload while keeping accurate account of product allocation amounts and allocation reset date. Previously, sending a Patch or Put call to set a custom inventory record attribute using a null allocation payload resulted in an invalid reset date. Salesforce has implemented a bugfix in the [Inventory API](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/ocapi-data-api?meta=Update%2BProduct%2BInventory%2BRecord) to ensure that the allocation reset date remains in a valid state and does not become invalid. There is not much else to report about this update. ### SCAPI > - Optional query parameter locale, is now supported for mergeBasket, transferBasket and all delete endpoints in Shopper Orders and Shopper Baskets, with the exception of deleteBasket. > - PaymentCardSpec includes a new field securityCodeLength. This is available in the response for Shopper baskets - getPaymentMethodsForBasket and Shopper Orders- getPaymentMethodsForOrder endpoints. > - Coming soon: mergeBasket and transferBasket response will no longer include the property notes. Previously, this property was sent with an empty value in the response. > - Fix coming soon: mergeBasket will return an HTTP 409 error response no-source-basket-exception if the guest’s basket has already been ordered. Previously, the ordered guest basket was merged with the new basket. > - Shopper Search productSearch now correctly handles storefront search queries with the & character and considers all terms before and after the &. Previously, the search query was incorrectly truncated before the & character and subsequent terms were missing in the query. More support for the “locale” parameter should make many people happy! Nothing else to report except future bugfix statements and actual bug fixes. And, of course: **scalability and infrastructure improvements**. ### SLAS > - SLAS Infrastructure and scale improvements. > - SLAS Admin UI improvements related to user search and get user statistics. > - Fixed logout implementation. SLAS to OCAPI calls no longer fail throwing (ClientAccessForbiddenException) > - As part of our efforts to scale the SLAS service for the upcoming holiday volume, temporarily, starting the week of August 7th, registered shopper sessions are valid for only 45 days. This applies to shopping apps integrated with SLAS, and to shoppers who have not returned to the shopping app at least once in the last 45 days need to relogin. This temporary state will conclude until September 15. After September 15, registered shopper login sessions will resume their full 90 day, standard duration. Shopper Guest sessions and B2C Commerce basket retention is not affected in any way. As I previously stated, the emphasis is on enhancing infrastructure and expanding scalability. However, it is essential to note that **SLAS will now only maintain active sessions for 45 days instead of the previous 90 days** until September 15th. If you are using SLAS in your projects, please keep in mind this temporary change. ## Account Manager > - Security Fixes > - Bug Fixes > - Infrastructure Updates A bit of familiar maintenance has happened on the Account Manager. But not to worry: there is more! ### UUID API Access Tokens Deprecated I have written [extensively on this topic](/the-deprecation-of-the-uuid-token-for-api-clients/) before, so it’s not something new. The due date has already passed and your only recourse now is to use JWT. ### Specify Enhanced Domain Names In Account Manager ![Salesforce Identity screen showing sign-in with external identity services.](/what-is-new-in-the-23-8-commerce-cloud-release/salesforce-identity-b628afdc63_hu_8dea5400c98da03a.webp) > You can now configure Identity Federation with Salesforce Identity in Account Manager using supported enhanced domain names. You can specify the organization MyDomain subdomain name in Salesforce Core. The default domain suffix is my.salesforce.com. If the identity federation is allowed or enforced, you can change the value. For example, if you use a Salesforce Core sandbox, you can use sandbox.my.salesforce.com as the domain suffix. This is a great new feature if you’re using or planning to use Salesforce Identity. If you are unfamiliar with it, you can have a single login for multiple Salesforce products. So depending on your situation, this [is one to look into!](https://www.salesforce.com/products/platform/products/identity/) ### Stricter rules for API Client Passwords Only new passwords These new requirements will only be enforced when a password is changed and won’t affect existing passwords. > For stronger passwords and better security, new password requirements are now enforced for Account Manager API Clients. To ensure better security, there are new password requirements in place. Passwords must be **at least 12 characters long** and have a minimum complexity that includes **three out of four - numbers, symbols, lower case, and upper case**. Passwords **cannot include any part of your name, username, or UUID**. ### Auto Disable Inactive Users > Compliance with PCI DSS 8.1.4 requires that Account Manager user accounts are disabled when their accounts are inactive for 90 days. To support compliance with PCI DSS 8.1.4, Account Manager administrators can now set the number of inactive days before an account is disabled. When the setting is enabled, users with inactive accounts receive an email notification 10 days and 1 day before their account is deactivated. To keep an account active, users can log in to any Commerce Cloud application. To enable the setting, in Account Manager > Organization details, activate or deactivate the setting. The setting is disabled by default. One of the benefits of using Salesforce Commerce Cloud is that users don’t have to concern themselves with infrastructure or compliance with various regulations, in this case: [PCI DSS 8.1.4](https://listings.pcisecuritystandards.org/documents/PCIDSS_QRGv3_1.pdf). Remember that with this change, inactive accounts will be automatically disabled after 90 days of inactivity, **but not deleted**! ## Updated Cartridges & Tools ### resource manager (v2.0.1) - [https://github.com/SalesforceCommerceCloud/resource-manager](https://github.com/SalesforceCommerceCloud/resource-manager) > This cartridge contains a Business Manager module that allows editing, translating and publishing of resource bundles. - Version 2.0.1 is here! This version contains a slew of updates and improvements. - Added **OpenAI translation support** - you can now translate your keys and bundles using ChatGPT - Updated Webpack and added development config - Added ‘address’ sample bundle from SFRA - Refactoring of client-side code - Various UI improvements - Upgrade to the latest compatibility mode (22.7) to support template literals - Update README.md with the latest changes, recent screenshots and OpenAI setup instructions - Feature/translation support by [@sfelius](https://github.com/sfelius) in [#17](https://github.com/SalesforceCommerceCloud/resource-manager/pull/17) --- ## AI as an Architect and Content Creator Canonical URL: https://rhino-inquisitor.com/ai-as-an-architect-and-content-creator/ Markdown URL: https://rhino-inquisitor.com/ai-as-an-architect-and-content-creator/index.md Content type: article Published: 2023-07-24T06:43:19Z Updated: 2023-07-24T06:43:36Z Summary: As a content creator and Salesforce Commerce Cloud architect, I am fascinated by the seamless integration of technology and creativity. Categories: AI, Salesforce Commerce Cloud Tags: ai, ohana, sfcc, technical ## Key Takeaways - Shows how AI tools support blog titles, images, documentation, and developer workflows - Explains why human expertise still drives the article content and technical substance - Shares a practical creator workflow that uses AI for speed rather than full replacement As a content creator and Salesforce Commerce Cloud architect, I am fascinated by the seamless integration of technology and creativity. AI has revolutionised my workflow, from creating stunning visuals for my blog to refining my writing. Its ability to streamline processes and improve efficiency has made my work more productive and fulfilling. I continuously seek new ways to leverage AI to drive innovation and creativity! But over the past months, the fact that I use this technology has not gone unnoticed. And there is a question that pops up quite often lately. **_What tools do I use?_** I have been asked a few times how I utilise AI for blogging work. Let’s use this article as an example of how I build it and move on to my other work (architectural and development) uses. ## Blogging As promised, I’ll document my entire process of writing this article and include screenshots. An image says more than a thousand words, right? ### Thinking of a title - **Generation Type**: Text - **Generation Engine**: OpenAI GPT 3.5 Turbo The first thing when writing a new blog post is… the subject. And generally, coming up with a topic is not the issue. There are [many things to write about](/archive/) in the Salesforce Commerce Cloud ecosystem and technology in general. But thinking of an engaging title is something entirely different… ![A screenshot of ChatGPT transforming the original title of this blogpost to some creative ones](/ai-as-an-architect-and-content-creator/generating-a-post-title-36528f6a0f_hu_6450a5b9fb028fd.webp) AI was most useful here as a fast brainstorming partner for stronger blog titles. And that is where ChatGPT comes into play, allowing me to ask for some ideas! All that is left is to mould them to my needs, and voila - we have a title! ### Some graphics to go with it - **Generation Type**: Image - **Generation Engine**: Stable Diffusion 1.5 - **Model**: DreamShaper v7 Regarding images, many options are available - each requiring its own style of prompting and capabilities. When choosing image engines and models, I consider the style I want. For this particular image, I wanted a Cyberpunk-style face with a technological twist, but not excessively dystopian. ![A screenshot of Leonardo.AI of generating the image of this post using the prompt 'a mix of a human male face wearing glasses with a robot'](/ai-as-an-architect-and-content-creator/generating-a-post-image-51933457be_hu_dd2f9a86562e6c96.webp) Generative image tools help turn a vague visual idea into a usable post illustration. Another step is completed, but filling an article with engaging content is a tad more challenging. ### The content - **Generation Type**: GPThomas 6 - **Generation Engine**: Me, myself and I - **Model**: 10+ Years Experience Model Honestly, I tried using AI to generate content. But for Salesforce B2C Commerce Cloud and especially new features, it just wasn’t working out: - Incorrect - Repetitive - Uninspiring After careful consideration, I decided to utilise [Grammarly](https://www.grammarly.com/) as a tool for fine-tuning the tone and detecting any spelling errors in my writing. As English is not my primary language, this AI tool helps correct mistakes and adjust my writing for tone or technicality. ![A screenshot of this blog post being assisted with the Grammarly AI tool.](/ai-as-an-architect-and-content-creator/grammarly-and-content-cf057efe86_hu_697928d9757b272e.webp) Grammar tools became the editorial pass that helped tighten tone and clarity. And when all of the content is written and adjusted with [Grammarly](https://www.grammarly.com/), we have an article! That wasn’t so hard now, was it 😅 Alright, it’s not writing the articles by itself, but using these tools has significantly reduced the time necessary to go from an idea to an entirely written article! And isn’t that the intended goal? Not to replace, but to enhance our creativity and speed up the process! ## Other uses for AI Blogging is only a tiny part of my life, and I use AI in plenty of other places! ### Development - **Generation Type**: Text and Code - **Generation Engine**: Github Copilot For the past months, I have purchased a [Github Copilot](https://github.com/features/copilot) license for personal and professional use. ![A screenshot of Webstorm showing React testing code being generated.](/ai-as-an-architect-and-content-creator/github-copilot-react-e4aab607d7_hu_191849ba4e878cfa.webp) For development work, AI was most helpful when accelerating repetitive test scaffolding. While sometimes it generates “garbage”, 99% of the time, it gives me great suggestions and understands my intent within my code. While I love the tool, I see some dangers for junior developers. And for one big reason: “_You must [understand](/preparing-for-the-b2c-commerce-developer-certification/) the code generated for you; if you don’t, it will hinder your growth and career._” ### Developer Documentation - **Generation Type**: Text - **Generation Engine**: OpenAI GPT 4 > **Documentation:** and explaining how a feature works is not always a developer’s most “exciting” job. Giving your code to the engine and asking for documentation can have some decent results! ![A screenshot of the OpenAI GPT 4 playground, documenting a React Component.](/ai-as-an-architect-and-content-creator/documentation-with-gpt-4-b13ad915e5_hu_8057d746ca9a714.webp) Documentation became easier once AI could turn working code into a first draft. ### Feature / Integration Documentation - **Generation Type**: Text - **Generation Engine**: OpenAI GPT 4 I find myself frequently immersed in technical documentation as an architect. It can become overwhelming at times for non-technical persons. But fortunately, AI technology has proven to be a valuable tool in simplifying complex documentation and transforming it into a more understandable format. ### Communication As mentioned, I rely heavily on [Grammarly](https://www.grammarly.com/) for all my blogging and English communication needs. With this tool in my arsenal, I can confidently convey my message through documentation, emails, or even chat messages, knowing it is accurate and understandable. ### #Shirtforce - **Generation Type**: Image - **Generation Engine**: Stable Diffusion - **Model**: Depends on the design I have long been held back by my limitations in drawing, which prevented me from bringing my creative visions to life. But with the help of generative AI, I can now quickly turn my ideas into [reality](https://shirtforce.org/tee/hybrid-deployment-theory-salesforce-commerce-cloud-tshirt/). ![Hybrid Deployment Theory T-shirt design mockup generated with AI.](/ai-as-an-architect-and-content-creator/hybrid-deployment-theory-02-poc-a7602136f7_hu_6880755dfe1751a8.webp) Image generation also unlocked side projects that previously depended on drawing skills. The generated image usually gets me 50-80% there, and then I fine-tune the details in Photoshop! Even though that still takes a lot of time, it is much less than it would have taken me from scratch! ## How much time do I spend per article? Many people probably want an answer to this, wondering where I find the time to do all of this. I spend about 2-4 hours on a single article, and the time depends on the subject. A well-documented feature will take less time than a [non-documented feature](/delta-exports-in-salesforce-b2c-commerce-cloud/), hidden away by a feature switch that not everyone knows exists. Although some articles may not require much time, the accompanying attachments can take weeks. A great example of this is the [ERD series.](/salesforce-b2c-commerce-cloud-erd/) --- ## 9 Salesforce Commerce Cloud Products Canonical URL: https://rhino-inquisitor.com/salesforce-commerce-cloud-products/ Markdown URL: https://rhino-inquisitor.com/salesforce-commerce-cloud-products/index.md Content type: article Published: 2023-07-17T09:07:01Z Updated: 2023-07-17T09:11:18Z Summary: Salesforce Commerce Cloud has gotten a lot bigger in the past few years, adding more and more products to the "name." Let us go over them! Categories: Salesforce Commerce Cloud Tags: sfcc ## Key Takeaways - Surveys the broader Salesforce Commerce product family and clarifies how each offering relates to classic SFCC - Explains the frequent confusion between B2C, B2B, D2C, OMS, OCI, marketplaces, composable storefront, and payments - Acts as a practical orientation guide for understanding where SFCC sits inside the larger Commerce Cloud portfolio You are probably here, reading this blog to learn more about [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/). But over the past years, more products have been put under Salesforce Commerce Cloud “wings.” Salesforce has quite the history of renaming products, causing some confusion with possible customers, partners, and within Salesforce itself! Let us have a look at them, and see how some are connected to SFCC (or not). ## SFCC - Salesforce B2C Commerce Cloud (Demandware) ![Comparison between SiteGenesis and SFRA storefront stacks.](/salesforce-commerce-cloud-products/sfra-vs-sitegenesis-965c09b9a6_hu_b93be19e82ca4e6f.webp) B2C Commerce still centers on storefront frameworks such as SiteGenesis and SFRA. Let us start with the most expected item on the list: “Salesforce B2C Commerce Cloud”, also known as Demandware, before being [acquired by Salesforce for $2.8B](https://techcrunch.com/2016/06/01/salesforce-buys-demandware-for-2-8b-taking-a-big-step-into-e-commerce/). It sounds like a good deal compared to the [acquisition of Slack,](https://techcrunch.com/2020/12/01/salesforce-buys-slack/) doesn’t it 😜? Since this is an acquired product, it runs on a completely different stack than the core platform of Salesforce. And this has been a confusing topic in the general Salesforce community for a long time now (many think it is built on the CRM). The reason for that we will touch on later. This platform mainly aims at B2C customers but doesn’t shy away from supporting B2B. And being a SaaS platform, it auto-scales very well to support high-traffic events such as [Black Friday and the holiday period](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_21_10_get_holiday_ready_je.htm&type=5)! SFCC also offers some different “flavours,” which I elaborated on [in an earlier article](/sitegenesis-vs-sfra-vs-pwa/). ## Salesforce B2B Commerce Classic (CloudCraze) ![CloudCraze storefront example in the Salesforce CRM environment.](/salesforce-commerce-cloud-products/cloudcraze-cd6f91241b_hu_806b721e5181fbcf.webp) CloudCraze shows how Salesforce originally tackled B2B commerce inside core CRM. This is where the confusion started to originate (I think). In 2018 [another acquisition happened](https://techcrunch.com/2018/03/12/salesforce-will-acquire-enterprise-e-commerce-software-startup-cloudcraze/) by Salesforce, but this time in the CRM space: “CloudCraze.” It was a Managed Package on the CRM that stretched the imagination of what the platform could do by building a complete B2B Platform on top of it. Because it had to use a few tricks to allow the number of customizations an Ecommerce Platform requires, it had its “unique” way of working compared to the CRM. A lot of custom development was needed to get it up and running as you wanted it to. But once you did, you had a fully operating B2B site in [Visualforce](https://trailhead.salesforce.com/content/learn/modules/visualforce_fundamentals). ## Salesforce B2B Commerce (Lightning) ![B2B Commerce experience built with Lightning components.](/salesforce-commerce-cloud-products/b2b-lightning-b6e80d0718_hu_524ccff42f15ad10.webp) Lightning B2B Commerce moves the storefront experience deeper into the Salesforce platform. Since CloudCraze was a managed package on the classic environment, a new version was made in the Lightning Runtime. Salesforce started to rebuild the system from scratch to align with the CRM and allow customisations the same way as the rest of the product line. This meant the more modern [Lightning Web Components](https://developer.salesforce.com/docs/component-library/documentation/lwc) could be used instead of [Visualforce](https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_intro_what_is_it.htm) Pages. And, of course, the feature set has grown over time to allow more flexibility and support more use cases than before! Get to know more If you want to learn more about it, there is an excellent Youtube Channel called [Salesforce Mojo](https://www.youtube.com/@salesforcemojo)! ## Salesforce D2C or B2B2C or Commerce on Core ![Commerce on Core storefront for direct-to-consumer selling.](/salesforce-commerce-cloud-products/salesforce-b2b2c-6f2e4e7217_hu_b4db707c75b1e0f9.webp) Commerce on Core is Salesforce's newer path for direct-to-consumer experiences. A more recent product (not acquired this time) is D2C, which is meant to work as an extension to a B2B website. And again, this one is also built on the CRM! With more and more B2B companies wanting to sell directly to the consumer, Salesforce had to come up with an answer. This turned out to be [D2C](https://trailhead.salesforce.com/content/learn/modules/b2b2c-commerce-basics). The main idea of this product is to create a customer-facing website with just clicks and as little custom code as possible. But let me get back to that “confusion” part. Do you see what name it has in the screenshot? It is also called Salesforce **B2C Commerce** Cloud. Both products target B2C customers but have a different angle on how to do this. D2C (B2C Commerce) aims to give already Salesforce B2B Commerce clients an easy way to connect directly to their consumers as a secondary channel. At the same time, Salesforce B2C Commerce Cloud is meant as a “primary” selling channel for Businesses that see B2B as a secondary channel. I hope that clarifies the “confusion” regarding B2C Commerce in the Salesforce space. Or are you even more confused now? Let me know on the known social channels! ## Salesforce Order Management ![Salesforce Order Management workspace connected to commerce operations.](/salesforce-commerce-cloud-products/salesforce-order-management-533a060e99_hu_e626f5eb6c6bf7e2.webp) Order Management extends the stack beyond the storefront into fulfillment and service operations. Another product built on the CRM, but good news. We are starting to head back into B2C Commerce Cloud territory! You may already know that an OMS (Order Management System) was once [built into Salesforce B2C Commerce Cloud](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OrderManagement/OrderManagement.html). This has been deprecated for a while and is no longer maintained; Salesforce will always point you toward the new Salesforce OMS. But not to worry, this product [natively integrates with SFCC](https://resources.docs.salesforce.com/latest/latest/en-us/sfdc/pdf/salesforce_order_management_implementation_guide.pdf)! (Well, with one support ticket away to flip a switch and quite a bit of configuration) This sounds optimistic. A lot of work is involved in getting an OMS up and running. More than just connecting it to your commerce platform will be required! If you want to learn more about this product, there are courses on the [Partner Learning Camp](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=0RvBSrDfVelmoIn4Km63qy9o3goOMpwHhZFzPKvrn%2BcTyRqXMOHIrsQt2T0ai2Kx) and [Trailhead](https://trailhead.salesforce.com/en/content/learn/modules/om-salesforce-order-management). ## OCI (Omnichannel Inventory) ![Omnichannel Inventory dashboard for shared stock visibility.](/salesforce-commerce-cloud-products/omnichannel-inventory-0b29da8f29_hu_eb0831acb59634ca.webp) OCI becomes the shared stock layer when inventory must stay consistent across channels. A “smaller” product in the lineup: a “Headless” addon called [OCI (Omnichannel Inventory)](https://trailhead.salesforce.com/en/content/learn/modules/omnichannel-inventory). A set of headless APIs to manage all of your inventory. I will not go into too much detail as I [already released a different article that digs into those details](/what-is-oci-omnichannel-inventory/)! License If you are a Salesforce B2C Commerce Cloud customer, this product is already included in your license! ## Commerce Marketplaces (Atonit) ![Marketplace analytics dashboard from the Atonit product suite.](/salesforce-commerce-cloud-products/atonit-tableau-9dae3f80c1_hu_718466bf10ee8398.webp) Atonit brings marketplace-specific analytics and operations into the wider commerce stack. > It has been our mission to create a marketplace management solution that is both easy to start and ready to scale, which is why we originally chose to build this solution on the Salesforce platform. Salesforce has been a company that has inspired us for many years, so it is particularly exciting for us to be the first company headquartered in Brazil to be acquired by Salesforce. Atonit Corporate Blog Post The most recent of acquisitions in the Commerce landscape: [Atonit](https://www.salesforceben.com/salesforce-signs-agreement-to-acquire-atonit/). A marketplace solution allows merchants to sell third-party products on their own website (or other channels). Built already on the force.com platform, it made sense to make the acquisition. And also good news, it already has a cartridge for Salesforce B2C Commerce Cloud! The idea within Salesforce is to tightly integrate this solution with its “Commerce Cloud” offering for all kinds of “markets” 😉 . ## Composable Storefront (PWA Kit and Managed Runtime) ![Composable Storefront architecture comparing the PWA Kit deployment model.](/salesforce-commerce-cloud-products/pwa-kit-comparison-07aff406fd_hu_c29c06ec596a0563.webp) Composable Storefront separates the storefront runtime from the legacy B2C architecture. Last but certainly not least, we look at [another acquisition by Salesforce (Mobify)](https://www.digitalcommerce360.com/2020/09/09/salesforce-agrees-to-buy-headless-commerce-tech-firm-mobify/). The answer of Salesforce to the new buzzwords floating around: - Headless - API First - Composable - … The [PWA Kit](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/pwa-kit-overview.html) provides an easy path to go Headless at the pace you want to go. Out of the box, it integrates with (_almost_) all Salesforce B2C Commerce Cloud features. But nothing stops you from swapping out a few components like CMS and Search… for another system that fits your needs. And another advantage is the [Managed Runtime](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/mrt-overview.html). Like we are used to with SFCC, Salesforce handles the hosting, security, uptime, and performance. So really, what’s not to like? [Keep Calm and Go Headless](https://shirtforce.org/tee/keep-calm-and-go-headless-salesforce-tshirt/)! ## Salesforce Payments ![Salesforce Payments workspace tied to a Stripe-backed checkout flow.](/salesforce-commerce-cloud-products/salesforce-payments-7926558e4f_hu_d7213e64a6fbdaa6.webp) Salesforce Payments keeps checkout and payment administration closer to the platform. [Salesforce Payments](/salesforce-payments-experience-explained/) is a native payment solution developed for the Salesforce Commerce Cloud platforms. For B2C Commerce Cloud, it is a plugin consisting of a Business Manager interface and cartridge, which provides native integration with the payment provider Stripe. Salesforce Payments is optional, and businesses can integrate any payment service provider (PSP) they desire. However, incorporating other PSPs may require more custom development work and offer different benefits than Salesforce Payments. --- ## Using Node 18 with SFRA Canonical URL: https://rhino-inquisitor.com/how-to-use-node-18-with-sfra/ Markdown URL: https://rhino-inquisitor.com/how-to-use-node-18-with-sfra/index.md Content type: article Published: 2023-07-10T08:09:37Z Updated: 2023-07-10T08:13:58Z Summary: Learn how to run Node 18 with SFRA, which compatibility checks matter, and where to watch for tooling or build issues during the upgrade. Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, technical ## Key Takeaways - Explains the practical path for running newer Node versions with modern SFRA projects - Calls out the OpenSSL legacy-provider workaround required by older SFRA build tooling - Warns that deeper dependency upgrades can be messy even when the core compile and upload scripts work As [responsible developers](/secure-coding-in-salesforce-b2c-commerce-cloud/), it’s important to stay up-to-date with the latest versions of our tools. The README of SFRA, unfortunately, reminds us that it is not always possible by recommending v12.21.0, which was the latest version at the time of launch (2017). However, Node and SFRA packages have undergone many updates since then, and utilising the latest versions is crucial for security reasons. Let’s keep our priorities in check and stay current with the latest updates. Is it possible to upgrade to the latest Node version? And what steps do we need to undertake? Let’s have a look! SFRA versions prior to 6.2.0 This guide will only work if you are on one of the latest versions of SFRA. Because node-sass was removed in version 6.2.0, upgrading Node versions became a lot “easier”. No need to worry! If you’re using an older version, there’s a node-sass version available for Node 18. But I will not cover that in this article. ## Activate Node 18 for your SFRA project ![Install Node 18 for SFRA](/how-to-use-node-18-with-sfra/node18-ac76311848_hu_e3f33941079e557c.webp) To use this version, it is necessary to install it first. Although I recommend using “[nvm](https://github.com/nvm-sh/nvm)”, it may not be the best option for every setup. It is crucial to explore and find the most efficient method for your specific setup to ensure the successful installation of this version. Messing with node versions can seriously block development if not done right, and we don’t want to be stressing out on our day job now do we? ## Install SFRA as usual Fortunately, we can still perform the usual “npm install” without hassle. Please note that you may receive a warning about the system modifying package-lock.json to ensure compatibility with the current version of Node. ```bash npm WARN old lockfile npm WARN old lockfile The package-lock.json file was created with an old version of npm, npm WARN old lockfile so supplemental metadata must be fetched from the registry. npm WARN old lockfile npm WARN old lockfile This is a one-time fix-up, please be patient... npm WARN old lockfile ``` So just as the message asks us, we will be patient. ## SGMF Scripts and SSL One of the hurdles in using the latest Node version is using a deprecated feature. Once you run any build or upload script, you will run into the following exception: ```text Error: error:0308010C:digital envelope routines::unsupported ``` Luckily, a quick google search later, we find the solution to this error. Enabling the “OpenSSL Legacy Provider”, and depending on your OS of choice a different command has to be used: ```text # Unix-like (Linux, macOS, etc...) export NODE_OPTIONS=--openssl-legacy-provider # Windows set NODE_OPTIONS=--openssl-legacy-provider # PowerShell $env:NODE_OPTIONS = "--openssl-legacy-provider" ``` It is possible to update your package.json, depending on your (and the teams) setup: ```text "scripts": { "test": "export NODE_OPTIONS=--openssl-legacy-provider && sgmf-scripts --test test/unit/**/*.js", "cover": "export NODE_OPTIONS=--openssl-legacy-provider && sgmf-scripts --cover 'test/unit'", "test:integration": "export NODE_OPTIONS=--openssl-legacy-provider && sgmf-scripts --integration 'test/integration/**/*.js'", "test:acceptance:custom": "npx codeceptjs run --plugins retryFailedStep --profile", "test:acceptance:deep": "npx codeceptjs run --plugins retryFailedStep --grep '(?=.*)^(?!.*@mobile)^(?!.*@tablet)^(?!.*@pageDesigner)' --profile", "test:acceptance:smoke": "npx codeceptjs run --plugins retryFailedStep --grep @happyPath --profile", "test:acceptance:pagedesigner": "npx codeceptjs run --plugins retryFailedStep --grep @pageDesigner --profile", "test:acceptance:desktop": "npx codeceptjs run --plugins retryFailedStep --grep '(?=.*)^(?!.*@mobile)^(?!.*@tablet)^(?!.*@pageDesigner)^(?!.*@deepTest)' --profile", "test:acceptance:mobile": "npx codeceptjs run --plugins retryFailedStep --profile sauce:phone --grep @mobile", "test:acceptance:tablet": "npx codeceptjs run --plugins retryFailedStep --profile sauce:tablet --grep @tablet", "test:acceptance:parallel": "npx codeceptjs run-multiple parallel --plugins retryFailedStep --profile", "test:acceptance:multibrowsers": "npx codeceptjs run-multiple multibrowsers --plugins retryFailedStep --profile", "test:acceptance:report": "./node_modules/.bin/allure serve test/acceptance/report", "bdd:snippets": "./node_modules/.bin/codeceptjs bdd:snippets --path", "compile:scss": "export NODE_OPTIONS=--openssl-legacy-provider && sgmf-scripts --compile css", "compile:js": "export NODE_OPTIONS=--openssl-legacy-provider && sgmf-scripts --compile js", "compile:fonts": "node bin/Makefile compileFonts", "build": "npm run compile:js && npm run compile:fonts && npm run compile:scss", "lint": "npm run lint:css && npm run lint:js", "lint:css": "export NODE_OPTIONS=--openssl-legacy-provider && sgmf-scripts --lint css", "lint:js": "export NODE_OPTIONS=--openssl-legacy-provider && sgmf-scripts --lint js", "init:isml": "./node_modules/.bin/isml-linter --init", "lint:isml": "./node_modules/.bin/isml-linter", "build:isml": "./node_modules/.bin/isml-linter --build", "fix:isml": "./node_modules/.bin/isml-linter --autofix", "upload": "export NODE_OPTIONS=--openssl-legacy-provider && sgmf-scripts --upload", "uploadCartridge": "export NODE_OPTIONS=--openssl-legacy-provider && sgmf-scripts --uploadCartridge app_storefront_base && sgmf-scripts --uploadCartridge modules && sgmf-scripts --uploadCartridge bm_app_storefront_base", "watch": "export NODE_OPTIONS=--openssl-legacy-provider && sgmf-scripts --watch", "watch:static": "export NODE_OPTIONS=--openssl-legacy-provider && sgmf-scripts --watch static", "release": "node bin/Makefile release --" }, ``` ## Libraries It seems like we still have a long way to go. The libraries we’re using for SFRA are outdated and trying to access Node functions that are no longer available. Let’s get cracking, and give them an update! ```bash npm update ``` ```bash npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: sfra@6.3.0 npm ERR! Found: stylelint@13.13.1 npm ERR! node_modules/stylelint npm ERR! dev stylelint@"^13.13.1" from the root project npm ERR! npm ERR! Could not resolve dependency: npm ERR! peer stylelint@"^8.0.0" from stylelint-config-standard@17.0.0 ``` ![Developer reviewing dependency updates after a failed npm resolution.](/how-to-use-node-18-with-sfra/upgrading-libraries-developer-d40cf53b81_hu_56c9eb18c64c0b65.webp) Ok. Probably never 😅 This task will require a significant amount of effort, and the outcome may vary depending on the used cartridges. If you have been working on a project for an extended period, some libraries may have been updated, while others remain unchanged from the beginning. However, it seems that the essential scripts are functioning correctly: - Compiling - Linting - Uploading And that is a good place to start! I hope this article proves helpful in updating your SFRA project to Node 18. Wishing you the best! ## Shouldn’t Salesforce make it compatible While the [Composable Storefront](/sitegenesis-vs-sfra-vs-pwa/) is generating a lot of excitement, SFRA remains a dependable choice for launching websites around the world. To stay current with the latest technology, it would make sense for Salesforce to simplify upgrading to Node 18. One important question remains: what will happen to third-party cartridges? It will require some investment from numerous third-party suppliers. The real question is, are they willing to make such an investment? --- ## Where can I find the new SFCC Documentation? Canonical URL: https://rhino-inquisitor.com/where-is-the-new-sfcc-documentation/ Markdown URL: https://rhino-inquisitor.com/where-is-the-new-sfcc-documentation/index.md Content type: article Published: 2023-07-03T06:32:44Z Updated: 2023-11-29T06:47:22Z Summary: Understand where the new SFCC documentation lives, what changed from Infocenter, and how to navigate the updated resources. Categories: Documentation, Salesforce Commerce Cloud Tags: documentation, sfcc ## Key Takeaways - Explains where SFCC documentation moved after the Infocenter retirement and how the new content is split across Help, Developer Center, and GitHub-hosted resources - Highlights the practical impact of that split for merchandisers, administrators, and developers trying to navigate the new structure - Offers a grounded opinion on the migration, including its likely benefits and the friction it introduced for experienced users In early 2023, we were notified that the Infocenter would be replaced with a supposedly more “modern” solution. While some may have looked forward to this update, others were disappointed by the news. Were these reactions anticipated? What changes are occurring? And where can we find the relevant [documentation](/salesforce-b2c-commerce-cloud-documentation/) now? Time to have a look! ## The official announcement In case you didn’t catch the official announcement, I’ve got you covered! Check out this link, or just read my copy/paste work. - [Salesforce B2C Commerce Infocenter Documentation Is Moving to Salesforce Help/Salesforce Developers/GitHub Pages](https://help.salesforce.com/s/articleView?id=000395100&type=1) > Beginning June 15, 2023, the information currently hosted on the Salesforce B2C Commerce Infocenter will be published across three locations. > > - Salesforce Help is the new home for administrator and merchandiser content. > - Commerce Cloud Developer Center is the new home for most developer-focused content. > - Salesforce B2C Commerce Developer Documentation Resources is the new home for the B2C Commerce API and other developer-focused content, including legacy developer documentation. Many improvements were made to the documentation as a part of the migration. As a result, there won’t always be a direct one-to-one mapping between topics in the Salesforce B2C Commerce Infocenter and topics in their new locations. Between June 15 and July 15, B2C Commerce documentation will be available in both the Infocenter and its new locations to help ensure a smooth transition for users. On July 15, 2023, the Infocenter will be retired and will no longer be available. ## The new locations ![Books with documentation scattered on multiple piles, falling over.](/where-is-the-new-sfcc-documentation/documents-on-multiple-locations-5bb9c96f2b_hu_5bc0c01f94ded8b6.webp) The word “locations” in the title of this section may be a concern for many people. Everything once found in a single place is now distributed among several. And the fact that this makes some veterans of SFCC nervous should come as no surprise. Nevertheless, this will have some advantages: - **Separation of concerns:** when looking for technical documentation, you will not be distracted or sent to the wrong place as easily as that happens now. And visa-versa. - **Included in the general help:** How well this works out will depend on the quality of the search engine of Salesforce Help. However, having one location and a similar style of documentation as the rest of Salesforce is (for me) a welcome change. The fact the URLs don’t contain the search query anymore is also helpful… ## Merchandisers & Admins - [Salesforce Help](https://help.salesforce.com/s/articleView?language=en_US&id=cc.b2c_getting_started.htm&type=5) Although this section applies to all roles, all functional documentation has been put under the “B2C Commerce for Merchandisers and Administrators”. In this section you will find everything about how to: - Merchandise B2C Commerce Cloud - Data protection & privacy - Account Manager - Log Center (although this one is technical) - Control Center - Storefront Toolkit - …. ## Developers - [Salesforce Developers](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/get-started.html) Salesforce provides a dedicated site for developers that serves as a centralized location for all developer documentation, with the exception two things which we will address later. Here you will find: - General development guidelines - Einstein documentation - Customer Service Center - [OCAPI](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/b2c-commerce-ocapi/get-started-with-ocapi.html) documentation As with the SCAPI documentation, the OCAPI now also lives in its separated bubble from the rest of the documentation. ### Legacy Documentation - [Legacy Documentation](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/LegacyDeveloperDocumentation.pdf) The Infocenter previously had documentation on features that are no longer available and outdated. Unfortunately, these documents cannot be transferred to the new system. However, they have been consolidated into a single PDF to ensure that important information is not lost. But does it make it easy to find something if you need it? Probably not. ### B2C Commerce API - [B2C Commerce API](https://salesforcecommercecloud.github.io/b2c-dev-doc) This movement will cause considerable friction with the Salesforce B2C Commerce Cloud developer community. The biggest question here is why it was not moved over to the developer center, to match [what was done on the core platform](https://developer.salesforce.com/docs/atlas.en-us.244.0.apexref.meta/apexref/apex_methods_system_system.htm#apex_System_System_enqueueJob_2). Understandably, it is a huge effort to move this over - and monthly releases need more maintenance. (Although the release notes of the core platform should not be underestimated….so many pages) #### An unofficial alternative Are you completely lost in the new system? Maybe this [unofficial solution](https://github.com/clavery/docset-sfcc-b2c) for [Dash](https://kapeli.com/dash), built by [Charles Lavery](https://github.com/clavery) will help you! ![Dash app indexing the B2C Commerce API documentation for offline lookup.](/where-is-the-new-sfcc-documentation/charles-lavery-dash-2de6a904d6_hu_bb58758ff81b6c6c.webp) ## My opinion ![Artwork of a person choosing between two flows.](/where-is-the-new-sfcc-documentation/go-with-the-flow-e1aeefde3e_hu_ddf858a9969f2747.webp) I just go with the flow...but suggest improvements As it stands for me, this change was to be expected. All new documentation was already moved over to these respective platforms (GitHub taken out of the equation), and the Infocenter was the “odd one out”. However, there is still a lot of work to be done, also on my side to get used to all of these new locations. Whether my workflow will improve or worsen is something I can not comment on yet. But we must give feedback via the known channels (such as [#documentation](https://sfcc-unofficial.slack.com/archives/CM7GDCR54) and [#airing-of-grievences](https://sfcc-unofficial.slack.com/archives/C019VUTDQ86)). Only time will tell! _Though I suspect the #airing-of-grievences channel on the [Unofficial Slack](https://unofficialsfcc.com/) should be monitored by the Salesforce team._ --- ## Can an isslot Element have a dynamic ID? Canonical URL: https://rhino-inquisitor.com/can-a-isslot-element-have-a-dynamic-id/ Markdown URL: https://rhino-inquisitor.com/can-a-isslot-element-have-a-dynamic-id/index.md Content type: page Published: 2023-06-28T18:13:06Z Updated: 2023-06-28T18:56:00Z Summary: A quick answer on why the SFCC isslot tag requires a static ID and which alternatives to consider instead. Categories: Documentation, Salesforce Commerce Cloud TL;DR It is not possible to set a dynamic ID in the `<isslot>` tag. ![Official isslot documentation showing the static slot identifier requirement.](/can-a-isslot-element-have-a-dynamic-id/isslot-element-d83390209d_hu_f46b5841d1e3fa1c.webp) - [Official Documentation](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-isslot.html?q=isslot) For quite some time now, Content Slots have been the go-to method for displaying personalized or scheduled content. However, the advent of Page Designer has given rise to a new option. Despite their popularity, one major limitation of [Content Slots](/salesforce-b2c-commerce-cloud-content-erd/) is the inability to set a dynamic ID. It’s likely that the system scans all ISML files to determine which slots to display for configuration in the Business Manager, but this is merely speculation since it is a black box feature. ## Alternative solutions to isslot ### Page Designer Using Page Designer will give you (and the merchandisers) a more modern option to manage their content! ### Context Slots support “category” and “folder” context objects that may provide a solution in specific use cases. --- ## A deep-dive into the 23.7 Commerce Cloud release Canonical URL: https://rhino-inquisitor.com/a-deep-dive-into-the-23-7-sfcc-release/ Markdown URL: https://rhino-inquisitor.com/a-deep-dive-into-the-23-7-sfcc-release/index.md Content type: article Published: 2023-06-28T07:47:03Z Updated: 2023-06-28T07:47:14Z Summary: Review the key changes in Salesforce B2C Commerce Cloud 23.7, from platform updates to headless improvements worth testing this month. Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc ## Key Takeaways - Highlights the most relevant 23.7 platform, API, and PWA Kit updates - Calls out Managed Runtime environment variables and promotion refinements - Flags new tooling and version upgrades worth testing after the release It’s summertime, which means we get to check out the fresh release of the Salesforce B2C Commerce Cloud. Join me as we delve into all the new features of the [July 2023 (23.7)](https://help.salesforce.com/s/articleView?language=en_US&id=sf.rn_b2c_rn_23_7_release.htm&type=5) release. Are you interested in last month’s release notes? Read the [23.6 release overview](/a-look-at-the-salesforce-b2c-commerce-cloud-23-6-release/). ## Environment Variables are now live on Managed Runtime > Environment variables allow you to add variables into the application process running in an environment, without having to make code changes. Environment variables are stored securely, making them ideal for use cases such as: > > - API keys for third-party integrations > - Feature flags for application logic > - Configuration that differs between environments Great news for users of Composable Storefront! You can now use the much-awaited feature of securely managing “secrets” and variables per environment! Currently, the API is the sole choice that is minimally (for now) documented [in the Managed Runtime environment variables guide](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.html#environment-variables). ## Improve Product Discoverability with the Google Inventory Listings Cartridge ![Google Local Inventory listing showing nearby shoe availability.](/a-deep-dive-into-the-23-7-sfcc-release/local-inventory-7952c2d4a2_hu_dba371c71321244d.webp) Google Inventory Listings surfaces nearby store stock directly in search results. > The Google Inventory cartridge is a B2C Commerce direct integration cartridge. You can use the cartridge to list your local store products on Google’s free product listings. Shoppers can discover products in stores near them. This increases local store foot traffic In today’s world, it’s essential to connect with customers at multiple touchpoints. Among these touchpoints, Google stands out as one of the most significant. By showcasing your products in proximity to Google searches, you can attract both new and loyal customers to your physical stores or online shop. It’s a proven strategy that can help your business stand out from the competition. You can download the cartridge to add to your codebase [from the Social Channel Integrations repository](https://github.com/SalesforceCommerceCloud/social_channel_integrations) to get started. ## Business Manager ### Receive Rejected Order Alerts in Business Manager > B2C Commerce Business Manager now displays an alert notification when orders are rejected by Salesforce Order Management. Users with access to the Business Manager orders module receive the alert and can review and act on rejected orders. The alert is also available in Slack when you connect your Business Manager instance to Slack. A much-needed update in the platform to be warned that one of the orders was not synchronised with Salesforce Order Management! Now we do not have to manually go to the page to see if an order was sent. But let us hope we don’t get any warning at all! ### Configure Up to 10 Categorization Conditions ![Categorization rule editor with support for up to ten conditions.](/a-deep-dive-into-the-23-7-sfcc-release/categorization-rules-in-23-7-affa83b506_hu_b3393943a94df096.webp) The rule editor now matches the API limit of ten conditions instead of five. > When configuring a categorization rule in Business Manager, you can now set up to ten categorization conditions per categorization rule set. Previously, Business Manager supported five conditions per rule set while the API supported ten conditions per rule set. This latest update gives us greater control and precision over the products [automatically assigned](https://help.salesforce.com/s/articleView?id=cc.b2c_dynamic_categories.htm&type=5) to a specific category. ## OCAPI & SCAPI ### Configure Promotion Search Refinement with OCAPI and SCAPI > You can now refine promotion searches in B2C Commerce OCAPI and SCAPI. Use the promotion search refinement APIs to generate and display results that help shoppers discover products that are on sale or part of a promotion. The description may be brief, but there’s good news - a support-only feature switch previously available for SG/SFRA has been enabled for headless implementations, enabling filtering based on promotions. Here are the steps to get started with this: 1. [Enable and configure it](https://help.salesforce.com/s/articleView?id=cc.b2c_configuring_catalog_level_search_refinement_definitions.htm&language=en_us&release=2.0.1&type=5) 2. [SiteGenesis/SFRA Code Changes](https://help.salesforce.com/s/articleView?id=cc.b2c_promotion_refinement_code_changes.htm&type=5) 3. [New “pmid” refinement for SCAPI](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-search?meta=productSearch) ## Development ### Get Coupon-Based Promotions with New Script API > The `PromotionMgr.getActiveCustomerPromotions(boolean ignoreCouponCondition)` script API returns all active promotions including coupon-based promotions when ignoreCouponCondition set to true. You can use the returned promotions to expose promotions on your storefront. For example, display a callout message for coupon-based promotions on product detail or product list pages. Although it may seem minor, this update is actually quite significant as it grants us greater flexibility in terms of how we present promotions and campaigns to customers! ### Script API Sort Methods Are Stable > As required by ECMAScript 2019, the B2C Commerce Script API methods Array.sort() and Array.sort(function) are now documented as stable, so equal elements aren’t reordered as a result of the sort. Not much to say about this, but being closer to the Official JS rules is never a bad thing! ## New Ideas Just a gentle reminder to [vote](https://ideas.salesforce.com/s/search#t=All&sort=%40sfcreateddate%20descending&f:@sfcategoryfull=[Commerce%7CB2C%20Commerce]) for your favourite new ideas to be added to the Commerce Cloud roadmap! ## PWA Kit v2.7.3 > - Add support for ES module import statements in ssr.js #1284 > - Support Node 18 and NPM 9. #1265 This is a minor release to ensure this version is compatible with the latest Node version (18), as the older versions will be deprecated soon! [![Node.js 16 end-of-life notice moving the deadline to September 11, 2023.](/a-deep-dive-into-the-23-7-sfcc-release/node-js-16-deprecation-b8d6f02bec_hu_e1c3dc855e5686bc.webp)](node-js-16-deprecation-b8d6f02bec.png) PWA Kit added Node 18 support so teams could move off Node 16 before end-of-life. ## PWA Kit v3.0.0 > We’ve added lots of new features to PWA Kit v3, including: > > - 🔨 Template extensibility: Greatly reduce your project’s code footprint and reduce development toil, cost of ownership, and future upgrade headaches. For more details, see the Template Extensibility guide! > - 🪝 @salesforce/commerce-sdk-react “hooks” integration: Decouples API calls from a project’s implementation, allows API calls to be upgraded as an npm library dependency, and brings along many of the great features (including state management, and others) via TanStack Query. See the the Commerce SDK React docs to get started! > - ⚛️ Major vendor library updates, including support for React 18, Node 16 / 18, Chakra 2, and more. This is a long-awaited [update](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.0.0), bringing many new treats to development. With the new template extensibility options, we can now start overriding just like in SFRA… or at least something that looks like it. Next to that, many updates to libraries and support for the latest stable Node version. One of the libraries is a favourite of mine: [TanStack Query](https://tanstack.com/query/v3/) (or React Query), which makes state management a breeze with APIs. ## Bugfixes Currently, many known issues exist in the state “[Solution in Progress](https://issues.salesforce.com/#sortCriteria=%40sflast_modified_date_external__c%20descending&f[sfcategoryfull]=Commerce%7CB2C%20Commerce&f[sfstatus__c]=Solution%20in%20Progress)”, so let us patiently wait until they are deployed! ## Updated Cartridges & Tools Compiling a list of updates has become more challenging since cartridges are no longer sourced from a single location… ### b2c-tools (v0.18.0) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances and administrative APIs (SCAPI, ODS, etc). It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. - All requests now use a (Version identified) b2c-tools user-agent - JSDoc refactoring and resulting bug cleanup by [@clavery](https://github.com/clavery) in #112 - `checkJs` is on now - set code version to active code version if not found in env vars by [@sandragolden](https://github.com/sandragolden) in #113 --- ## Skills You Need as an SFCC Architect Canonical URL: https://rhino-inquisitor.com/what-skills-do-i-need-as-a-sfcc-architect/ Markdown URL: https://rhino-inquisitor.com/what-skills-do-i-need-as-a-sfcc-architect/index.md Content type: article Published: 2023-06-26T07:02:54Z Updated: 2023-06-27T08:08:03Z Summary: Learn how to successfully transition from developer to architect in Salesforce B2C Commerce Cloud with these tips and strategies. Categories: Architecture, Salesforce Commerce Cloud Tags: architect, sfcc ## Key Takeaways - Outlines the core skills developers need to build before moving into an SFCC architect role - Emphasizes the need for broad platform understanding, cross-system awareness, project leadership, and business alignment - Frames architecture growth as a mix of technical depth, communication, continuous learning, and network building As a [Salesforce Commerce Cloud developer](/preparing-for-the-b2c-commerce-developer-certification/), you may have reached a point in your career where you feel ready to take on a more strategic role and transition into an architecture role. Making the jump from developer to [architect](/the-b2c-commerce-architect-certification/) can be challenging and exciting, but you can successfully make that transition with the right approach and mindset! ## Build a strong foundation in Commerce Cloud development Before you can become an architect, it’s crucial to have a solid foundation in Commerce Cloud development. This includes understanding core concepts such as the [Salesforce Commerce Cloud architecture](/the-salesforce-b2c-commerce-cloud-environment/), using APIs and integrations, and building and maintaining [custom functionality](/preparing-for-the-b2c-commerce-developer-certification/). ## Develop a broad understanding of the platform As an architect, you’ll need to have a comprehensive understanding of the [Commerce Cloud platform](https://www.salesforceben.com/salesforce-b2c-commerce-cloud-architecture-explained/) and how it can be used to solve business challenges. This includes the various features and capabilities of the platform, as well as how to use them to build custom solutions. You’ll be responsible for designing and building custom solutions on the platform and helping shape your organisation’s technology strategy. Here are some specific areas where it can be helpful to develop a deep understanding of the platform: - **Platform architecture:** Understanding the architecture of the Commerce Cloud platform is necessary for building custom solutions that are scalable, reliable, and maintainable. This includes understanding how the platform is organised, how data is stored and accessed, and how the various components work together. - **Platform features and capabilities:** The Commerce Cloud platform offers a [wide range of features and capabilities](https://www.salesforceben.com/salesforce-b2c-commerce-cloud-architecture-explained/) that can be used out-of-the-box or to build custom solutions. As an architect, you’ll need to have a comprehensive understanding of these features and how to use them to create solutions that meet your organisation’s needs. - **Platform integrations:** The Commerce Cloud platform can be integrated with various other systems and data sources, including CRM systems, marketing automation platforms, and more. As an architect, you must understand how to use APIs and other integration technologies to connect the platform to these other systems. - **Best practices for building on the platform:** Certain best practices should be followed when building custom solutions on the Commerce Cloud platform. These best practices can help ensure your solutions are scalable, reliable, and maintainable. As an architect, it’s important to be familiar with these best practices and to apply them when designing and building custom solutions. ## Expand your knowledge beyond (B2C) Commerce Cloud ![An illustration of blurry systems connected in the clouds. It illustrates the path to the architect.](/what-skills-do-i-need-as-a-sfcc-architect/understanding-multiple-systems-c824b11ed0_hu_972da58c4e7e0ca5.webp) Understanding the connections between systems and eliminating the 'blur' may take some time. As an architect, you must understand the various technologies and platforms used to run Commerce Channels. Here are some specific areas where it can be helpful to expand your knowledge: - **Integration options:** As an architect, you’ll likely need to work with various integration technologies to connect the Commerce Cloud platform with other systems and data sources. This could include [APIs](/creating-custom-ocapi-endpoints/), webhooks, and other integration technologies. - **Other platforms and technologies:** Understanding different platforms and technologies that may be relevant to your organisation. For example, if you’re working in the retail industry, you should understand point-of-sale systems, inventory management systems, and other [commonly-used technologies](/salesforce-payments-experience-explained/). By expanding your knowledge beyond Commerce Cloud, you’ll be better equipped to understand the broader context in which your solutions are being built and to design and develop more integrated and holistic solutions. ## Gain experience in project management As an architect, you’ll manage projects and lead development teams. It’s important to have experience in project management, including understanding how to scope and plan projects, track progress and identify issues, and work with cross-functional teams to deliver successful projects. ## Understand the business needs and goals of your organization ![An illustration of a woman architect in front of a planning board.](/what-skills-do-i-need-as-a-sfcc-architect/project-management-illustration-f4cbfcccf1_hu_f85100c3680a3d2d.webp) Having a clear understanding of a business's needs and wants is essential. As an architect, you’ll communicate complex technical concepts to non-technical stakeholders, such as business leaders and merchandisers. It’s critical to be able to clearly and effectively communicate your ideas and solutions and to be able to work well with others to achieve shared goals. Understanding your organisation’s business needs and goals is a core aspect of transitioning from developer to architect in Salesforce Commerce Cloud. As an architect, you’ll be responsible for helping to shape the direction of your organisation’s technology strategy and for designing and building custom solutions that meet the needs of the business. Here are some ways you can understand the business needs and goals of your organisation: - **Work closely with business stakeholders:** Take the time to understand the needs and goals by asking questions to understand better how technology can support and enable objectives. - **Attend meetings and participate in discussions:** Participating in meetings and discussions with business stakeholders can be a great way to learn more about your organisation’s business needs and goals. This could include attending strategy sessions, project meetings, or other discussions where the direction of the business is being discussed. - **Review documentation and reports:** Reading documentation and reports can be a helpful way to better understand your organisation’s business needs and goals. This could include reviewing business plans, marketing materials, financial reports, and other documents that provide insight into the direction of the business. ## Keep up with industry trends The technology field constantly evolves, and an architect must stay current on the latest trends. This could include reading industry blogs and publications, attending [conferences](/community-salesforce-events-and-commerce-cloud/) and events, and participating in online communities and groups. Stay current on industry trends to ensure your organisation uses the best and most effective technologies and approaches. ## Be open to learning and continuous improvement Being open to learning and continuous improvement is an important aspect of being an architect. The field of technology is constantly evolving, and it’s vital for architects to stay up-to-date. Here are some specific ways you can stay open to learning and continuous improvement: - **Seek out new learning opportunities:** You can continue to learn and grow as an architect in many ways. This could include taking online courses or attending workshops, participating in hackathons or other events, or attending conferences and other industry events. You can stay current and relevant in your field by actively seeking out new learning opportunities. - **Collaborate with others:** Collaborating with other professionals can be a great way to learn and grow as an architect. This could include working on side projects with peers, participating in hackathons or other events, or joining a study group or mentorship program. By staying open to learning and continuous improvement, you can ensure that you’re always learning and growing as an architect and can make valuable contributions to your organisation. ## Build a network and seek out mentors ![A group of architects is standing on a cloud, looking at more clouds with a blue sky.](/what-skills-do-i-need-as-a-sfcc-architect/people-meeting-in-the-clouds-fb0c92659f_hu_abe23c13424f9898.webp) It's impossible to have all the answers. It's okay to reach out and seek assistance from others! [Connecting](https://unofficialsfcc.com/) with other architects and industry experts can be a powerful tool to help you navigate the transition ahead. Whether it be through joining industry groups or communities, attending conferences, or seeking out mentors within your organisation, the support and guidance of others can help you achieve your goals. Together, we can build a better future for architecture. ## Taking on the challenge Transitioning from a developer to an architect in Salesforce Commerce Cloud might be challenging, but it’s worth it. With a strong foundation in Commerce Cloud development and expanding your knowledge beyond the platform, you can successfully make the transition. Keep learning and growing! --- ## How to extend Active Data in Salesforce B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/how-to-extend-active-data-in-salesforce-b2c-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/how-to-extend-active-data-in-salesforce-b2c-commerce-cloud/index.md Content type: article Published: 2023-06-19T05:13:10Z Updated: 2023-06-19T05:15:47Z Summary: Learn what Active Data can track in Salesforce B2C Commerce Cloud, where the platform stops, and how far you can extend it safely. Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, technical ## Key Takeaways - Explains how to extend Active Data with custom customer or product attributes in SFCC - Walks through the feed, CSV, import, and verification steps needed to load external behavior data - Shows how custom Active Data can support richer segmentation and dynamic customer groups When working on personalization and segmentation within Salesforce B2C Commerce Cloud, [Active Merchandizing](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/active_merchandising/b2c_active_merchandising.html) is one of the tools to help you along the way. By utilizing data collected automatically by Salesforce B2C Commerce Cloud, you can gain a deeper understanding of your customers’ behavior and tailor campaigns accordingly. For instance, we display a distinctive banner to frequent visitors compared to those who only visit sporadically. ## How is Active Data gathered ![Slide introducing Active Merchandising data collection across commerce channels.](/how-to-extend-active-data-in-salesforce-b2c-commerce-cloud/b2c-active-merchandising-slide-1-9a027d6449_hu_8ea29d41113800b3.webp) ### Storefront When looking at “out-of-the-box” data gathering, we mean all data gathered by analytics that happens on Salesforce B2C Commerce Cloud channels such as: - Storefront Sites such as SiteGenesis / SFRA - Headless OCAPI / SCAPI channels The data collection happens either by client-side tracking (JavaScript - e.g. [`<isobject>`](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/active_merchandising/b2c_add_isobject_tags.html)) for information such as product views or server-side events such as placing orders. ```html // Example of the client-side generated scripts <script type="text/javascript"><!-- /* <![CDATA[ (viewProduct-active_data.js) */ dw.ac._capture({id: "5024501", type: "detail"}); /* ]]> */ // --> </script> ``` PWA Kit / Headless SiteGenesis and SFRA make use of `<isactivedatahead>`, `<isactivedataconext>`, and `<isobject>` tags to insert JavaScript client side to take care of the tracking of information. This is not the case for the PWA Kit or custom headless implementations! A custom implementation will be needed to add support for some of these “standard” Active Data fields again. ## Extend Active Data Besides [all of the standard fields](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/active_merchandising/b2c_creating_feeds.html) available for merchandising, you can extend the model with your own data! This can be particularly useful if you create campaigns/personalisation based on customer actions originating on systems/places outside of Salesforce B2C Commerce Cloud. As for the example flow, we are going to be using visits to a physical store as an example: - Visits in the last 24 hours - Visits in the last 30 days By utilising this information, we can categorise individuals into a specific customer group and create a marketing campaign to target those who make purchases online and offline. ### Step 1: Extend the System Object There are two System Objects that we can extend: - [CustomerActiveData](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_customer_CustomerActiveData.html) - [ProductActiveData](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_catalog_ProductActiveData.html) In this case, we want to extend the Customer Active Data, so we head to: _Administration > Site Development > System Object Types > Customer Active Data \_ On the “_ Attribute Definitions\_” tab, we click “New” to start creating our new attributes. ![Customer Active Data system object with the physicalVisits attribute.](/how-to-extend-active-data-in-salesforce-b2c-commerce-cloud/system-object-active-data-physicalvisits-84071d27a1_hu_cde801f7f1032870.webp) The first extension step is adding the new customer attribute to Active Data. ![Customer Active Data system object with the physicalVisitsMonth attribute.](/how-to-extend-active-data-in-salesforce-b2c-commerce-cloud/system-object-active-data-physicalvisitsmonth-e1e4a24148_hu_a0e6eb38925a9093.webp) A second attribute lets the model capture visits over a monthly time window. As with any attribute, if we want to be able to view them in the Business Manager screens, we should not forget to add them to a new or existing “Attribute Group”. To do this, we go to: _Administration > Site Development > System Object Types > Customer Active Data - Attribute Groups_ Once here, let us create a new group called “Physical Store Traffic”, and assign our two new attributes. ![Attribute group configuration for the Physical Store Traffic fields.](/how-to-extend-active-data-in-salesforce-b2c-commerce-cloud/system-object-active-data-attributegroup-96d35b50eb_hu_91ceeea55339b1f9.webp) Grouping the new fields makes them usable in Business Manager screens and workflows. Attribute Group For many screens, attributes that are not assigned to a group will not be visible or not function properly. ### Step 2: Create the feed definition (CSV) Now that our attribute model has been extended, we need to create a way of importing that data. The first step to allowing CSV import is to create a “feed”. To do this we need to head over to the “Feed Definitions”: _Merchant Tools > Online Marketing > Active Data > Feed Definitions_ In the overview, we see our two types of active data again. Here we will be creating a feed for Customer Active Data. Click the “new” button and create our feed! On the next screen decide on the following fields: - **ID:** The ID of the feed. We will need this in our CSV file later (I have chosen “customer-physicial-store-information-feed”) - **Description:** Free text to describe the purpose of the feed - **Fresh Period:** The value is the number of days after which the data becomes stale if it’s not updated. 0 means the data is never considered stale. ![New Customer Active Data feed definition form.](/how-to-extend-active-data-in-salesforce-b2c-commerce-cloud/new-customer-active-data-feed-ec272e512c_hu_2ebb9eb275f63053.webp) The feed definition is where the external visit data starts entering Active Data. ### Step 3: Create the file to import SFCC understands what we want to send to the system by defining the feed. Now on to creating the file for import! A simple CSV file, with the data that our external system is generating. ```text ‎ customer-physicial-store-information-feed customerNo,custom.physicalVisits,custom.physicalVisitsMonth "W00000001",0,5 "W00000006",1,2 ``` Some things to keep in mind with this file: - The first line should be empty! - The second line is the ID of the feed we defined earlier (it tells SFCC which feed this file is for) - The third line is our header - Custom attributes, like in code, are defined in the header starting with “custom.” ### Step 4: Import the CSV file There are two ways to import this file: - Through the business manager _Merchant Tools > Online Marketing > Active Data > Import & Export_ - Through an automated job using the Job Step “[ImportActiveData](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/jobstepapi/html/api/jobstep.ImportActiveData.html)” ### Step 5: Check that it worked Once the import has been completed we can go and check on a profile if that import succeeded! ![Customer profile showing imported Active Data values in Business Manager.](/how-to-extend-active-data-in-salesforce-b2c-commerce-cloud/customer-active-data-sfcc-c14383fa6a_hu_125efcf1684985e8.webp) After the import runs, the customer profile confirms whether the new data arrived. And with this new addition, we can start creating new [Dynamic Customer Groups](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/active_merchandising/b2c_creating_a_dynamic_customer_group.html), for example! ![Dynamic customer group rule based on recent in-store visits.](/how-to-extend-active-data-in-salesforce-b2c-commerce-cloud/dynamic-customer-group-a8cdefb897_hu_ad83e7faead076e4.webp) Once imported, the new signal can drive customer groups and targeting rules. Active Data Custom feed imports do not show in the Business Manager if the “standard” Active Data fields are empty for a customer or product. You might have to do a manual import on your sandbox to force the visibility. For that reason, I have provided an example file below! ```text ‎ Demandware Customer Active Data customerNo,visitsWeek,visitsMonth,orderValueMonth,productsViewedMonth,productsAbandonedMonth,visitsYear,orders,orderValue,discountValueWithoutCoupon,discountValueWithCoupon,giftUnits,avgOrderValue,sourceCodeOrders,topCategoriesOrdered,productsOrdered,giftOrders "W00000001",0,0,0.0,,,0,1,37.29,0.0,0.0,0.0,37.29,0,,"""8571677"",""8642255"",""8705308""",0 "W00000006",0,0,0.0,,,0,1,18.1,0.0,0.0,0.0,18.1,0,,"""8704168"",""8714462""",0 ``` --- ## Custom TTF fonts in PDF for Salesforce B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/custom-ttf-fonts-in-pdf-for-sfcc/ Markdown URL: https://rhino-inquisitor.com/custom-ttf-fonts-in-pdf-for-sfcc/index.md Content type: article Published: 2023-06-12T08:12:49Z Updated: 2023-06-12T08:13:03Z Summary: Learn how to use custom TTF fonts in Salesforce B2C Commerce Cloud PDF generation so branded documents render correctly in production. Categories: Salesforce Commerce Cloud, Technical Tags: pdf, sfcc, technical ## Key Takeaways - Explains how to package and register custom TTF fonts for PDF generation in SFCC - Shows the jsPDF conversion, loading, and runtime usage steps needed to render branded fonts - Warns to keep font payloads lean so generated PDFs and email attachments stay manageable A while ago, I wrote two articles on how to get PDF magic to work within SFCC: - [PDF Generation](/pdf-and-salesforce-commerce-cloud-b2c/) - [How to send PDF files as attachments in e-mails](/mail-attachments-in-b2c-commerce-cloud/) As this is a common topic that many projects may encounter, I have chosen to write a third article to conclude the series. Companies need to have a consistent and recognisable identity that is reflected in all their communication channels, even in attachments such as PDFs. A personalised font that complements the brand’s aesthetic can help achieve this goal. But how do you add them to a PDF? Let us find out! ## Only TTF To my knowledge, jsPDF solely supports TTF fonts. This information can be found in the “Read Me” section of the documentation: > The 14 standard fonts in PDF are limited to the ASCII-codepage. If you want to use UTF-8 you have to integrate a custom font, which provides the needed glyphs. **jsPDF supports .ttf-files**. So if you want to have for example Chinese text in your pdf, your font has to have the necessary Chinese glyphs. So, check if your font supports the wanted glyphs or else it will show garbled characters instead of the right text. ## Fonts as base64 To use a custom font, they need to be part of our code-base as a base64 encoded string. Luckily, jsPDF has provided a tool to convert your TTF files to a jsPDF-compatible string. [Open the jsPDF font converter](https://rawgit.com/MrRio/jsPDF/master/fontconverter/fontconverter.html) I could explain how to use this tool elaborately, but luckily [someone has already done this for me](https://www.devlinpeck.com/tutorials/jspdf-custom-font)! ## Ready to go ### Add the file to your codebase The tool described above will spew out a JavaScript file that you can add to your code-base with some small modifications. An example of such files have been added to my GitHub: - [angin-senja-normal.js](https://github.com/taurgis/salesforce-commerce-cloud-libraries/blob/master/cartridges/jsPDF/fonts/angin-senja-normal.js) - [broc-webfont-normal.js](https://github.com/taurgis/salesforce-commerce-cloud-libraries/blob/master/cartridges/jsPDF/fonts/broc-webfont-normal.js) Add your font JS file to the cartridge and folder that makes the most sense to you! ```js module.exports = function (jsPDFAPI) { var font = 'BASE64 HERE'; var callAddFont = function () { this.addFileToVFS('broc-webfont-normal.ttf', font); this.addFont('broc-webfont-normal.ttf', 'broc-webfont', 'normal'); }; jsPDFAPI.events.push(['addFonts', callAddFont]); }; ``` ### Load in the font Next we need to expand [main.js](https://github.com/taurgis/salesforce-commerce-cloud-libraries/blob/master/cartridges/jsPDF/main.js) to load in the fonts. ```js var jsPDF = require('./jsPDF'); // libs require('./libs/ttffont')(jsPDF.API); // plugins require('./plugins/addImage')(jsPDF.API); require('./plugins/total_pages')(jsPDF.API); ... // Custom Fonts require('./fonts/angin-senja-normal')(jsPDF.API); require('./fonts/broc-webfont-normal')(jsPDF.API); module.exports = jsPDF; ``` As with any other script file, it’s entirely within your control to override it on your cartridge. It’s a given that you won’t be needing those two sample fonts anyway! ### Use your font After loading your font, it’s time to put it to use! Simply add the following code in your controller or job. ```js var JSPDF = require('jsPDF'); var doc = new JSPDF(); doc.setFontSize(25); doc.setFont('broc-webfont', 'normal'); doc.text(35, 10, 'Forward loves jsPDF'); response.writer.print(doc.output()); ``` The first parameter of the setFont function is the font name defined in the initial JavaScript file we generated using the font conversion tool. If they do not match, it will not work! But if set up correctly, you should get a result like this (an example from the [GitHub repository code](https://github.com/taurgis/salesforce-commerce-cloud-libraries/blob/master/cartridges/plugin_testlibraries/cartridge/controllers/jsPDF.js)): ![Generated PDF preview showing multiple custom fonts rendered in the output.](/custom-ttf-fonts-in-pdf-for-sfcc/custom-font-result-df8aa2e64b_hu_6fe376387cfd4d9c.webp) Figure 1: Generated PDF preview showing multiple custom fonts rendered in the output ## Something to keep in mind To optimise file size, it’s important to limit the use of excessively large fonts and avoid loading unnecessary ones. Even though you can incorporate all the different bold or italic font styles, it’s not required if you only use a few. This will prevent the PDF from being unnecessarily bloated. This is especially important if you plan to send your files out by e-mail, as there are limitations to how big your files can be (depending on the providers on both the sending and receiving end ). --- ## Commerce Cloud t-shirts on #shirtforce Canonical URL: https://rhino-inquisitor.com/commerce-cloud-t-shirts-on-shirtforce/ Markdown URL: https://rhino-inquisitor.com/commerce-cloud-t-shirts-on-shirtforce/index.md Content type: article Published: 2023-06-05T06:43:00Z Updated: 2023-06-06T08:54:49Z Summary: For a long time shirtforce only had core platform-related t-shirt options, until now! To help a charity I decided to make some designs! Categories: Community Tags: ohana, sfcc, shirtforce ## Key Takeaways - Explains how Commerce Cloud shirt designs on Shirtforce support charitable giving - Shares the backstory behind several Commerce-themed community t-shirt designs - Encourages readers to contribute new ideas and help choose future causes [shirtforce](https://shirtforce.org/) was created as a community project, supplying (hopefully) humorous t-Shirt designs to for folk in the tech industry, primarily focused at those in the Salesforce ecosystem, and at the same time providing a way to donate money to good causes. If you read the hashtag wrong, I don’t blame you! Just have a look at [the FAQ on the #shirtforce website](https://shirtforce.org/faq/). Until last year, no Commerce Cloud-related options were available. And this is because [it isn’t known within the Commerce Cloud community](/the-state-of-ohana-for-salesforce-commerce-cloud/). A week into the war in Ukraine (2022), I looked for options to donate and help, and my “[penny](https://www.linkedin.com/in/toddhalfpenny/)” dropped! There already is a Salesforce-related charity option. Why not hop on the same wagon rather than re-inventing the wheel? And with this, we have something permanent rather than a one-time donation. Let’s not waste time and get straight to the designs and their backstory. ## Keep Calm And Go Headless ![A headless-themed red t-shirt.](/commerce-cloud-t-shirts-on-shirtforce/keep-calm-and-go-headless-6e775cd9c3_hu_a6fe22b83f07bef0.webp) The headless shirt turns one of the ecosystem's favorite architecture debates into merch. - [Get it now](https://my-store-5a6a56.creator-spring.com/listing/salesforce-ohana-rocks) Most people will have already seen a similar text on an image or T-Shirt over the years. In this case, we just changed the subject to “Headless.” Headless has become more prominent in the Salesforce Commerce space in the past two to three years. Especially with the [acquisition of Mobify](https://www.digitalcommerce360.com/2020/09/09/salesforce-agrees-to-buy-headless-commerce-tech-firm-mobify/), this has gotten quite the boost. And with the option for hybrid (or phased) deployments…another idea popped into my head. ## Hybrid Deployment Theory ![A horse-printed t-shirt.](/commerce-cloud-t-shirts-on-shirtforce/hybrid-deployment-theory-491c6dcca5_hu_f1292279dd3881b7.webp) Hybrid Deployment Theory was the joke that deserved its own shirt. - [Get it now](https://my-store-5a6a56.creator-spring.com/listing/hybrid-deployment-theory) Based on the iconic album “[Hybrid Theory](https://en.wikipedia.org/wiki/Hybrid_Theory)” by Linkin Park, the design represents the album’s title. Referencing the Rhino Engine and linking it to a “hybrid deployment”, it truly is a Commerce Cloud design. So, if you’re a Linkin Park fan or appreciate great music, I highly recommend adding this must-have t-shirt to your collection. ## #DynamiteDev ![A blue shirt with the text '#DynamiteDev'](/commerce-cloud-t-shirts-on-shirtforce/dynamite-dev-3f8e65854b_hu_c81eeab172661930.webp) Dynamite Dev is for the people who enjoy shipping boldly and cleaning up later. - [Get it now](https://teespring.com/dynamitedev?pid=389&cid=100020) Without our developers, how would we ever build an eCommerce channel that matches the brand’s look and feel? With this design, we celebrate how amazing they are! ## #BadassBA ![A blue t-shirt with the text '#BadassBA'](/commerce-cloud-t-shirts-on-shirtforce/badass-ba-c2f0429cdd_hu_3db6fa70169b5caa.webp) Badass BA gives business analysts equal billing in a developer-heavy culture. - [Get it now](https://my-store-5a6a56.creator-spring.com/listing/badassba) Inspired by [Vanessa Grant](https://twitter.com/rlvanessagrant), we designed a logo celebrating our Badass Business Analysts! Where would any project be without them? This design is not specifically for Salesforce B2C Commerce Cloud, but it applies! ## Breaking Prod ![A green t-shirt with the text 'Breaking Prod' in the style of 'Breaking Bad'](/commerce-cloud-t-shirts-on-shirtforce/breaking-prod-16547b5665_hu_82b208021de03c23.webp) Breaking Prod is the punchline every release team understands immediately. - [Get it now](http://teespring.com/en-GB/breaking-prod) With great power comes great responsibility. And one of the things any developer, merchandiser, or architect can do … is break production! If you haven’t recognised where this design comes from, you might have to add [another show](https://en.wikipedia.org/wiki/Breaking_Bad) to your “binge-watch” list. ## Tip of the iceberg There are many more designs like these, and new designs often make their way to the [site](https://shirtforce.org/)! So be sure to follow [#shirtforce](https://twitter.com/shirtforceOrg)! ### Selecting a cause Shirtforce polls for these every few months on what charity to donate to, and it’s a great way to give back to the community. All you have to do is follow the [Twitter account](https://twitter.com/shirtforceOrg), submit a charity that you feel passionate about and encourage others to vote for it (when the time comes). It’s a simple but impactful way to make a difference and help those in need. ### Do you have a great idea or design Are you feeling creative and have a great idea for a t-shirt design? We would love to see it! We are always looking for fresh and exciting designs to add to our collection. So, if you have something in mind, don’t hesitate to send it over. We can’t wait to see what you come up with! --- ## The Salesforce B2C Commerce Cloud URL: Cracking the Code Canonical URL: https://rhino-inquisitor.com/sfcc-url-cracking-the-code/ Markdown URL: https://rhino-inquisitor.com/sfcc-url-cracking-the-code/index.md Content type: article Published: 2023-05-29T07:12:19Z Updated: 2023-05-29T11:16:52Z Summary: It should be no secret that a URL is a vital part of any website In this article, we will dissect and explain the different parts of a Salesforce B2C Categories: Salesforce Commerce Cloud, Technical Tags: headless, sfcc, technical ## Key Takeaways - Breaks down the parts of an SFCC URL, including protocol, domain, path, and query parameters - Shows how to access the same URL information in classic SFCC controllers and in React-based composable storefront code - Acts as a lightweight cheat sheet for developers working across monolithic and headless storefront patterns It should be no secret that a URL is a vital part of any website. In this article, we will dissect and explain the different parts of a Salesforce B2C Commerce Cloud URL and provide code examples on how to access this information [in an SFCC controller and React using the useLocation() hook](/what-does-the-composable-storefront-mean-for-sfcc-developers/). ## The URL Structure ![Anatomy of a B2C Commerce Cloud URL](/sfcc-url-cracking-the-code/anatomy-of-a-url-33092362d8_hu_a7b0d7fb4bca528c.webp) A typical Salesforce B2C Commerce Cloud URL consists of the following components: 1\. Protocol (https only) 2. Domain & Subdomain (your site’s domain) 3. Path (Including the Pipeline Name in non-SEO URLs) 5. Query Parameters (optional, used to pass additional data to a server-side controller or React component) Example URLs: ```text https://www.example.com/on/demandware.store/Sites-MySite-Site/en_US/MyPipeline-MyAction?param1=value1¶m2=value2 ``` ```text https://www.example.com/my-site/en_US/route?param1=value1¶m2=value2 ``` ## Protocol The protocol is the foundation of how data is transmitted across the internet. In a Salesforce B2C Commerce Cloud URL, the protocol is [HTTP](https://en.wikipedia.org/wiki/HTTP) (Hypertext Transfer Protocol) or [HTTPS](https://en.wikipedia.org/wiki/HTTPS) (Hypertext Transfer Protocol Secure). HTTP is the standard protocol for transmitting data between a web server and a browser, while HTTPS is a more secure version that uses encryption to protect the data being sent. [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/) only allows HTTPS and has blocked the use of HTTP for quite a few years now. When working locally with the PWA Kit, HTTP is used, however. ```text // SFRA - SiteGenesis request.getHttpProtocol(); // PWA KIT Client Side window.location.protocol // PWA Kit Server Side (getProps) req.protocol ``` ## Domain & subdomain ```text // SFRA - SiteGenesis request.getHttpHost(); // PWA KIT Client Side window.location.hostname // PWA Kit Server Side (getProps) req.hostname ``` The [domain](https://en.wikipedia.org/wiki/Domain_name) is the unique address of your website on the internet. It is the identifier that users will type into their browser to access your site, and search engines also use it to index. In a Salesforce B2C Commerce Cloud URL, the domain represents your site’s custom domain or a subdomain provided by Salesforce. Choosing a domain that is easy to remember and represents your brand is crucial, as it plays a vital role in your site’s visibility and credibility. ## Path ```js // SFRA - SiteGenesis request.getHttpPath(); // PWA KIT import {useLocation} from 'react-router-dom' const { pathname } = useLocation() ``` The “[path](https://en.wikipedia.org/wiki/URL)” of a URL refers to the hierarchical structure of a website that designates the specific location of a resource, such as a web page, an image, or a file, on the web server. The path helps users and search engines navigate and understand the organisation of a website’s content. It is an essential part of the URL, following the domain name and starting with a forward slash (/). A URL path is typically organised into multiple segments, separated by forward slashes. Each segment represents a level in the site’s hierarchical structure. The leftmost segment is the highest level, and the following segments represent subdirectories or resources within the higher-level directories. For example, in the URL `https://www.example.com/blog/2021/post-title`, the path is `/blog/2021/post-title`. This path indicates that the specific web page is located within the “2021” subdirectory of the “blog” directory on the server. A well-structured and descriptive URL path can improve a website’s search engine optimization (SEO) and user experience (UX) by making it easier for users and search engines to understand the relationship between different pages and resources on the site. ## Query Parameters ```js // SFRA - SiteGenesis request.getHttpParameterMap(); request.getHttpParameters(); request.getHttpQueryString(); // PWA KIT import {useLocation} from 'react-router-dom' const { search } = useLocation() ``` [Query parameters](https://en.wikipedia.org/wiki/Query_string) are optional components of a Salesforce B2C Commerce Cloud URL that are used to pass additional data to a server-side controller. They are key-value pairs that are appended to the end of the URL, starting with a question mark (?) and separated by an ampersand (&). Query parameters can transmit data such as filters, search terms, or pagination information. You can create dynamic and interactive user experiences by utilising query parameters and optimising your site’s performance. ## Not rocket science Fortunately, obtaining this information is not rocket science, and it can be easily accessed. But having a cheat sheet can be quite helpful, don’t you think? --- ## A look at the Salesforce B2C Commerce Cloud 23.6 release Canonical URL: https://rhino-inquisitor.com/a-look-at-the-salesforce-b2c-commerce-cloud-23-6-release/ Markdown URL: https://rhino-inquisitor.com/a-look-at-the-salesforce-b2c-commerce-cloud-23-6-release/index.md Content type: article Published: 2023-05-25T06:26:10Z Updated: 2023-05-25T06:26:10Z Summary: The weather (at least here) is giving us more sunshine, so let us shine a light on the next Salesforce B2C Commerce Cloud release! Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc ## Key Takeaways - Highlights 23.6 changes that affect search performance, SLAS, and eCDN controls - Warns teams to review outbound integrations after hostname verification changes - Points to new CDN firewall and logpush capabilities worth enabling and testing The weather (at least here) is giving us more sunshine, so let us shine a light on the next Salesforce B2C Commerce Cloud release! This time we look at the [June 2023 (23.6) release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_23_6_release.htm&type=5)! Are you interested in last month’s release notes? [Read the 23.5 release notes](/a-look-at-the-sfcc-23-5-release/)! ## Enhance Storefront Search Scale and Performance > Enhance the scale and performance of storefront search for keyword search and product browsing with the new B2C Commerce search settings option. Improve page load times for large product catalogs when processing search results that exceed a configurable threshold. Shoppers get quicker results when performing a keyword search, refinement calculation, product grouping, sorting, and category browsing. For example, if your storefront doesn’t use search refinement counts in the refinement bar, a setting is available to improve refinement calculation and search and category page load times. **How:** To activate the new search settings, contact Salesforce Customer Support or work with your Technical Account Manager and Customer Success Group representatives. Salesforce recommends that you test the new functionality on a development or dedicated test instance before enabling them on a staging or production environment. If you have been in the eco-system for a while, you may have noticed that the built-in search engine did not get much love (visibly) in the past few years. Looking at the past two months, that appears to have changed! Your site’s performance is a very important aspect, and seeing that more options to fine-tune search to our specific needs is excellent! But what does Salesforce mean by “large product catalogs”? Well, that means more than 1 million products in your catalog. But there are still a few questions that I have that are open on this topic: - Does this impact OCAPI/SCAPI performance as well? - If you have less products, is it still a feature you would want to activate? Are there benefits? - What options are there? I hope more information will pop up in the documentation soon, as this is a welcome improvement! ## Platform ### Validate Hostnames for Certificates > B2C Commerce now validates the hostname in the HTTPS certificate for outgoing connections. Validating the hostname eliminates the chance that a connection is made to the wrong host. To identify failed verifications, search the logs with the keyword phrase: Host name verification failed. This validation can be disabled on specific requests using the new setHostNameVerification method on the HTTPClient script API. **Time to re-evaluate all your third-party integrations**! An extra validation step has made its way to the HTTPClient. Luckily you have a “quick fix” available: [disabling it through code](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_net_HTTPClient.html#dw_net_HTTPClient_setHostNameVerification_Boolean_DetailAnchor). ## OCAPI & SCAPI ### Shopper Login (SLAS) > - Updated the getTrustedAgentAccessToken endpoint to make the agent\_id parameter optional. > - Updated the SLAS Admin UI with specific error messaging for issues with logging into Account Manager. > - Private clients now support `grant_type=authorization_code` in addition to `grant_type=authorization_code_pkce`. > - Removals of customer records in B2C Commerce are now synchronized with SLAS. If a customer record is deleted in B2C Commerce, this change is recognized by SLAS. > - Infrastructure and scale improvements to handle higher transaction volume for the upcoming holiday season. > - NEW SLAS-Marketing Cloud SMS for Passwordless login is ready! See Passwordless Login with SMS to get started. > - Improved exception handling for invalid passwords. Returns 400 with clear messaging. > - The /userinfo endpoint now handles extended UT\_08 character set. > - The /userinfo endpoint now allows trusted system on behalf (TSOB) access tokens. > - Security library updates. > - Deprecated the CredQuality API. > - Improved Guest Shopper validation to allow B2C Commerce IDP origin for session bridge. > - Session Bridge: fixed 500 server error on incorrect hint. SLAS Admin UI: Fixed issues related to Tenant ID format check at browser level. No month goes by without new additions to the SLAS service. As the Composable Storefront (and hybrid deployments) get more traction, this service needs to get some “love” and provide the flexibility brands need. A significant change here is that there is now an automatic synchronisation of deleted customers to SLAS, which required [manual API calls](https://developer.salesforce.com/docs/commerce/commerce-api/references/slas-admin?meta=deleteShopper) before. And another is the [Marketing Cloud integration for passwordless login via SMS](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-passwordless-sms.html)! If you are a multi-cloud customer, this is one to look at (if you have use cases where this makes sense, such as in-store kiosks where someone doesn’t just want to enter their password in public)! ### Set Up Custom Firewall Rules with the CDN-API > To enable better rule enforcement, the B2C Commerce CDN-API now supports custom firewall rules. The API also provides custom firewall controls to target traffic from a specific path or user agent. Custom firewall rules is a superset of existing firewall rules, it will replace the existing firewall rules for IP, ASN, Geo, the existing firewall rules will be deprecated by February 1, 2024. All firewall rules will be deprecated by February 1, 2024. Have you been desperate for more control of the eCDN firewall? It seems Salesforce has some good news for you! With this new feature, you can block or challenge traffic [based on dynamic rules you control](https://developer.salesforce.com/docs/commerce/commerce-api/guide/cdn-zones-custom-rules.html)! Cloudflare Documentation Be sure to check out the [official Cloudflare documentation](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/)! ### Set Up CDN Logpush > You can use the CDN-API to store firewall events and CDN logpush for HTTP requests in your S3 bucket for immediate log visibility. The API supports visibility of HTTP requests and firewall events in the CDN logs. The logs are also available for eCDN implementations. Getting access to all of the eCDN logs has been a “drag”. Doing it manually via the Business Manager or API was quite the time-sink to set up. With [this new system](https://developer.salesforce.com/docs/commerce/commerce-api/guide/cdn-zones-logpush.html), it is possible to push batches of up to 100.000 records to an Amazon S3. ## New Ideas Some great new ideas popped up on the ideaexchange, [be sure to give it a gander and vote](https://ideas.salesforce.com/s/search#t=All&sort=%40sfcreateddate%20descending&f:@sfcategoryfull=[Commerce%7CB2C%20Commerce])! ## PWA Kit v2.7.1 A [“smaller” release](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v2.7.1) made its way to the Composable Storefront the past month with some nice new updates: Several changes and improvements have been made in the latest release notes. Here’s a summary of the most significant updates: 1. **Phased launch with optional session bridge call:** An optional session bridge call has been added to the login process, allowing for a smoother phased launch of new features. 2. **Product-list refinements:** Enhancements have been made to product-list handling, including support for multiple types, improved isChecked functionality, and better management of query parameters. 3. **Fixes for multi-value query parameters and basket issues:** This release addresses issues with multi-value query parameters being lost and makes the mergeBasket conditional more robust, resolving basket problems when a new account is created. 4. **Security package updates and bug fixes:** Several security package updates have been implemented, along with various bug fixes to improve overall system stability. 5. **Mobile-friendly phone number input:** The phone number field type has been changed to bring up a numeric keyboard on mobile devices, making it more user-friendly. 6. **Address listing improvements:** Preferred addresses are now listed first, streamlining the user experience when selecting shipping or billing addresses. 7. **Modal handling and cart functionality:** The update prevents modals from opening when adding an item to the cart fails, ensuring a smoother shopping experience. 8. **Performance improvements and fixes:** Various performance enhancements have been made, including webpack build improvements, fixing Page Designer ImageWithText Link component issues, and addressing a local dev memory leak issue in the retail react app. 9. **File handling and static file serving:** Fixes have been implemented for file collisions between client-side and server-side JavaScript files and improvements to static file serving. ## Updated Cartridges & Tools ### Sandbox Launchd (v1.0.0) - [https://github.com/sfccdevops/sandbox-launchd](https://github.com/sfccdevops/sandbox-launchd) > Automatically Start & Stop your Sandbox when your macOS device Boots, Shuts Down, Wakes & Sleeps. Another new project by Peter Schmalfeldt to make us even more lazy by booting and shutting down our sandboxes automatically! ### b2c-tools (v0.17.0) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances and administrative APIs (SCAPI, ODS, etc). It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. - support local/offline page designer page export in cli - migration script standard input support / logging levels ### plugin\_slas (v7.0.0) - [https://github.com/SalesforceCommerceCloud/plugin\_slas](https://github.com/SalesforceCommerceCloud/plugin_slas) > This cartridge extends authentication for guest users and registered shoppers using the Shopper Login and API Access Service (SLAS). A significant update has happened to SLAS, with too many changes to note down! If you use this plugin or plan to implement it, [look at this release](https://github.com/SalesforceCommerceCloud/plugin_slas/releases/tag/7.0.0)! ### SFRA Webpack builder (v3.4.1) - [https://github.com/SalesforceCommerceCloud/sfra-webpack-builder](https://github.com/SalesforceCommerceCloud/sfra-webpack-builder) > Webpack can be cumbersome to setup, especially in multicartridge projects for SFRA. This plugin let you bundle all your js, scss and jsx files out of the box. A bugfix release, so nothing to note here. --- ## B2C Commerce Architect Certification Guide Canonical URL: https://rhino-inquisitor.com/the-b2c-commerce-architect-certification/ Markdown URL: https://rhino-inquisitor.com/the-b2c-commerce-architect-certification/index.md Content type: article Published: 2023-05-22T07:18:54Z Updated: 2023-05-22T07:19:06Z Summary: Prepare for the Salesforce B2C Commerce Architect certification with a guide to exam domains, study priorities, and practical preparation. Categories: Architecture, Salesforce Commerce Cloud Tags: certification, sfcc ## Key Takeaways - Breaks down the B2C Commerce Architect exam by domain and highlights what each section is really testing - Curates study resources across Trailhead, official documentation, and related Rhino Inquisitor articles - Frames the certification as achievable with targeted preparation, especially for architects who need broader Business Manager and launch knowledge Congratulations on your decision to become a [certified Salesforce B2C Commerce Architect](https://trailhead.salesforce.com/en/credentials/b2ccommercearchitect)! Obtaining certification is an excellent way to validate your knowledge and ensure that it meets Salesforce’s high standards. While practical experience and training can provide a strong foundation, preparing specifically for the exam never hurts. In this article, we will review the exam guide and highlight the areas you may want to focus on to increase your chances of passing the exam on your first attempt. ## Design/Discovery (29%) The Official List - Given a customer’s business requirement, create a technical specification that accurately reflects the business requirement. - Given business and technical requirement details, create standard technical artifacts that are complementary and accurate to the design and project needs. - Given business and technical requirement details, review implementation specifications for solutions, future growth, and gap analysis to stakeholders and provide analysis to defend if necessary. - Given systems integration requirements & technical details, evaluate LINK cartridges applicable versions, 3rd-Parties’ technical specifications, and API documentation for integrations. - Given the systems that are interacting with the platform, evaluate the integration points, data type and volume, data migration approach, and diagram the system architecture. Capturing business requirements and providing the best solution for the business (or providing multiple - with pros and cons) is a crucial skill you need as an architect. Using the [knowledge of the platform](/the-salesforce-b2c-commerce-cloud-environment/) and what it can and cannot do, is imperative to make the right decisions. And if the platform cannot do a particular feature, what tools to use (third-party or custom-built) in that situation. - [Trailhead: Salesforce Commerce Cloud Architect Roles: Quick Look](https://trailhead.salesforce.com/content/learn/modules/commerce-cloud-architect-roles-quick-look?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Commerce Cloud Features](https://trailhead.salesforce.com/content/learn/modules/cc_cccapability?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Client Analysis](https://trailhead.salesforce.com/content/learn/modules/cc-solution-design-client-analysis?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Architecture of Salesforce B2C Commerce](https://trailhead.salesforce.com/content/learn/modules/architecture-of-commerce-cloud-digital?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Project Documentation for Salesforce B2C Commerce Functional Architects](https://trailhead.salesforce.com/content/learn/modules/cc-create-functional-consulting-documents?trailmix_creator_id=auser1343&trailmix_slug=arc300-salesforce-b2c-commerce-architect-classwork) - [Trailhead: Project Documentation for Salesforce B2C Commerce Technical Architects](https://trailhead.salesforce.com/content/learn/modules/b2c-project-docs-for-technical-architects?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Functional Consulting](https://trailhead.salesforce.com/content/learn/modules/cc-functional-consulting?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Functional Consulting Strategy](https://trailhead.salesforce.com/content/learn/modules/b2c-functional-consulting-strategy?trailmix_creator_id=auser1343&trailmix_slug=arc300-salesforce-b2c-commerce-architect-classwork) - [Trailhead: Salesforce Architecture Diagrams: Quick Look](https://trailhead.salesforce.com/content/learn/modules/archdia?trailmix_creator_id=auser1343&trailmix_slug=arc300-salesforce-b2c-commerce-architect-classwork) - [Trailhead: Architecture of Salesforce B2C Commerce](https://trailhead.salesforce.com/content/learn/modules/architecture-of-commerce-cloud-digital?trailmix_creator_id=auser1343&trailmix_slug=arc300-salesforce-b2c-commerce-architect-classwork) - [Trailhead: Salesforce B2C Commerce Import & Export](https://trailhead.salesforce.com/content/learn/modules/b2c-import-export?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Einstein Product Recommendations for Commerce Cloud](https://trailhead.salesforce.com/content/learn/modules/cc-einstein-product-recommendations?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Storefront Search](https://trailhead.salesforce.com/content/learn/modules/b2c-storefront-search?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Storefront Sorting Rules](https://trailhead.salesforce.com/content/learn/modules/b2c-storefront-sorting-rules?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Smarter Search with Commerce Cloud Einstein](https://trailhead.salesforce.com/content/learn/modules/cc-einstein-smarter-search?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Campaigns and Promotions](https://trailhead.salesforce.com/content/learn/modules/b2c-campaigns-and-promotions?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [PLC: B2C Commerce: Frontend Architectural Options](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=3jgpi8TpMhWnKj6DIFXuJtx1QeFdL3j7lMgxipymXIyYFWYx29Pu5%2FVKHk1GSGs1) - [Webinar: Storefront Reference Architecture (SFRA) overview](https://salesforce.vidyard.com/watch/rgvLUk97rk1Kg58nYVcuy9?) - [Let’s GO-LIVE: The Salesforce B2C Commerce Cloud Environment](/the-salesforce-b2c-commerce-cloud-environment/) - [Salesforce (Commerce) Payments: Payment Integration Simplified](/salesforce-payments-experience-explained/) - [The Salesforce B2C Commerce Cloud Entity-Relationship model explained](/salesforce-b2c-commerce-cloud-erd/) - [AI (Einstein) in Salesforce B2C Commerce Cloud](/ai-einstein-in-salesforce-b2c-commerce-cloud/) - [What is OCI (Omnichannel Inventory)](/what-is-oci-omnichannel-inventory/) - [B2C Commerce: LINK Certification Guide](https://help.salesforce.com/s/articleView?id=000388942&language=en_US&type=1) - [B2C Commerce: Einstein](https://help.salesforce.com/s/articleView?id=cc.b2c_commerce_cloud_einstein.htm&type=5&language=en_US) - [B2C Commerce: Release Notes](https://help.salesforce.com/s/articleView?id=sf.b2c_rn_release_notes.htm&type=5&language=en_US) - [B2C Commerce: Videos](https://help.salesforce.com/s/articleView?id=cc.b2c_videos.htm&language=en_US&type=5) - [Account Manager](https://help.salesforce.com/s/articleView?id=cc.b2c_account_manager_overview.htm&type=5&language=en_US) - [Control Center](https://help.salesforce.com/s/articleView?id=cc.b2c_cc.htm&type=5&language=en_US) ## Build (19%) ![A group of people sitting at a table with laptops.](/the-b2c-commerce-architect-certification/b2c-commerce-architect-build-1e15c905c7_hu_91337c140f9a7951.webp) The Official List - Given a set of technical specifications, evaluate the implementation process to ensure the solution meets the business requirements. - Given an implementation, validate that best practices are followed and guide their usage so that the end solution is secure, performant, and modular. - Given a complex issue or set of issues, guide a development team in the steps toward resolution. - Given an implementation and known KPIs, support in load testing, evaluate results, and ensure the implementation meets expectations. - Given a collection of cartridges and data, define a process to compile and deploy to Salesforce environments. Once all the requirements have been captured and we have worked out a design for the project(s) - it is time to start building! But does what we are building comply with the original requirements? Or what if we hit a wall in the middle of the implementation? How do we handle these kinds of situations? This is another key skill of the B2C Commerce Architect! - [Trailhead: Salesforce B2C Commerce Project Management](https://trailhead.salesforce.com/content/learn/modules/cc-project-mgmt?trailmix_creator_id=auser1343) - [Trailhead: Salesforce B2C Commerce Trust Site](https://trailhead.salesforce.com/content/learn/modules/b2c-commerce-trust-site?trailmix_creator_id=globantuniveristy&trailmix_slug=salesforce-commerce-cloud-architecture) - [Trailhead: Salesforce B2C Commerce Storefront Security Strategies](https://trailhead.salesforce.com/content/learn/modules/b2c-storefront-security-strategies?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Roles & Permissions](https://trailhead.salesforce.com/content/learn/modules/b2c-configure-users-roles-permissions?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Tools & Resources for Salesforce B2C Commerce Developers](https://trailhead.salesforce.com/content/learn/modules/b2c-developer-resources-and-tools?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce On-Demand Sandboxes](https://trailhead.salesforce.com/content/learn/modules/b2c-on-demand-sandbox?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Build Processes and Unit Tests for Salesforce B2C Commerce Technical Architects](https://trailhead.salesforce.com/content/learn/modules/b2c-build-processes-and-tests-for-technical-architects?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Cartridges](https://trailhead.salesforce.com/content/learn/modules/b2c-cartridges?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Storefront Implementation](https://trailhead.salesforce.com/content/learn/modules/b2c-implement-functional-solution?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Storefront Localization](https://trailhead.salesforce.com/content/learn/modules/b2c-localization) - [Secure Coding in Salesforce B2C Commerce Cloud](/secure-coding-in-salesforce-b2c-commerce-cloud/) - [B2C Commerce: Security Guide](https://help.salesforce.com/s/articleView?id=cc.b2c_commerce_security_guide.htm&type=5&language=en_US) - [Data Protection & Privacy](https://help.salesforce.com/s/articleView?id=cc.b2c_data_protection_and_privacy.htm&type=5&language=en_US) ## Monitoring/Troubleshooting (14%) The Official List - Given an implementation, evaluate the end-to-end needs for custom logging configuration, the ability to leverage Log Center, and investigate other tools required to identify potential and existing issues for governance, trust, and best practices. - Given an implementation performance issue, demonstrate the ability to identify and address existing and potential performance issues, including quota violations, cache utilization, service timeouts, and optimization opportunities. - Given an implementation issue, demonstrate the ability to identify root causes and recommend solutions. - Given an implementation, evaluate and adjust the system proactively to ensure a healthy, scalable system for current and future business operational needs. Keeping an eye out on what you build is not just important, it is crucial to have any project be successfully launched. Using standard tools out-of-the-box available and third-party solutions, this is something that can be easily achieved. - [Trailhead: Salesforce B2C Commerce Cache for Performance & Scalability](https://trailhead.salesforce.com/content/learn/modules/b2c-implement-cache?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Site Performance Analysis and Monitoring](https://trailhead.salesforce.com/content/learn/modules/b2c-performance-analysis-post-launch-monitor?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Reports & Dashboards](https://trailhead.salesforce.com/content/learn/modules/b2c-reports-and-dashboards?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Promotions Dashboards](https://trailhead.salesforce.com/content/learn/modules/salesforce-b2c-commerce-promotions-dashboards?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Sales and Products Dashboards](https://trailhead.salesforce.com/content/learn/modules/b2c-sales-and-products-dashboards?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Leveraging Server-Side Caching to Improve SFCC REST API Speed](/caching-rest-apis-in-sfcc/) - [How to change the code Compatibility Mode in Salesforce B2C Commerce Cloud](/how-to-change-the-code-compatibility-mode-in-salesforce-b2c-commerce-cloud/) - [Reports & Dashboards - How to Set Up Access](https://salesforce.vidyard.com/watch/qf6QPehudWEP4RJQvz7kRB?) ## Integrations and Customizations (22%) The Official List - Given a business requirement of integrating with a 3rd-Party web service identify what protocol (SOAP/REST) and what approach (real-time vs. batch processing) should be used and then apply all security strategies and best practices that SFCC can support. - Given a set of batch process requirements, leverage the productized Job Framework for batch process integration. - Given a list of third-party LINK cartridge integrations, identify “legacy” LINK cartridges that are still using Pipelines and define an integration approach with Controllers. - Given a set of real-time integration requirements, leverage the productized Service Framework for real-time integration. Salesforce B2C Commerce Cloud has many features out of the box, but it can’t do everything. Any project (or at least the majority) must deal with third-party integrations. Knowing where to look and how to monitor these integrations is crucial as a B2C Commerce Architect. - [Trailhead: Salesforce B2C Commerce Third-Party Integration Strategies](https://trailhead.salesforce.com/content/learn/modules/b2c-integration-approaches?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Scheduled Jobs](https://trailhead.salesforce.com/content/learn/modules/b2c-admin-create-and-manage-jobs?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Headless Commerce Basics](https://trailhead.salesforce.com/content/learn/modules/b2c-headless-commerce-basics?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce SDK](https://trailhead.salesforce.com/content/learn/modules/b2c-commerce-sdk?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Headless Implementation Strategies for Salesforce B2C Commerce](https://trailhead.salesforce.com/content/learn/modules/b2c-headless-implementation-strategies?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: PWA Kit & Managed Runtime: Quick Look](https://trailhead.salesforce.com/content/learn/modules/commerce-pwa-kit-and-managed-runtime?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Submitting a file to a third party service in SFCC](/submitting-a-file-to-a-third-party-service-in-sfcc/) - [How to use OCAPI/SCAPI hooks](/how-to-use-ocapi-scapi-hooks/) - [What is the OCAPI session bridge?](/what-is-the-ocapi-session-bridge/) - [Delta exports in Salesforce B2C Commerce Cloud](/delta-exports-in-salesforce-b2c-commerce-cloud/) - [Get started with the OCAPI](https://developer.salesforce.com/docs/commerce/commerce-cloud/references/b2c-commerce-ocapi/get-started-with-ocapi.html) ## Launch (16%) ![A group of people standing around a table drinking sparkling wine.](/the-b2c-commerce-architect-certification/b2c-commerce-architect-launch-959e1a842f_hu_a08e5d24a8caea30.webp) The Official List - Given requirements for a site, set up aliases that follow SEO best practices and accurately land customers on desired domain, locale, and currency. - Given a site launch checklist, identify rollback steps possibly required, plan post-production activities, and ensure all launch tasks are completed. - Given a site launch, monitor launch activities that cover all system health indicators. - Given dependencies between sources of site data, define jobs and data replication schedules. - Given data migration scenarios, plan and support the data migration process. Once we have analysed, built, and tested our solution - it is time to put it live! But what do we need to watch out for, and how do we get our production environment to spin? As a Salesforce B2C Commerce Architect, you need to know where all the buttons and knobs are to get your environments up and running! - [Trailhead: Salesforce B2C Commerce Replication](https://trailhead.salesforce.com/content/learn/modules/b2c-admin-replication?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce SEO Meta Tags](https://trailhead.salesforce.com/content/learn/modules/b2c-seo-meta-tags?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce SEO URLs](https://trailhead.salesforce.com/content/learn/modules/b2c-seo-urls?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce XML Sitemaps](https://trailhead.salesforce.com/content/learn/modules/b2c-xml-sitemaps?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Hostname Aliases](https://trailhead.salesforce.com/content/learn/modules/b2c-hostname-aliases?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Site Readiness Assessment](https://trailhead.salesforce.com/content/learn/modules/salesforce-b2c-commerce-site-readiness-assessment?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: Salesforce B2C Commerce Launch Readiness](https://trailhead.salesforce.com/content/learn/modules/b2c-solution-functional-launch-readiness?trailmix_creator_id=mking23&trailmix_slug=b-2-c-commerce-architect-certification-prep) - [Trailhead: eCDN for Salesforce B2C Commerce](https://trailhead.salesforce.com/content/learn/modules/ecdn-b2c-commerce) - [Trailhead: Holiday Season Readiness with Salesforce B2C Commerce](https://trailhead.salesforce.com/content/learn/modules/b2c-holiday-season-ready) - [Let’s GO-LIVE: SEO](/lets-go-live-seo/) - [Let’s GO-LIVE: Customer Migration](/lets-go-live-customer-migration/) - [Let’s GO-LIVE: eCDN](/lets-go-live-ecdn/) - [How to set up the eCDN for Staging in Salesforce B2C Commerce Cloud](/how-to-set-up-the-ecdn-in-sfcc-staging/) - [AB Testing and Testing Methodologies](https://salesforce.vidyard.com/watch/dZ9vxBEeFuBRFh9snKfBjU) ## What if I fail the exam Failing a certification exam should not be considered a catastrophic event, especially one to become a Salesforce Certified B2C Commerce Architect. It is essential to understand that even if you have experience in successfully implementing Salesforce B2C Commerce Cloud, you may still need to pass the certification exam. During your project, you only had the opportunity to explore some aspects of Salesforce B2C Commerce Cloud and SFRA. It’s best to take note of the questions that gave you trouble, as these may represent gaps in your understanding that need to be addressed. Return to those topics, experiment with them in a Sandbox environment, and then resume your efforts to pass the exam. Remember, it’s always possible to get back on track! ## What if self-study isn’t my thing Not to worry, there are instructor-led courses available at [Trailhead Academy](https://trailheadacademy.salesforce.com/)! One specifically to become a Salesforce B2C Commerce Architect: ARC300. - [B2C Commerce Developer with SFRA ( CCD102 )](https://trailheadacademy.salesforce.com/classes/ccd102-b2c-commerce-developer-with-sfra) - [Manage and Merchandise a B2C Commerce Cloud Store ( CCM101 )](https://trailheadacademy.salesforce.com/classes/ccm101-manage-and-merchandise-a-b2c-commerce-cloud-store---extended) - [Architect B2C Commerce Solutions ( ARC300 )](https://trailheadacademy.salesforce.com/classes/arc300-architect-b2c-commerce-solutions) ## Can I wing it Undoubtedly, passing the B2C Commerce Architect certification exam can be a challenging task, even for those who have extensive experience in Salesforce B2C Commerce Cloud and SFRA development across multiple years/projects. It’s important to note that passing this certification exam is only easy if you have also worked on the configuration aspect of the Business Manager, including setting up search, category management, Jobs, and OCAPI, among others. However, with multiple projects and at least 3-4 years of experience, passing the exam without preparation is feasible. In my case, I passed the exam on my third attempt, whereas my first try was entirely unprepared- which I do not recommend. It’s vital not to take the exam lightly, as it’s a certification exam, not a Trailhead module. Therefore, adequate preparation and a thorough understanding of the exam content are necessary to achieve success. --- ## A Developer’s Guide to Using the getProps Method in the PWA Kit Canonical URL: https://rhino-inquisitor.com/guide-to-the-getprops-method-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/guide-to-the-getprops-method-in-sfcc/index.md Content type: article Published: 2023-05-15T09:58:07Z Updated: 2023-05-15T12:09:08Z Summary: Learn how the getProps method works in PWA Kit, what data it exposes, and when it helps with faster, cleaner storefront code. Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, pwa kit, sfcc, technical ## Key Takeaways - Explains what PWA Kit getProps does and where it fits in route-based data loading - Shows how getProps receives context, can be extended, and should handle errors and caching - Highlights the client-server trade-offs around personalization, payload size, and execution timing As a developer, you’re always looking for ways to improve the performance and functionality of your projects. The PWA Kit includes several features and functions that make creating high-performance, mobile- and [SEO](/lets-go-live-seo/)\-friendly web applications accessible. In this article, we’ll explore one of the critical features of the PWA Kit: the getProps method. ## Before we get started This article assumes you have experience with React and the libraries the PWA Kit uses behind the scenes. Is this not the case? Not to worry, there is plenty of public information available to get you started: - [Official PWA Kit Documentation: Skills for success](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/skills-for-success.html) - [Your first React Component](https://react.dev/learn/your-first-component) - [React Router v5](https://www.sitepoint.com/react-router-complete-guide/) - [Isomorphic React](https://yudhajitadhikary.medium.com/isomorphic-implementation-of-react-fa6e129c246f) - [Understanding Higher Order Components](https://blog.logrocket.com/understanding-react-higher-order-components/) ### React Router For navigation, the PWA Kit uses [React Router v5](https://v5.reactrouter.com/), a popular routing library for React. React Router offers a variety of options for constructing path strings, including the ability to specify more than one path for the same component and use regular expressions to match paths that follow a pattern. Version Note that the PWA Kit is designed to work with version 5 of React Router. While there may be newer versions available, please be aware that this library documentation may not reflect those updates. ### Express The PWA Kit uses [Express](https://expressjs.com/), a popular web application framework for Node.js, to handle server-side rendering and API requests. Express is known for its simplicity, flexibility, and robust features, making it an excellent choice for building scalable, high-performance web applications. In the PWA Kit, Express handles the server-side rendering of React components, improving our SPA’s (Single Page Application) performance and SEO-friendliness. Version The PWA Kit utilizes the latest stable release of Express, which is version 4. Version 5 is currently in BETA. ## What is the getProps method TL;DR You can access this function by adding a “page” to the [routes](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/develop/packages/template-retail-react-app/app/routes.jsx) file in the PWA Kit. The getProps method is used to supply data fetched from API requests to the routeComponent via the props object. When a component from the routes array is rendered, the component’s getProps method is supplied with a single JavaScript object that contains information about the rendering context, such as the URL of the request and any named route parameters. ### routeComponent “[routeComponent](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/develop/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js) is a higher-order PWA Kit React SDK component that enhances each component specified in the routes array. When a component is enhanced by “[routeComponent](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/develop/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js)”, it gains access to several static methods, including two important ones that storefront developers can customise: [getProps](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/develop/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js#L163) and [shouldGetProps](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/develop/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js#L109). Here is a snippet from the PWA Kit where the “wrapping” happens on the client side. ```js const props = { error: window.__ERROR__, locals: locals, routes: getRoutes(locals), WrappedApp: routeComponent(App, false, locals) } // ... export const OuterApp = ({routes, error, WrappedApp, locals}) => { const AppConfig = getAppConfig() const isInitialPageRef = useRef(true) return ( ) } ``` ### getProps Example ```js const ProductDetails = ({name}) => ( <h1>{name}</h1> ) ProductDetails.getProps = async () => { const response = await fetch(`https://httpbin.org/status/404`) const data = await response.json() return data // {name: "product_name} } ``` In this example, we define a ProductDetails component that takes one prop: name. We also define a getProps function for the component that fetches data from an API and returns it as props. Routed Pages Since the getProps function is an extension on a “route”, you can only use this function if this is a component being handled by react-router! Trying to use this in other components will not work. ## getProps Object Parameter The getProps method receives a JavaScript object with properties based on the rendering context. These include: - **params:** contains [object properties](https://expressjs.com/en/4x/api.html#req.params) corresponding to named route parameters - **req:** an enhanced version of Node’s [request object](https://expressjs.com/en/4x/api.html#req) for HTTP requests - **res:** representing the [HTTP response](https://expressjs.com/en/4x/api.html#res). - **location:** the URL of the request and is available on both client and server sides, but is not part of the Express API. ```text ProductDetails.getProps = async ({params, req, res, location}) => { ... } ``` ### Add your own properties To add custom properties to the object passed to the getProps function, define a function called extraGetPropsArgs as a property of the AppConfig component. This function can extend the set of arguments that get passed to all components enhanced by routeComponent via the getProps function. For example, the Retail React App uses the [extraGetPropsArgs](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/f5b07a8949f56657e5e4db96464fc5dc53abced1/packages/template-retail-react-app/app/components/_app-config/index.jsx#L80) function to give all components enhanced by routeComponent access to an object for interacting with the Salesforce Commerce API. This is achieved by defining the extraGetPropsArgs function to return an object with the API property set to locals.api. Here is an example of how it is defined in [AppConfig](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/develop/packages/template-retail-react-app/app/components/_app-config/index.jsx#L82): ```text AppConfig.restore = (locals = {}) => { locals.api = new CommerceAPI(apiConfig) } AppConfig.freeze = () => undefined AppConfig.extraGetPropsArgs = (locals = {}) => { return { api: locals.api } } ``` And now we can use that new property in our ProductDetail component: ```js ProductDetail.getProps = async ({res, params, location, api}) => { const {productId} = params let category, product const urlParams = new URLSearchParams(location.search) product = await api.shopperProducts.getProduct({ parameters: { id: urlParams.get('pid') || productId, allImages: true } }) ... } ``` ## Handling errors To handle [errors](/secure-coding-in-salesforce-b2c-commerce-cloud/) in a getProps function, you have two options. The first option is to throw an HTTPError object, which can be imported from “pwa-kit-react-sdk/ssr/universal/errors”. When you throw an HTTPError, a dedicated Error component is rendered. The second option is to use props to inform the rendered component of the error so that it can be used in custom error-handling logic. Here’s an example of how to handle errors in a getProps function: ```js ProductDetails.getProps = async ({res}) => { const response = await fetch(`https://httpbin.org/status/404`) if (!response.ok) { if (response.status !== 404) { throw new HTTPError(response.status, response.statusText) } res && res.status(404) return {errorProductNotFound: true} } const data = await response.json() return data } ``` ## Things to keep in mind When writing getProps functions, it’s important to be selective in what data to return to keep the size of the rendered HTML down. Besides HTML size, any external API call you do will also impact the response time of that page! You should also write conditional code in your components to handle undefined props, and render a placeholder component while props are undefined. ```js const ProductDetails = ({name}) => ( <h1>{name ?? 'My fallback'}</h1> ) ProductDetails.getProps = async ({params}) => { const response = await fetch(`https://api.example.com/products/${params.productId}`) const data = await response.json() return data || {} } ``` ### Caching Just like in SiteGenesis or SFRA it is possible to cache the server-side response! By setting the ‘[Cache-Control](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/maximizing-your-cache-hit-ratio.html)’ header, the CDN knows that it should cache the response. ```js const ProductDetails = ({name}) => ( <h1>{name ?? 'My fallback'}</h1> ) ProductDetails.getProps = async ({params, res}) => { const response = await fetch(`https://api.example.com/products/${params.productId}`) const data = await response.json() // If res exists, we are on the server-side if (res) { res.set('Cache-Control', `max-age=${MAX_CACHE_AGE}`) } return data || {} } ``` ### Personalisation Another thing to remember is that the server side uses a “guest” token, meaning no personalisation can happen there. It makes sense, but watch out with caching (see the previous section)! The PWA Kit has no concept of “[varyby=price\_promotion](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/isml/b2c_iscache.html)” caching. That is the responsibility of the SCAPI! ### Client Side Execution Once the first page loads, the responsibility of displaying the content shifts from the server to your device through a process known as hydration. This is when your React app starts working in your browser. As you interact with the page, it responds to your actions and shows the necessary elements. This efficient and user-focused approach creates the smooth experience React is known for. The PWA Kit architecture ensures a seamless transition from server-side to client-side rendering. For instance, all components are prepared with the required information, even if it comes from API requests. This data is embedded into the page source during server-side rendering, making it available during hydration. After this transition, you lose access to some “server-side” properties in the getProps function, such as res (Express). ![https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/rendering.html](/guide-to-the-getprops-method-in-sfcc/pwa-kit-isomorphic-constructs-4f4cc1e134_hu_29bcc5b48ceea5b6.webp) [Isomorphic Code](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/rendering.html) explained on developer.salesforce.com ## Conclusion For one method, there is a lot to write about and to keep in mind! The PWA Kit has many features available, ready for use - you just need to know they exist! --- ## What is the Salesforce B2C Commerce Cloud Managed Runtime? Canonical URL: https://rhino-inquisitor.com/what-is-the-sfcc-managed-runtime/ Markdown URL: https://rhino-inquisitor.com/what-is-the-sfcc-managed-runtime/index.md Content type: article Published: 2023-05-08T13:04:24Z Updated: 2023-05-08T13:15:51Z Summary: The Salesforce B2C Commerce Cloud Managed Runtime is a cloud-based hosting environment for Progressive Web Applications (PWAs). Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, headless, sfcc, technical ## Key Takeaways - Explains the Managed Runtime as Salesforce-hosted infrastructure for deploying, running, and monitoring PWA Kit storefront bundles - Covers the core concepts of organizations, projects, environments, and bundles that structure a composable storefront deployment - Highlights the main business and developer benefits, including simplified infrastructure management, scaling, rollback clarity, and API-driven automation In the last two years, more vocabulary has been added to the [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/) ecosystem because of the [Composable Storefront](/sitegenesis-vs-sfra-vs-pwa/). And one of the terms you might have heard is “[Managed Runtime](https://runtime.commercecloud.com/login)”, which provides the infrastructure to deploy, host, and monitor your Progressive Web App (PWA) Kit storefront. In this article, we will explore the inner workings of Managed Runtime, its benefits, and how it empowers developers to build storefronts without having to think (much) about the underlying infrastructure. ## What does the Managed Runtime do The [Managed Runtime](https://runtime.commercecloud.com/login) is designed to support applications created from a PWA Kit template in the [PWA Kit repository](https://github.com/SalesforceCommerceCloud/pwa-kit) on GitHub. It operates within environments, which is the term to describe all of the cloud infrastructure and configuration values. It is possible within that infrastructure to differentiate between development and production environments. Developers will use the PWA Kit tools to generate a bundle, a snapshot of the storefront code at a specific time, and push it to Managed Runtime. Once the bundle is pushed, it is possible to use the Runtime Admin Web Interface or [Managed Runtime API](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/using-the-managed-runtime-api.html) to designate that bundle as “deployed.” Each project can have multiple bundles, but each environment has only one “deployed” bundle. Similar to the fact that you can only have one active “[Code Version](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_development/b2c_code_versions.html)” on the server side. ![Managed Runtime project list showing one organization with two storefront projects.](/what-is-the-sfcc-managed-runtime/salesforce-commerce-cloud-managed-runtime-e2b922960d_hu_3bbc4a779d565fd0.webp) The Managed Runtime operates within a hierarchy of organisations and projects. Organisations can contain multiple projects for various storefronts, and each project can contain multiple environments. This structure allows for efficiently managing multiple environments and separating different work streams. ![Mind map showing Managed Runtime organisations, projects, and environments with production and development types.](/what-is-the-sfcc-managed-runtime/managed-runtime-projects-environments-ba31af2d92_hu_60a4d9cd89e45bee.webp) ### AWS Lambda Under the hood, the Managed Runtime uses AWS Lambda, a serverless computing service provided by Amazon Web Services (AWS) that allows you to run your code without provisioning or managing servers. Curious about Lambda? [Here you go](https://aws.amazon.com/lambda/)! ## Benefits of the Managed Runtime for businesses When a platform offers features, there are a lot of questions that will go through your mind. And one of them will probably be, “What benefits does it bring?”: 1. **Included in the license:** It is not a phrase you often see in the Salesforce Eco-system, but the managed runtime is ready to be taken advantage of if you have a license for B2C Commerce Cloud! 2. **Simplified deployment:** Managed Runtime streamlines deploying and hosting your PWA Kit storefront, meaning that developers only need to develop - and not worry about the infrastructure. And that saves time and, ultimately, money. 3. **Scalability:** Nothing new to B2C Commerce Cloud, but the infrastructure provided by Managed Runtime allows your storefront to scale seamlessly as your business grows, ensuring optimal performance and customer experience just like the “[monolithic solution](/sitegenesis-vs-sfra-vs-pwa/)”. 4. **Security:** Managed Runtime offers robust security features that protect your storefront from potential threats and vulnerabilities like the back end. 5. **Improved troubleshooting:** The immutable nature of bundles allows for a complete and accurate history of deployments, making it easier to identify and resolve issues or even do a quick rollback to a previous version! ## Benefits of the Managed Runtime for developers ![A developer wearing headphones working across two monitors.](/what-is-the-sfcc-managed-runtime/developer-working-on-multiple-monitors-27024b5da3_hu_9b060d8ff54b51c5.webp) Developers working with Salesforce B2C Commerce Cloud can leverage this runtime to: 1. **Accelerate development:** This was already mentioned, but the fact that, as a developer, you do not have to worry about the infrastructure is a significant benefit! 2. **Streamline collaboration:** The organisation and project structure within Managed Runtime enables you to work together more efficiently, sharing knowledge and resources across multiple environments. 3. **Enhance productivity:** With the ability to designate specific bundles as deployed, developers can easily switch between different versions of their storefront, making testing and iterating on new features more accessible. 4. **No credits:** The environments on the managed runtime do not work on the same system as the sandboxes (credits for uptime). That means no extra processes have to be set up! ## APIs Salesforce offers [a range of APIs](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/using-the-managed-runtime-api.html) that developers can use to interact with the platform, including: 1. **Managed Runtime APIs:** This API allows developers to manage bundles, environments, and deployments within their projects. 2. **Admin APIs:** This API provides access to administrative functions, such as managing users, organisations, and projects. These APIs make setting up CI/CD pipelines and automating specific processes much easier! ## Conclusion Some developers might hesitate to give up control when deciding whether to let Salesforce manage its environment. Others might appreciate the specialised skills needed to manage infrastructure and will gladly pass on the baton to Salesforce. It’s important to know that you don’t have to use the Managed Runtime option and can create your own Headless Storefront for Salesforce B2C Commerce Cloud if you want to. But if you choose this route (build your own), the managed runtime might not be an option! ![A diagram depicting how you would roll your own Headless Storefront based on a custom Node.js server running APIs through Apollo.](/what-is-the-sfcc-managed-runtime/b2c-commerce-cloud-roll-your-own-b16dfb6a8d_hu_d2a8cacf81852abb.webp) An example of a 'roll your own' architecture --- ## Server-Side Performance Troubleshooting in SFCC Canonical URL: https://rhino-inquisitor.com/server-side-performance-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/server-side-performance-in-sfcc/index.md Content type: article Published: 2023-05-01T05:50:49Z Updated: 2025-07-29T12:37:49Z Summary: Performance is important for any eCommerce site. You need to make sure your content loads quickly and customers can start shopping! Categories: Salesforce Commerce Cloud, Technical Tags: performance, sfcc, technical ## Key Takeaways - Explains the main server-side performance tools available in SFCC, including reports, the pipeline profiler, and the code profiler - Highlights practical performance levers such as better code hygiene, custom caches, and page caching - Provides a troubleshooting flow teams can follow when storefront controllers or API customizations slow down All web developers understand the crucial role [performance](/caching-rest-apis-in-sfcc/) plays for a website, both in terms of the visitor experience and as a quality benchmark. Not to forget, conserving CPU cycles contributes to environmental sustainability, albeit in small increments. So, how can you maintain high performance on your pages within [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/)? In this article, we’ll focus on server-side implementation. Salesforce offers numerous tools to enhance and diagnose performance issues, and we’ll explore a selection of these valuable resources! ## Write performant code It may seem like an obvious point, but many developers tend to overlook the importance of considering performance while coding. It’s common to get stuck on an issue for hours, finally, come up with a solution, and then feel hesitant to make any further changes to the code since it’s working. However, it’s crucial to revisit the code and perform some refactoring. You may have inadvertently written loops or commands that consume precious milliseconds of processing time. As you review the code, ask yourself if every line of code is necessary and if better alternatives or out-of-the-box solutions are available. ## Use Custom Caches for heavy-duty processes If you have never heard about Custom Caches, [time to read up](/field-guide-to-custom-caches-in-sfcc/)! Custom Caches can significantly enhance performance when you need to perform resource-intensive operations. Keep in mind that **Custom Caches are only suitable if the process’s outcome remains constant**. For instance, you can cache the retrieval of configuration values from an external service or store an access token instead of fetching a new one for every request. Or, if you need to calculate the average of a custom attribute for all the variants of a master product, storing the outcome in custom caches is more efficient than calculating it repeatedly. There are some things to keep in mind with Custom Caches: - It is not site-specific, so include the site-id in the key. If you don’t, you might have some unexpected results. - Caches in the application servers of the same instance are separated - The cache can be cleared automatically in a lot of different ways, so don’t depend on cached values existing (replication, code activation, and time-based) - You can only store a maximum of 20MB of data in total - The cache is stored in memory and is not persisted - Custom Caches can be turned off in the Business Manager ## Don’t forget page caching ![A diagram of a web server and a web server. Showing the request of a page being handled by the Web Server to determine whether a cached page should be returned or to let the Application Server do the generation.](/server-side-performance-in-sfcc/b2c-page-caching-110c7fcba6_hu_ba253096676ea973.webp) In simple terms, page caching stores the Application Server responses (HTML, JSON, XML, …) in the Web Server. By doing this, the requests coming from the browser don’t have to traverse the entire stack again to render the same content as before. But how do you set this up? There are two ways: - [`<iscache>` tags](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/isml/b2c_iscache.html) - [SFRA Cache Middleware Functions](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/blob/master/cartridges/app_storefront_base/cartridge/scripts/middleware/cache.js) I will not cover all of the details of what page caching offers. That deserves a dedicated blog post, as this can become quite the rabbit hole! And as luck would have it, [there is a blog post about it](https://medium.com/salesforce-architects/caching-in-salesforce-commerce-cloud-part-1-e49b5f3e1801) (and more)! _[Here is a link](https://medium.com/salesforce-architects/caching-in-salesforce-commerce-cloud-part-2-cc2adc664a1) to part 2 of that same blog post for completeness._ ## Performance Debugging Oh no… a certain thing hit the fan, and the product detail pages suddenly slowed to a crawl! But at first glance, you have no clue what the issue is. You did a code release before this happened but can’t pinpoint the cause. Luckily there are some tools to help you out within the platform to do performance monitoring and debugging. ### Technical Reports We have live data since we are in production, which means “[Reports & Dashboards](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/analytics/b2c_reports_and_dashboards.html)” are available! Part of those reports is not about sales, but about performance! Just what we need! The [Technical Dashboard](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/analytics/b2c_technical_dashboard.html) (as it is called) gives us a great overview about: - Average Response Time - Cache Hit Ratio - Error Rates - Response Time Distribution Looking at the list of data above, it makes sense to have a look at it! ![A screenshot of the 'Reports & Dashboards' with the 'Average Response Time' graph depicting a significant performance degradation (doubling in milliseconds).](/server-side-performance-in-sfcc/performance-dashboard-8a847df133_hu_3dcf6d5f5b336680.webp) The Technical Dashboard is the first place to confirm whether response times are trending the wrong way. This dashboard lets you obtain the essential information regarding your cache performance for all endpoints, including Remote Includes. Clicking on a controller will reveal insights into the various sub-requests caused by the [Remote Include](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/ops_troubleshooting/b2c_understanding_remote_includes.html) mechanism. This dashboard is an excellent starting point for identifying caching issues and controllers with extended runtimes. _The screenshot shows performance has decreased for the Product-Show controller over the past few days or weeks._ ### Pipeline Profiler _Don’t be fooled by its name; it will profile more than pipelines!_ The second tool you should be grabbing ahold of is the [Pipeline Profiler](https://documentation.b2c.commercecloud.salesforce.com/DOC1/index.jsp?topic=%2Fcom.demandware.dochelp%2FLegacyDevDoc%2FAnalyzePerformancePipelineProfiler.html). It is easy to use, will give you a high-level overview of all of your pipeline/controller endpoints, and show you how much processing time it needs to do its thing. ![A screenshot of the Pipeline Profiler showing the Search-Show controller with two hits and its total processing time of 1023 milliseconds. Below the controller is the template performance, showing the searchResults.isml file.](/server-side-performance-in-sfcc/pipeline-profiler-24fb681d34_hu_df886b2172b2004a.webp) The Pipeline Profiler shows which controller and template path is actually burning time. As you can see, the above screenshot shows a basic overview of the performance of a controller and the template (response) it renders. If the template uses local includes, you can see their processing time separately. All of the [Remote Includes](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/ops_troubleshooting/b2c_understanding_remote_includes.html) you have done are within the list of controllers. ![A screenshot of the Pipeline Profiler showing a list of Remote Includes, with the 'Tile-Show' controller marked with a red circle around it.](/server-side-performance-in-sfcc/pipeline-profile-remote-includes-0e99481937_hu_9960e6ae34d856af.webp) Remote includes show up as their own controllers, so they must be profiled separately. The information you get is quite basic, but it will give you the first indication of pain points and where to start looking. You can do this on production, but preferably as a last resort. You should be able to reproduce the issue in a different environment, such as development. Cache This method only works for uncached endpoints if caching is enabled. Cached responses are not taken into account by the Pipeline Profiler! ### Code Profiler Last but not least, the [Code Profiler](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_performance/b2c_using_code_profiler.html) provides you with detailed insights on run-time performance. You can control how detailed you want that information as it supports three modes: Production, Development and Extended. ![A screenshot of the Code Profiler with the activated 'Extended Script Development Mode' setting. The screenshot includes an extensive list of functions and Javascript files executed in the server-side code.](/server-side-performance-in-sfcc/salesforce-code-profiler-extended-eeb0fcbb69_hu_77277076d18cf599.webp) The Code Profiler is the deep-dive tool once dashboards and profiler views stop being enough. Looking at the screenshot above, you can understand why they call it “Extended Script Development Mode.” You get fine-grained details about the performance of your code, including information on which line in what JavaScript file. This tool is your final stop for performance issues. Production Enabling the Extended Script Development Mode offers a deeper understanding of the script’s internal run-time behaviour, supplementing the information provided by the Development Mode. However, using the Code Profiler in this mode may severely impact performance, and therefore, it’s recommended to exercise caution while using it in production environments. ## What about the Composable Storefront? Although the Pipeline Profiler isn’t applicable in this scenario, you can still utilize the Technical Reports and Dashboards in conjunction with the Code Profiler. ### Reports & Dashboards Within these reports are dedicated tabs for OCAPI and SCAPI performance! ![A screenshot of the OCAPI / SCAPI Technical Reports and Dashboards showing the average response times and response distribution graphs.](/server-side-performance-in-sfcc/ocapi-and-scapi-performance-reports-f411be08a3_hu_7bd713c67d63565f.webp) Use the API reports when the slowdown is in integrations rather than storefront rendering. OCAPI and SCAPI Performance Reports ### Code Profiler This report includes all Custom Hooks implemented for SCAPI and OCAPI, providing you with the opportunity to analyze the performance impact of your API customizations. ## Conclusion Server-side performance is a crucial factor in ensuring the success of any website, and B2C Commerce Cloud is no exception. In today’s fast-paced digital world, users expect websites to load quickly and efficiently, and any delays or lags can result in a negative user experience. This can lead to a loss of potential customers and revenue for businesses. A performance debugging flow could look like this: 1. **Production**: Look at Reports and Dashboards (Technical Dashboard). 2. **Development:** Run the Pipeline Profiler to see if you have similar results as on the dashboard. 3. **Development:** Run the Code Profiler to look for the lines of code that cause the performance issue. --- ## Non-Technical Salesforce B2C Commerce Certifications Canonical URL: https://rhino-inquisitor.com/non-technical-sfcc-certifications/ Markdown URL: https://rhino-inquisitor.com/non-technical-sfcc-certifications/index.md Content type: article Published: 2023-04-24T08:47:47Z Updated: 2023-05-02T17:31:52Z Summary: Salesforce B2C Commerce Cloud appears to only have certifications for developers, but is this true? Are there other options available? Categories: Certification Tags: certification, sfcc, trailhead ## Key Takeaways - Surveys Salesforce certifications and accreditations that fit non-developer roles around SFCC work - Explains how UX, strategy, business analyst, sales, and Einstein credentials map to different career paths - Clarifies that most current options are ecosystem-wide rather than SFCC-specific role certifications People working as Business Analysts, UX designers, or other non-developer roles have felt a [gap](/certifications-for-salesforce-b2c-commerce-cloud/) in the Salesforce B2C Commerce Cloud certifications for a while. There have been [certifications](/is-salesforce-certification-worth-it/) available for developers for a very long time now, but those require you to know how to code. But in 2021, 2022, and 2023, some options became available for those who do not have a developer background! ## User Experience (UX) Designer ![Usability and UX Certifications](/non-technical-sfcc-certifications/usability-vs-ux-9753e7801d_hu_840546b5a535ca9d.webp) UX certifications are the most natural bridge into commerce work for design-focused roles. - [Trailhead - Certification](https://trailhead.salesforce.com/en/credentials/userexperiencedesigner) The first certification reared its head in 2021 was the User Experience Designer. A certificate that does not focus on developing features but on how to design these features to be user-centric and easy to use. One thing to know with this certification is that besides the general knowledge of UX with topics like [User Research](https://trailhead.salesforce.com/content/learn/modules/ux-research-basics?trailmix_creator_id=strailhead&trailmix_slug=prepare-for-your-ux-designer-credential), it bases examples on the [force.com](https://www.force.com) platform, specifically the [Lightning Design System](https://www.lightningdesignsystem.com/). To get this certification, having only SFCC knowledge, you must come out of your comfort zone and explore the CRM. But, look at it as an excellent opportunity to learn more about the Salesforce ecosystem and the possibilities that it brings to the table. ## Strategy Designer ![A digital drawing of a group of people standing in front of a window, looking at the skyscrapers of a modern city illuminated in the night.](/non-technical-sfcc-certifications/business-men-and-women-looking-at-a-skyline-76f36bbb13_hu_744ee680ee859d21.webp) Strategy Designer suits people who frame problems before anyone touches implementation. - [Trailhead - Certification](https://trailhead.salesforce.com/en/credentials/strategydesigner) While a UX designer focuses on the end-user, a Strategy Designer focuses on the business and its goals. The description is taken from Trailhead: > Strategy Designer candidates create value by aligning an organisation around and directing the design of systems-level solutions toward desired business and user outcomes. A completely different path than the User Experience Designer and Business Analyst as you take a more high-level approach to the projects and their alignment with the business and users’ goals. A perfect role (and certificate) for those who like to spar with businesses on their roadmap and vision for the future. The preparation for this certification will take you across different products of Salesforce, not only Salesforce B2C Commerce Cloud. But isn’t that a good thing? As a Strategy Designer, you should be aware of all of the different offerings of Salesforce to align them with the organisation’s vision! ## Business Analyst ![Illustration of a business analyst collaborating with stakeholders around a desk.](/non-technical-sfcc-certifications/business-analyst-scaled-e1656834912690-1350424ea9_hu_e00cb79e71062cd5.webp) Business Analyst is the clearest path for people who translate needs into delivery. - [Trailhead - Certification](https://trailhead.salesforce.com/en/credentials/businessanalyst) You understand and analyse business operations, processes, and requirements to improve productivity and drive business growth, so naturally, this certification fits you like a glove, right? ~~But for B2C Commerce Cloud professionals, this particular certification has a significant drawback: it requires you to have the [Salesforce Administrator certification](https://trailhead.salesforce.com/en/credentials/administrator). And to get that certification, you need more than just a basic understanding of the Salesforce CRM.~~ ~~While in the big picture of things in the Salesforce eco-system, it is a requirement that you have a solid knowledge of the platform that you are implementing, the fact that B2C Commerce Cloud is not built on the “core” means that we are at a disadvantage.~~ ~~The fact that there is no “administrator” like certification for B2C Commerce Cloud doesn’t help… But if you are not afraid of a challenge and are preparing for [the world of tomorrow](/what-is-commerce-on-core/), this certification might be worth pursuing!~~ Salesforce Admin is no longer required As of May 2, 2023, the Salesforce Administrator certification is no longer a requirement! > Effective today, May 2, 2023, the Salesforce Administrator Certification will no longer be required prior to earning the Salesforce Business Analyst Certification. > > As a result of this change, Salesforce Business Analyst Certification will no longer be maintained with Salesforce Administrator Certification maintenance. A Business Analyst maintenance module will be available with the start of Summer ’23. For more maintenance info, visit the [Certification Maintenance Schedule Help article](http://click.mail.salesforce.com/?qs=0e0922571fda7b008a681bf990b59c2f7b900a3427d9add675a77798af335adaeae10a342e704083c34ab11d8ab098ad2d996f3a680b73dc). > > For more information, please visit the [Salesforce Certified Business Analyst FAQ](http://click.mail.salesforce.com/?qs=0e0922571fda7b00223dfa49da8843ba54e3e7fc99e3741274f7e195bb9cf6b9a25eb0a6d3410fc592f3597d5a741ecf4563b416e552dc2c). > > Salesforce Certification Mail ## Sales Representative ![A group of men and women sitting around a table e, drawn in the style of the 50's](/non-technical-sfcc-certifications/a-sales-meeting-0eb7bfc029_hu_5ae2a53f7f764b3c.webp) Sales-focused accreditations matter most when your role is shaping the commercial conversation. - [Trailhead - Certification](https://trailhead.salesforce.com/en/credentials/salesrepresentative) Salesforce has recently announced the Certified Sales Representative certification exam, designed to showcase your knowledge and skills in various areas, such as guiding discovery and research, fostering business relationships, handling objections, and closing deals. The best part? Unlike other certifications, this one does not require any CRM-based prerequisites like Business Analyst, making it more accessible to sales professionals who focus on Salesforce B2C Commerce Cloud. Watch for the upcoming guiding trailmix, which will help you understand the product knowledge required for the exam. Take advantage of this opportunity to demonstrate your expertise and take your sales career to the next level. Trailmix Once the trailmix becomes available, I will update this section of the article! ## Commerce Cloud Einstein Accredited Professional - [Partner Learning Camp - Accreditation](https://partnerlearningcamp.salesforce.com/s/credentials-catalog?plc__recordId=d%2Fx2y6m%2FknTcjnfe7C0GiHmOkms8uLPL82Zrct7hYQcVHqfIycgjEyVfwejd21xa) ![A drawing of Einstein standing in a store, wearing a green vest with a red tie and shoes. The store walls are painted red and green, with the shopping racks filled with clothes and perfume.](/non-technical-sfcc-certifications/einstein-shopping-c2fd371422_hu_674283be580cdebe.webp) Einstein accreditation fits people who need to position commerce AI to business stakeholders. We ran out of Trailhead Certifications, so now we are turning to the [Partner Learning Camp](https://partnerlearningcamp.salesforce.com/s/learner-dashboard) (PLC). Here you will find certifications targeted toward Partners and Employees of Salesforce, so if you are neither, this Accreditation is not an option for you. [Einstein](/ai-einstein-in-salesforce-b2c-commerce-cloud/) is one of the critical features of Salesforce B2C Commerce Cloud, providing many different AI features “natively” to the platform. And even though some development has to go into it, many of its features must be configured to work out of the box! Knowing where all those buttons and switches are is essential to any project. The official description is as follows: > The Commerce Cloud Einstein Accredited Professional exam is intended for individuals who have the knowledge, skills, and experience with data ingestion processes, security and access implementations. This exam expects basic Salesforce knowledge including objects, data and data modeling. **Be prepared for a few technical questions**, so read the “developer guides” before attempting it. (These are part of the [course](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=LvENtDruwJ3xK1jpdgHFO79ru9n7PrrVcEOQmcXlz7nNXzQy1CYDOFzq9byO51a6) also available inside the Partner Learning Camp) ## Indirect Sales Accredited Professional ![Sales-themed illustration for the Indirect Sales Accredited Professional section.](/non-technical-sfcc-certifications/sales-25d69d411e_hu_81c262d93fed3351.webp) Indirect Sales accreditation is aimed at the partner and channel side of the business. - [Partner Learning Camp - Accreditation](https://partnerlearningcamp.salesforce.com/s/credentials-catalog?plc__recordId=huaR3i8ewEj9BrjQeVKHB51JTVgrOzyjjUy8ORjUXXoU52nqrMytajtg4M1c44Ux) Again a different type of certification than we are used to and a completely different role. The official description sounds something like this: > The Indirect Sales Accredited Professional exam is intended for an individual who may have the title of Sales Manager, Account Executive, Marketing Manager, or Business Development. These sales roles are responsible for communicating the benefits of a company’s products in order to drive sales. They serve as the point of contact between a business and its prospects or clients. Their range of responsibilities includes identifying and educating prospective customers while supporting existing clients with information and assistance that relates to products and services. Qualifications often include strong interpersonal and communication skills. I may start sounding like a broken record, but this certification also targets the different Salesforce product catalogues, not just Salesforce B2C Commerce Cloud. If your company targets Salesforce B2C Commerce Cloud, this might not be the course for you. But trying it to see how Salesforce expects you to approach potential clients might be interesting. This is also an excellent opportunity for your salespeople to get acquainted with the Salesforce ecosystem! ## What about Salesforce B2C Commerce Cloud specific ones? Although the abovementioned certifications are not specific to Salesforce B2C Commerce Cloud, the skills you need to perform these roles do not require you to have them per se. However, you must learn about all of the features that Salesforce B2C Commerce Cloud offers to help your clients better and make optimal use of what the platform(s) offer! Hopefully, at one point, there will be a certificate along the lines of “Salesforce B2C Commerce Merchandiser”, but for now, that is only a dream. --- ## A look at the Salesforce B2C Commerce Cloud 23.5 release Canonical URL: https://rhino-inquisitor.com/a-look-at-the-sfcc-23-5-release/ Markdown URL: https://rhino-inquisitor.com/a-look-at-the-sfcc-23-5-release/index.md Content type: article Published: 2023-04-20T05:52:49Z Updated: 2023-04-23T15:28:04Z Summary: 23.5 release overview covering eCDN certificate renewal, search updates, order-management controls, and new SCAPI basket capabilities. Categories: Release Notes, Salesforce Commerce Cloud Tags: security, sfcc, technical ## Key Takeaways - Highlights 23.5 improvements across eCDN certificates, search, and order management - Calls out new basket and trusted-agent API capabilities in SCAPI - Notes security and operational changes that deserve follow-up testing Another month, another release! This time we look at the [May 2023 (23.5) release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_22_7_release.htm&type=5)! Are you interested in last month’s release notes? Read the [23.4 release overview](/everything-new-in-sfcc-23-4/). ## Platform ### Auto Renew CDN Certificates > Starting May 19, 2023, if you can self-manage your custom SSL certificates, you have the option to configure Cloudflare provisioned SSL certificates for automatic renewal. Auto renewing a certificate saves time and keeps you from missing deadlines. It also improves managing eCDN on staging instances. You can configure auto renewing certificates for development, staging, and production instances. Auto renewal is available only for Cloudflare certificates and only with the CDN-API. If you use Cloudflare provisioned SSL certificates, this update is a big ease-of-life improvement! > **Limitations:** You can renew up to 10 auto-renewing certificates. Signature Customers can renew up to 50 auto-renewing certificates. ### Log Users Views of Personal Identification Information > Configure Business Manager to make security log entries when a user views a shopper’s personal identification information (PII) in the Order module. When a user clicks a button, tab or field that displays a shopper’s PII, the security log updates with details about when, who, and what is viewed. For example, When the user views an order, the security log is updated with a timestamp, the user, and the order number viewed. Protecting your customer data is vital in eCommerce (and any industry). With this new option, you can have greater visibility into who looks at personal data and do audits on these logs. Customer Support It is not possible to activate this feature manually, a ticket with Support has to be logged to activate it. ### Code Profiler Wait Times Removed from CSV Report > Code profiler wait times, which include Wait Time Own and Wait Time Total, are no longer measured. These values have been removed from the B2C Commerce CSV report. The CSV report remains backward compatible. Some metrics are disappearing from the [code profiler](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_performance/b2c_using_code_profiler.html), a tool available in the Business Manager to check the performance of your custom code: - total\_wait\_ time - total\_wait\_ time\_avg - own\_wait\_ time - own\_wait\_ time\_avg CSV Export The CSV report generated from system job sfcc-export-code-profiler-reports and the CSV report accessible from the Code Profiler Business Manager module maintain these columns, filled with zeros as data. ### Export Attributes of Type Number as Decimal Representation > To support commerce business use cases, custom attributes of type Number are now exported as their decimal representation (xsd:decimal) instead of as a String representation (xsd:string). If you want to continue using the xsd:string representation, you can change the default in Business Manager to the legacy xsd:string formatting. A relatively “small” change in this release is: Now the [XML](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/xsd/Schemas.html) files will represent the type they are exported as - ensuring no possible misinterpretation moving from String to Number. ## Business Manager ### Manage Orders Rejected by Salesforce Order Management > You can now exclude, cancel, and resubmit orders rejected by Salesforce Order Management in the Business Manager Orders page. [![Salesforce Order Management 23.5 Release](/a-look-at-the-sfcc-23-5-release/salesfore-order-management-manage-rejected-orders-87ae4bdc6c_hu_a87f4b191274a77a.webp)](salesfore-order-management-manage-rejected-orders-87ae4bdc6c.png) Rejected-order actions in Order Management The screenshot displays three options for managing excluded orders in Salesforce Order Management. Firstly, you can resubmit an unintentionally excluded order with one click by selecting option “1”. Option “2” enables the manual exclusion of orders with a failed status from being resubmitted to Salesforce Order Management, providing greater control over the order fulfilment process. Lastly, option “3” allows for the cancellation of excluded orders, moving the ordered product back to inventory and making it available for other reservations. These options finally provide flexibility and more control over orders synced with Order Management, a welcome change! ### Improve Search Results with Autocorrection > Enable search to process configured synonyms when autocorrecting or autocompleting a user’s search phrase. If the original phrase matches the synonym entries, search includes the synonyms. When search autocorrects a phrase, it considers both the original phrase and the autocorrected version. Previously, if a phrase was autocorrected or autocompleted, synonym group matching on the initial search phrase wasn’t considered. It’s fantastic to hear that search is finally receiving much-needed attention in this release! This feature will undoubtedly enhance the search experience for users, allowing them to discover what they’re looking for more quickly and easily. ## OCAPI & SCAPI ### Shopper Baskets and Trusted-Agent-On-Behalf-only endpoints New endpoints are now supported: - PUT /baskets/{basketId}/agent - PUT /baskets/{basketId}/storefront - POST baskets/{basketId}/price-adjustments - DELETE baskets/{basketId}/price-adjustments/{priceAdjustmentId} - PATCH baskets/{basketId}/price-adjustments/{priceAdjustmentId} ### New Channel Types supported for Baskets & Orders [![Channel-type list showing the new basket and order channels added in the 23.5 release.](/a-look-at-the-sfcc-23-5-release/scapi-channel-types-2023-2795e88145_hu_87871c4a4f8e0063.webp)](scapi-channel-types-2023-2795e88145.jpg) New basket and order channel types The list of channels before the update The following new channel types are supported by Baskets and Orders apps: TikTok, SnapChat, Google, WhatsApp, and YouTube. ### SLAS Updates [SLAS](/how-to-set-up-slas-for-the-composable-storefront/) received quite a bit of love in the past month: - SLAS service supports SMS notifications for passwordless login. - BOT Mitigation improvements: Reduced the time window from 2 seconds to 1 second for the same user login that returns Error 409. - Fixed the issue around deletion of a user with different loginID and IDP, when the tenant and customerID remains the same. - SLAS Tenant creation improvements to include region validation. - SLAS Service Introducing Rate Limit of 25 TPM per tenant for JWKs and well-known endpoints. - SLAS service redirect to customer’s registered callback URL on IDP errors and return Error 412 for refresh token calls. - Security library updates. ## New Ideas It has been a great month of ideas with some noteworthy suggestions from the community! - [Add trend chart for Views & Clicks to Commerce Einstein Report](https://ideas.salesforce.com/s/idea/a0B8W00000NwwPuUAJ/add-trend-chart-for-views-clicks-to-commerce-einstein-report) - [Page Designer: Ability to target content display to multiple customer groups](https://ideas.salesforce.com/s/idea/a0B8W00000O20kSUAR/page-designer-ability-to-target-content-display-to-multiple-customer-groups) - [Checkout Address Updates](https://ideas.salesforce.com/s/idea/a0B8W00000O5s9lUAB/checkout-address-updates) - [Product Readiness for B2C Commerce](https://ideas.salesforce.com/s/idea/a0B8W00000O6UiMUAV/product-readiness-for-b2c-commerce) - [API First B2C Commerce](https://ideas.salesforce.com/s/idea/a0B8W00000O6VItUAN/api-first-b2c-commerce) - [Trial sandboxes for B2C Commerce](https://ideas.salesforce.com/s/idea/a0B8W00000O6WeCUAV/trial-sandboxes-for-b2c-commerce) - [Add the ability to track and view product set performance](https://ideas.salesforce.com/s/idea/a0B8W00000O7VCVUA3/add-the-ability-to-track-and-view-product-set-performance) - [Voice To Text Search](https://ideas.salesforce.com/s/idea/a0B8W00000O7ouVUAR/voice-to-text-search) - [Toolkit for the compassable storefront](https://ideas.salesforce.com/s/idea/a0B8W00000NuNGUUA3/toolkit-for-the-compassable-storefront) ## Updated Cartridges & Tools ### Composable Local Hybrid Dev Server - [https://github.com/SalesforceCommerceCloud/composable-hybrid-dev-server](https://github.com/SalesforceCommerceCloud/composable-hybrid-dev-server) > This repo contains sample Node.js app that can be used to develop and test hybrid deployment shopper flows across PWA Kit and SFRA/SiteGenesis. It is no secret that hybrid deployment projects will be happening more and more. Having these supporting projects to make development easier are a welcome addition! ### plugin\_slas (v6.4.2) - [https://github.com/SalesforceCommerceCloud/plugin\_slas](https://github.com/SalesforceCommerceCloud/plugin_slas) > The plugin\_slas cartridge extends authentication for guest users and registered shoppers using the Shopper Login and API Access Service (SLAS). - Add changes to support SiteGenesis [#103](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/103) - Exclude page designer controllers from triggering SLAS login flows [#104](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/104) - Fix bug in logic to determine origin of request to SLAS [#104](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/104) - Fix bug in uploadCartridge npm script [#104](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/104) ### b2c-japan-package (v1.7.0) - [https://github.com/SalesforceCommerceCloud/b2c-japan-package](https://github.com/SalesforceCommerceCloud/b2c-japan-package) > This is a demo repository of commonly used business solutions in Japan.This cartridge enhances the SFRA(app\_storefront\_ base). - Release plugin\_groputax\_ ex - Release plugin\_groputax\_ ex\_sg I am assuming it is supposed to say “grouptax”. A feature which has been added in a [recent update](/salesforce-b2c-commerce-cloud-23-2/). ### Salesforce B2C Commerce / Customer 360 Platform Integration (v3.0.0) - [https://github.com/SalesforceCommerceCloud/b2c-crm-sync](https://github.com/SalesforceCommerceCloud/b2c-crm-sync) > Salesforce B2C Commerce / CRM Sync is an enablement solution designed by Salesforce Architects to teach Salesforce’s B2C Customer Data Strategy for multi-cloud use-cases. The solution demonstrates a contemporary approach to the integration between Salesforce B2C Commerce and the Cloud products running on the Salesforce Customer 360 Platform. Modify the Account Manager Auth Token token type from UUID to JWT by [@jbachelet](https://github.com/jbachelet) in [#199](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/199) This is a significant update, as [UUID tokens are being deprecated and will stop working shortly](/the-deprecation-of-the-uuid-token-for-api-clients/)! --- ## Understanding SFCC Instances Canonical URL: https://rhino-inquisitor.com/understanding-sfcc-instances/ Markdown URL: https://rhino-inquisitor.com/understanding-sfcc-instances/index.md Content type: article Published: 2023-04-17T14:18:06Z Updated: 2023-04-17T14:18:18Z Summary: Salesforce B2C Commerce is a robust platform that enables businesses to create highly customised and scalable digital storefronts. Categories: Architecture, Salesforce Commerce Cloud Tags: architect, instance, sfcc, technical ## Key Takeaways - Explains the SFCC instance model across PODs, realms, PIGs, SIGs, and the main instance types - Shows how sandbox, development, staging, and production environments support different phases of storefront delivery - Maps common team roles to the instances they typically use, making the platform structure easier to understand operationally Salesforce B2C Commerce is a [robust platform](/the-salesforce-b2c-commerce-cloud-environment/) that enables businesses to create highly customised and scalable digital storefronts. One of the key components (and advantages) of B2C Commerce is the available instances, which contain the tools and resources needed for customising your storefront. This blog post will discuss the different types of B2C Commerce instances, their uses, and how different teams within your organisation can utilise them. ![Diagram showing how PODs, realms, and instances relate in Salesforce B2C Commerce.](/understanding-sfcc-instances/pod-realm-and-instances-transparent-65c6b4e389_hu_7216ae1734c3a0f3.webp) POD, Realm, Instances, and Domains ## POD (Point of Delivery) In Salesforce B2C Commerce, a Point of Delivery (POD) is a comprehensive infrastructure hosting a multi-tenant Software as a Service (SaaS) application. This infrastructure comprises computing, networking, and storage services, which work together to support the operation of the B2C Commerce platform. The POD architecture ensures that resources are allocated effectively to handle various tenants’ needs on the platform while maintaining high performance and availability. This approach allows businesses to focus on building and managing their digital storefronts without worrying about the underlying infrastructure. Salesforce takes care of maintaining the POD and ensuring its optimal performance. Deprecation This also means that [Salesforce makes crucial decisions on this infrastructure](/a-look-back-at-origin-shielding/) that must be considered during development. ## Realms A realm is an essential organisational component that houses instances required for developing, testing, and deploying your online storefront. Typically, a single realm is adequate for managing multiple sites with different branding or locales. This setup allows for flexible management, as individuals overseeing the storefront sites can be located in various places. However, consider using multiple realms if you have distinct lines of business, global teams with unique processes, or separate organisations with different backend integrations. While sites within the same realm can share product catalogs, sites in other realms cannot share data through the catalog structure. You can, however, set up a CI/CD system to automate the synchronisation of the data when working with multiple realms. ## PIG vs SIG Within a [realm](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/getting_started/b2c_platform_overview.html), instances are organised into Primary Instance Group (PIG) and Secondary Instance Group (SIG). The PIG comprises three instances: - Development - Staging - Production These are used for site configuration, testing, and hosting the live site. In the SIG, you will find the Developer Sandboxes. _**Note:**_ _Each realm can have only one PIG and SIG._ ## Instance Types There are four types of B2C Commerce instances: Sandbox, Staging, Development, and Production. Each instance type has a unique purpose and set of features, making it suitable for specific tasks within the development and management of your storefront. ### Sandbox ![A lone server rack illustrated in a desert landscape, representing an isolated sandbox environment.](/understanding-sfcc-instances/a-server-in-the-desert-v2-f8f32e48de_hu_42402c9967a4aff8.webp) Developers use sandbox instances to create and update storefront code. These instances are located in a secondary instance group (SIG) and have most system jobs disabled. Deletion Sandboxes without login activity for 150 days might be deleted, but Salesforce will notify you before this occurs. Though honesty, I never saw this happen on the old system, and with On-Demand sandboxes having become the default option, you are in total control. ### Staging The staging instance is where merchandising work takes place. This instance simulates the production environment and is used as the final step in testing the intersection of content and code. Staging instances are located in the realm’s primary instance group (PIG) and are ([since recently](/how-to-set-up-the-ecdn-in-sfcc-staging/)) connected to the eCDN. ### Development Development instances are used to replicate the production environment closely and are ideal for testing purposes. Like Staging instances, they are located in the PIG and have data and code replicated from the Staging instance. ### Production The production instance is the live environment used for storefront transactions. It is also located in the PIG and is connected to the eCDN provided by B2C Commerce. Caching Caching can not be disabled in this instance. ## Matching Roles with Instances Depending on the size of your team, one person may play more than one role. Here is a breakdown of the different roles within an organization and the instance types they typically use. ### Architect The role of an Architect in Salesforce B2C Commerce Cloud involves designing and implementing scalable, reliable, and high-performance solutions to meet the needs of the business. They work closely with stakeholders to understand requirements and develop technical solutions using best practices and industry standards. Architects also oversee the development and deployment of customisations, integrations, and extensions to ensure that they align with the overall architecture and roadmap of the platform. In terms of instances, Architects will be interacting will all instances that Salesforce has to offer. ### Developer Developers play a critical role in shaping a digital storefront’s look, feel, and functionality on the Salesforce B2C Commerce platform. They are responsible for creating and modifying templates, pipelines/controllers, and scripts that define the site’s user experience and overall performance. Developers primarily work with three instances: Sandbox, development, and staging. The Sandbox instance is a safe environment for developers to experiment with and test their code without affecting the live storefront or other instances. It is an isolated space where developers can create, modify, and debug their code to ensure proper functionality and compatibility with the rest of the system. ![Illustration of a developer working in a Salesforce B2C Commerce sandbox environment.](/understanding-sfcc-instances/woman-developer-working-on-a-project-1-4710b72058_hu_da0ec2aa5352ddcc.webp) Once developers are satisfied with their work in the Sandbox instance, they move on to the Staging instance. The Development environment is where developers upload their finalised code, which is subject to further testing and integration with the content created by merchandisers. This ensures the code and content work seamlessly before being deployed to the Production instance. Depending on your process, the content is first replicated to the Development instance and tested with the latest code before moving it into staging, where bugs in the code can disrupt the daily merchandising activity. Developers may also export data added by merchandisers on the Staging instance to use as test data for their Sandbox environments. This helps them develop and test their code with realistic data that reflects the actual content and structure of the live storefront. Developers play a collaborative role within the organisation, working closely with merchandisers, SEO engineers, administrators, and QA engineers. This collaboration ensures that all aspects of the digital storefront are well-coordinated, resulting in a seamless and high-quality user experience. ### Merchandiser A Merchandiser plays a vital role in creating and managing content for a digital storefront, such as campaigns, promotions, and product information. In the Salesforce B2C Commerce ecosystem, Merchandisers typically work within the Staging instance. The Staging environment allows Merchandisers to develop and refine their content strategies and marketing efforts without affecting the live storefront. They can also configure search behaviour to optimise the user experience. Once satisfied with their work, the changes are replicated in the Production instance for seamless integration. ### Quality Assurance Engineer A Quality Assurance (QA) Engineer is responsible for ensuring the optimal performance and functionality of a digital storefront before it goes live. In the context of Salesforce B2C Commerce, QA Engineers primarily work with the Development instance. The Development instance offers a close replication of the Production environment, allowing QA Engineers to test the site under conditions similar to the live storefront. By thoroughly examining the website’s features, design, and user experience, QA Engineers can identify and address any issues before they impact the end-users. ### SEO Specialist ![SEO Specialist reviewing search visibility results on a monitor showing the Google logo.](/understanding-sfcc-instances/seo-specialist-looking-at-google-1b930270d3_hu_8371a10e63cca63d.webp) An [SEO Engineer](/lets-go-live-seo/) is crucial in optimising a digital storefront for search engines, ensuring better visibility and higher organic traffic. Typically, an SEO Engineer will utilise the Staging instance to work on various aspects of search engine optimisation. SEOs can configure essential elements such as meta tags, sitemaps, and URL configurations in the Staging environment. These configurations are crucial for improving the website’s search engine rankings and overall online visibility. Once the SEO optimisations have been implemented and tested in the Staging instance, they will be replicated in the Production instance. After replication, the SEO Engineer must verify that the changes work as intended on the Production instance. This ensures that the optimisations made in the Staging environment are correctly applied and functioning in the live storefront. ## Conclusion Understanding the different types of Salesforce B2C Commerce instances and their specific uses is crucial for successfully managing and developing your digital storefront. By assigning the appropriate instance types to the relevant team members within your organization, you can ensure a streamlined and efficient development process, ultimately leading to a better end-user experience for your customers. --- ## Server-Side Caching for Faster SFCC REST APIs Canonical URL: https://rhino-inquisitor.com/caching-rest-apis-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/caching-rest-apis-in-sfcc/index.md Content type: article Published: 2023-04-10T06:46:06Z Updated: 2023-04-11T08:01:28Z Summary: Caching GET endpoints for the OCAPI in Salesforce B2C Commerce Cloud is possible, but where do you start? Let us dig into this together! Categories: Salesforce Commerce Cloud, Technical Tags: cache, ocapi, sfcc, technical ## Key Takeaways - Explains which OCAPI Shop API resources support server-side caching and which do not - Shows how page cache and OCAPI settings control cache duration and personalization - Clarifies why SCAPI cache control is more limited and where custom caches help instead The [OCAPI](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/OpenCommerceAPI.html?cp=0_16) has been around for a long time (2016) and allows you to cache responses to increase performance. **By default, GET responses that support caching are cached for 60 seconds**, but can this be improved? ## What can be cached in the OCAPI Before we start, we must understand that not all API endpoints support caching. But which ones do? - [Meta API](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/Metadata.html) - [Categories](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/Categories.html?cp=0_16_3_1) - [Content](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/Content.html?cp=0_16_3_2) - [ContentSearch](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/ContentSearch.html?cp=0_16_3_3) - [CustomObjects](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/CustomObjects.html?cp=0_16_3_5) - [Folders](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/Folders.html?cp=0_16_3_6) - [Products](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/Products.html?cp=0_16_3_12) - [ProductSearch](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/ProductSearch.html?cp=0_16_3_13) - [Promotions](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/Promotions.html?cp=0_16_3_14) - [SearchSuggestion](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/SearchSuggestion.html?cp=0_16_3_15) - [Site](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/Site.html?cp=0_16_3_17) - [Stores](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/Stores.html?cp=0_16_3_18) This is quite an extensive list and contains all the objects we would expect to support caching! > Only GET calls can be cached. > The Data API does not support caching at all. ## Page Cache An important thing to remember before starting to tinker with the [Shop API](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/ShopAPIResources.html) (part of the OCAPI) caching is to enable the “[Page Cache](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_development/b2c_configure_page_cache.html)” for the site you will be working with. If the Page Cache is disabled, you will see this header value on every response: ```text cache-control: no-cache, no-store, must-revalidate ``` This is easy to fix. But without enabling it, you cannot test your settings on a sandbox where this is usually disabled. > It is not possible to clear the Page Cache for the OCAPI only, it will take your storefront (SiteGenesis/SFRA) with it. Clearing the page cache can create a heavy load on the application servers. Only clear the page cache manually when necessary, and avoid clearing it during times of high traffic. ## Overriding the OCAPI Cache Time It is possible to override the default 60 seconds of caching of an resource by adding it to the [OCAPI Settings](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/OCAPISettings.html?cp=0_16_2_24) in the Business Manager. _“Administration” > “Site Development” > “Open Commerce API Settings”_ [![OCAPI caching settings](/caching-rest-apis-in-sfcc/ocapi-settings-with-cache-f7e7acfcf8_hu_63366423905add0.webp)](ocapi-settings-with-cache-f7e7acfcf8.png) OCAPI resource cache\_time settings ```json { "_v": "22.6", "clients": [ { "client_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "allowed_origins": [], "resources": [ { "resource_id": "/categories/*", "methods": [ "get" ], "read_attributes": "(**)", "cache_time": 900 }, { "resource_id": "/customers/auth", "methods": [ "post" ], "read_attributes": "(**)", "write_attributes": "(**)" }, { "resource_id": "/product_search", "methods": [ "get" ], "read_attributes": "(**)", "write_attributes": "(**)", "cache_time": 86400 } ] } ] } ``` Adding “cache\_time” to the resource configuration lets you easily control the time responses are cached. You can set a **maximum value of 86.400 seconds** (1 day). ### “Expand” parameter Lowest Cache Time When using the expand parameter to make a single request with the Open Commerce API, the Cache-Control header is automatically populated with the lowest caching time of the requested resources. [![OCAPI: Expand Parameter Caching](/caching-rest-apis-in-sfcc/ocapi-expand-parameter-caching-c91c7001dd_hu_d3be2b7d525bf897.webp)](ocapi-expand-parameter-caching-c91c7001dd.jpg) Expand parameter cache-time rule Screenshot of the Infocenter about the “expand” parameter ## Personalized Caching Personalized caching is enabled by default based on the customer context (JWT). It is possible to disable this for a resource to improve performance. ```json { "_v": "22.6", "clients": [ { "client_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "allowed_origins": [], "resources": [ { "resource_id": "/product_search", "methods": [ "get" ], "read_attributes": "(**)", "write_attributes": "(**)", "cache_time": 86400, "personalized_caching_enabled": false } ] } ] } ``` By setting the “personalized\_caching\_ enabled” option to false, personalization will be disabled for that resource. > You can find information about other options (not related to caching) for resources in the [Infocenter](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/OCAPISettings.html). ## SCAPI (Salesforce Commerce API) Currently, you can’t control the server-side cache times of SCAPI. All known approaches from the OCAPI Shop API (for example, setting cache times in the OCAPI settings) don’t apply to the [Salesforce Commerce API](https://developer.salesforce.com/docs/commerce/commerce-api/guide). ### Custom Caches to the rescue (for hooks) [Custom caches](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/caches/b2c_custom_caches.html) are user-defined in Salesforce B2C Commerce Cloud, allowing developers to store and retrieve data efficiently. They can be used to cache frequently accessed data, reducing the load on the server and speeding up response times for SCAPI REST APIs where [hooks](/how-to-use-ocapi-scapi-hooks/) have been implemented. Here are some ways custom caches can be used to speed up responses in the SCAPI REST APIs that have customisations: 1. **Reducing database queries:** If an API call requires fetching data from the database, custom caches can help store the data in memory. This way, when subsequent API calls are made, the data can be quickly retrieved from the cache instead of querying the database again. 2. **Complex Calculations:** Sometimes, processing API requests may involve complex calculations or transformations. Custom caches can store the results of these calculations, allowing subsequent requests to retrieve the cached data instead of re-computing the results. 3. **Third-party API responses:** If your SCAPI REST APIs depend on third-party APIs, custom caches can help store the responses from these external APIs, reducing latency and improving performance. ## OCAPI Caching Best Practices There is a lot of information and best practices available on the [Infocenter](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/BestPractices.html?cp=0_16_2_2). --- ## Get the Request Body in an SFCC Controller Canonical URL: https://rhino-inquisitor.com/the-request-body-in-an-sfcc-controller/ Markdown URL: https://rhino-inquisitor.com/the-request-body-in-an-sfcc-controller/index.md Content type: article Published: 2023-04-03T06:57:02Z Updated: 2023-04-03T06:57:14Z Summary: Learn how to retrieve the request body in an SFCC controller and when that pattern helps with custom endpoints and integrations. Categories: Salesforce Commerce Cloud, Technical Tags: api, sfcc, technical ## Key Takeaways - Shows the simplest way to read an HTTP request body inside an SFCC controller using requestBodyAsString - Explains how that pattern fits custom controller endpoints handling POST or PUT payloads - Highlights the need for parsing, validation, and error handling when accepting request data from external clients [Custom endpoints](/creating-custom-ocapi-endpoints/) are a way to create personalised solutions that meet the needs of a particular business. If we are working with POST or PUT requests, developers need to be able to access and handle the submitted data within an SFCC controller. But where can we find this [request body](https://en.wikipedia.org/wiki/HTTP_message_body)? ## TLDR [![Example code in SiteGenesis of accessing the Request Body in the COPlaceOrder controller.](/the-request-body-in-an-sfcc-controller/reques-body-sfcc-00c1f40887_hu_b61e48bd076d8ec9.webp)](/the-request-body-in-an-sfcc-controller/reques-body-sfcc-00c1f40887.jpg) To get the request body in an SFCC controller, use the following script: ```text request.httpParameterMap.requestBodyAsString ``` This attribute will provide a string representation of the request data, which can then be parsed and processed. Global Variable “request” is a [global variable](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_global.html) available everywhere in the back end. ## Understanding SFCC Controllers and Body In the context of SFCC, a controller is a script module that takes care of processing various HTTP requests and generating suitable responses. Controllers are typically used to implement server-side logic for various user interactions, such as adding items to the cart or processing payments. The request body is part of an HTTP request containing the client’s data to the server. In the case of an e-commerce platform, this might include information such as item details or a query. ## Accessing submitted data in an SFCC Controller To access the body in an SFCC controller, you must use the “[request](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_system_Request.html)” object provided by the controller’s execution context. This object represents the incoming HTTP request and provides various attributes and methods for accessing request data. The “request.[httpParameterMap](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_web_HttpParameterMap.html)” attribute is a collection of all input parameters received in the HTTP request. This includes query parameters, form parameters, and the request body. You can use the “[requestBodyAsString](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_web_HttpParameterMap.html#dw_web_HttpParameterMap_getRequestBodyAsString_DetailAnchor)” attribute to access the request body. This attribute provides a string representation of the request body, allowing you to parse and process the data as needed. Here’s an example of how to use the “request.httpParameterMap.requestBodyAsString” attribute to access the request body inside a basic SFCC controller (without the SFRA wrapping): ```js var ISML = require('dw/template/ISML'); function start() { var requestBody = request.httpParameterMap.requestBodyAsString; // Process the request body here // Render the response ISML.renderTemplate('mytemplate', { requestBody: requestBody }); } exports.Start = start; ``` The “requestBodyAsString” attribute gets the request body as a string (what’s in a name). You can then process the value as needed, such as parsing it into a JSON object or using it to perform server-side validation. ## Parsing the data In many cases, the request body will be a JSON string that needs to be parsed into a JavaScript object. You can use the “JSON.parse()” method to do this. Here’s an example of how to parse these requests into a JSON object: ```js var requestBody = request.httpParameterMap.requestBodyAsString; var requestBodyJson = JSON.parse(requestBody); ``` ## Handling Errors ![Border API security check result shown before the request-body error-handling example.](/the-request-body-in-an-sfcc-controller/security-check-border-api-security-5695d3d810_hu_e6c3903079a6e765.webp) When working with data being submitted to the server, handling any errors that might occur, such as malformed JSON or an invalid request, is essential. You can use a try-catch block to catch any exception thrown during the processing of the request body. Here’s a basic example of how to handle errors: ```js var requestBody = request.httpParameterMap.requestBodyAsString; var requestBodyJson; try { requestBodyJson = JSON.parse(requestBody); } catch (error) { // Handle the error, such as sending an error response or logging the error } ``` Validation It is always a good idea to have some validation of the made request, such as: - **Structure of the request (contract):** Does it contain all required fields, and are they the correct type? - **Values:** Validate the minimum and maximum length of the field and if they follow a certain structure (e.g. email, phone, address, …) - **Rate Limiting:** The SCAPI may come with rate limiting, but you don’t want the eCDN to be fully in charge of your controller limits, right? ## Conclusion API-first development has been long-awaited in the Salesforce B2C Commerce Cloud world, but that time is finally upon us. By creating custom endpoints, either with the OCAPI (hopefully soon the SCAPI) or with custom controllers, we can add new features to Headless storefronts such as the Composable Storefront. And in a transactional context, we will need that request body! --- ## Salesforce Payments Explained Canonical URL: https://rhino-inquisitor.com/salesforce-payments-experience-explained/ Markdown URL: https://rhino-inquisitor.com/salesforce-payments-experience-explained/index.md Content type: article Published: 2023-03-27T14:54:22Z Updated: 2023-03-31T07:19:52Z Summary: Understand what Salesforce Payments changes for SFCC integrations, checkout design, and the overall payment implementation path. Categories: Salesforce Commerce Cloud Tags: payment, sfcc ## Key Takeaways - Explains what Salesforce Payments is, how it wraps Stripe, and where it reduces custom integration effort in SFCC - Highlights the trade-offs around control, payment-method coverage, composable storefront support, and future multi-cloud value - Gives teams a practical starting point for evaluating Salesforce Payments against third-party PSP cartridges As a [Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/) connoisseur, you know how important it is to have a seamless customer payment process. After all, a clunky checkout experience can result in abandoned carts and lost sales. But what exactly is [Salesforce Payments](https://trailhead.salesforce.com/content/learn/modules/cc-commerce-payments) - or [Commerce Payments](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/salesforce_payments/b2c_salesforce_payments.html), and how can it benefit you with the payment provider implementation? In this article, we’ll explore the ins and outs of Salesforce Payments, from its features and benefits to the integration. ## A plugin ![Salesforce Payments interface inside Business Manager.](/salesforce-payments-experience-explained/salesforce-payments-business-manager-6773ef14af_hu_c81199e8e71710cf.webp) Salesforce Payments is an optional “plugin” consisting of a native Business Manager interface and cartridge that provides native integration with the payment provider “[Stripe](https://stripe.com/)”. Since this payment provider may not apply to all projects, you are not forced to enable and use it. But if you are still in the process of selecting a Payment Service Provider, this is a strong contender to consider. But hold off on deciding until you have read this article. ### Stripe If you’re a developer working with e-commerce platforms, you’ve likely heard of Stripe, a technology company that provides an online payment processing platform. Founded in 2010 by brothers [Patrick](https://en.wikipedia.org/wiki/Patrick_Collison) and [John Collison](https://en.wikipedia.org/wiki/John_Collison), Stripe has become one of the world’s most widely used payment gateways, processing billions of transactions yearly. One of the reasons for Stripe’s popularity is its ease of use and straightforward APIs. But Stripe is more than just popular because it’s easy to use. The platform also offers a range of advanced features, such as support for multiple currencies, fraud prevention tools, and powerful analytics capabilities. Another factor that has contributed to Stripe’s success is its commitment to innovation. The company constantly releases new features and updates to its platform, ensuring it stays at the forefront of the rapidly evolving e-commerce landscape. And with the integration of Salesforce Payments, companies can take advantage of Stripe’s capabilities directly within the Salesforce platform. ## Salesforce Payments The key benefit of integrating Salesforce Payments into your e-commerce project is the ability to manage payments directly within the Salesforce platform. That way, you can easily set up and manage payment methods and view payment information within a single, unified platform. This out-of-the-box integration can help save time and reduce the need for custom development work, allowing developers and businesses to focus on other aspects of their e-commerce projects. If you want a quick visual overview, watch the Business Manager demo recording: [Business Manager demo recording](/salesforce-payments-experience-explained/salesforce-payments-business-manager-sfcc.mp4) ### New features added regularly Usually, when you integrate with a payment provider, updates happen to their APIs - but it is still your responsibility to implement them. With Salesforce Payments, new features get added regularly. Let us have a look at the past few months: - [23.4 - Extend Payment Processing with Salesforce Payment APIs](/everything-new-in-sfcc-23-4/) - [23.3 - Buy Now Items Get Their Own Cart](/salesforce-b2c-commerce-cloud-23-3-release/) - [23.2 - Set Up Payments for Immediate or Future Payment Capture](/salesforce-b2c-commerce-cloud-23-2/) - [23.1 - Orders from Stored Information with Salesforce Payments](/salesforce-b2c-commerce-cloud-23-1/) - [22.7 - AfterPay and Venmo added to Salesforce Payments](/salesforce-b2c-commerce-cloud-22-9-release/) #### Double-Edged Sword As you may already know, the checkout process plays a crucial role in the customer journey. However, by using Salesforce Payments, you surrender some control, and if any changes are made, you’ll have to adjust accordingly. Nevertheless, this is the norm for the entire platform, and Salesforce is highly proficient in this field. It’s simply a factor to be mindful of and to monitor by reviewing the release notes and known issues. ### Missing payment methods You may have noticed that Salesforce Payments [only supports some payment methods](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/salesforce_payments/b2c_salesforce_payments_platforms_services.html) available on Stripe. This is an important consideration when selecting a payment provider for your current and future projects. Keep this in mind! ### Combining with other payment providers I talked about the “Double-Edged Sword” before, but it’s even more important to keep in mind if you’re considering adding more payment providers later. With most payment providers, you can get your hands on the source code for their cartridge and customise it however you want, even combining it with other providers. But you have less control over Salesforce Payments, which could cause you to hit a wall or two before coming to a solution. ### Composable Storefront Currently, there is no readily available integration for the [PWA Kit,](/sitegenesis-vs-sfra-vs-pwa/) a component of the Composable Storefront. However, plans are in place to include this integration in the future. ### Multi-Cloud (the future) Do you have multiple Salesforce products in your architecture, such as Order Management? In that case, Salesforce payments will have the added benefit of being available and integrated out of the box in the future! The roadmap of Salesforce payments is filled with multi-cloud journeys! (Forward-looking statement 😅) ## How to get started ![Salesforce Payments promotional artwork introducing the getting-started resources.](/salesforce-payments-experience-explained/salesforce-payments-7926558e4f_hu_d7213e64a6fbdaa6.webp) For those familiar with my articles, I am not one to start reinventing (and writing) the wheel. And in this case, a rare one for B2C Commerce Cloud, Trailheads are available! - [Quick Look](https://trailhead.salesforce.com/en/content/learn/modules/cc-payments-processing) - [Salesforce Payments for Administrators](https://trailhead.salesforce.com/en/content/learn/modules/cc-commerce-payments) - [Official Salesforce Payments Product Page](https://www.salesforce.com/products/commerce-cloud/solutions/payments/) - [Documentation](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/salesforce_payments/b2c_salesforce_payments.html) - [Demo](https://www.salesforce.com/form/commerce/conf/payments-demo?leadcreated=true&redirect=true&sfuuid=31472534-1e3c-4b8a-a90a-9156e45c6e61&d=70130000000sUVq&nc=7013y000002KFkZAAW) Support Ticket As usual, this feature must be enabled on your environment through a support ticket if you are a partner (on a sandbox, for example). As a customer, please contact your CSM to get the ball rolling! ## Other options As mentioned, Salesforce provides this as an option - not a pre-requisite. You still have the freedom to integrate [any PSP your heart desires](https://appexchange.salesforce.com/category/payment). But does that mean more custom development is needed to integrate them? The short answer is no, but it depends on whether they provide a cartridge (third-party plugin). The most significant difference will be the need for integration in the Business Manager. You will have to configure the different payment options in a separate interface unless a payment provider decides to write a custom-built Business Manager module too. But for most, the benefits of this fully-fledged custom-built administrative module outweigh the cost of development and keeping it up to date (at least, that is my speculation). But, of course, nothing stops you from building it yourself - if time and budget are available, that is. Here is a list of Payment Service Providers that have a storefront cartridge available, which will ultimately mean less development to get it up and running: - [Adyen](https://www.adyen.com/) - [Mollie](https://www.mollie.com/be) - [CCV](https://www.ccv.eu/en/) - [Braintree](https://www.braintreepayments.com/) - [Worldline](https://www.six-payment-services.com/en/site/e-commerce/solutions/paymentsolution.html) - [Stripe](https://stripe.com/) (yes, you can do the integration yourself) - Many, many more! ## Conclusion By leveraging Salesforce Payments, you can provide customers with various payment options, reduce the need for custom development work (and the complexity), and streamline the payment processes. --- ## A New Day for Commerce: Recap Canonical URL: https://rhino-inquisitor.com/a-new-day-for-commerce-recap/ Markdown URL: https://rhino-inquisitor.com/a-new-day-for-commerce-recap/index.md Content type: article Published: 2023-03-20T07:55:32Z Updated: 2023-03-21T09:44:52Z Summary: A recap of A New Day for Commerce and what the event says about Salesforce's broader commerce direction, ecosystem momentum, and priorities. Categories: Community Tags: ohana, sfcc, trailhead ## Key Takeaways - Recaps the first European A New Day for Commerce event and its community value - Compares the event with Connections and TrailblazerDX for commerce audiences - Highlights where future editions should improve developer visibility and session depth When we look at the Salesforce [eco-system](/the-state-of-ohana-for-salesforce-commerce-cloud/), Commerce seems like a speck on the entire Salesforce landscape (CRM). Luckily, when going to Salesforce events such as Connections, much attention is given to Commerce. But all that attention takes place in the [United States](/20-years-of-dreamforce/). For many customers and partners, this is quite a ways out, meaning that a large part of the community is not being represented and allowed to network and learn at these large-scale events. Come into play ‘A New Day for Commerce’, a dedicated Salesforce event for Commerce Cloud in Europe! And big things start small, so let’s recap the first edition! But first, a history lesson. ## History & Salesforce Events ### Demandware XChange ![Demandware XChange 2015 event website.](/a-new-day-for-commerce-recap/demandware-xchange-2015-6b0d29c1ff_hu_26a88d136a23a8c1.webp) The old XChange brand shows how long this community has been reinventing itself. Before the acquisition of Salesforce, there were events in the United States and Europe dedicated to just Demandware, which was interesting for any customer, partner and developer! The agenda had something for everyone: - Existing and potential Demandware customers - Architects - Developers That resulted in various parts of the community attending the event: Going from business to deeply technical. But after the acquisition, this event disappeared and became (I assume) ‘[Connections](https://www.salesforce.com/connections/)’, a US-only event not dedicated solely to Salesforce B2C Commerce Cloud. And since there is a vast community of customers and partners in Europe, they were suddenly cut off from this local event. But now, after six years - there is a speck of light at the end of the tunnel! ### Connections Don’t get me wrong, even if it is not a dedicated event to Salesforce B2C Commerce Cloud - there is a lot to do and a fantastic place to connect with peers and to learn. But as a developer, you might return disappointed if you went to learn more about [B2C Commerce Cloud development and architecture](/the-salesforce-b2c-commerce-cloud-environment/). If you look at last year’s agenda, there were only a few technical presentations. But Connections is not advertised as a developer conference; TrailblazerDX is - but I’ll get to that in a second. Go with the right expectations (for me, mainly networking and high-level feature/roadmap knowledge). It can be a fantastic event and well worth the travel and expenses that come with it. And it will always have a special place in my heart, having been allowed to tell my story on the main stage and getting that [Golden Hoodie](/events-and-the-golden-hoodie/)! ### TrailblazerDX Talking about a developer conference, bring in [TrailblazerDX](https://www.salesforce.com/trailblazerdx/)! But unfortunately, as I mentioned before, Commerce is not the most considerable speck on the map that is Salesforce. This year there were only three sessions and no Commerce keynote. It’s challenging to convince your boss to allow you to attend this event as a Salesforce Commerce Cloud developer in Europe. ## A New Day for Commerce ### Short Notice and ‘small’ Any new event, Salesforce or Community, must feel the waters before going full-blown. “Go big or go home” doesn’t apply as such events don’t come cheap to organise and require much preparational work. So at the end of January, the registration page went live for March! Just over a month in advance, which leaves little time for people to clear their schedules, book a hotel and make travel arrangements. Nevertheless, the event quickly sold out with a limit of only 500 people (the venue capacity). I even heard people from around Europe had to be turned down, which is “technically” a good sign. ### The products As it is a dedicated event to Salesforce Commerce Cloud, you need to distinguish it from B2C Commerce Cloud. The event itself was tailored to all of the different products that make out the portfolio of Salesforce: - B2C Commerce Cloud - B2B Commerce Cloud - D2C Commerce Cloud - Order Management - Marketplaces - Payments This is a good thing as many of these products have been becoming increasingly interconnected over the years - and for people who have read my articles before, I like to broaden my horizons. ### Sales, technical, community ![Thomas Theunen, Igor Faletski, and Sander Felius during the fireside chat.](/a-new-day-for-commerce-recap/fireside-chat-a-new-day-for-commerce-cd97b9b2c7_hu_c26932e7a29fded0.webp) The fireside chat was one of the moments where the event felt smallest and most useful. In the first place, the event was designed to be your standard Salesforce event to pitch the product to potential customers and show off the array of products available to existing customers looking to expand their horizons. But there were already some pieces to support the architect and developer community. We had a dedicated developer (community) lounge for people to mingle and talk tech. There was also a Fireside chat with [Igor Faletski](https://www.linkedin.com/in/igorfaletski/) planned to ask any questions about the Composable Storefront and the different buzzwords that go with it. Did all of the community and technical stuff go as planned? No, definitely not. The goal of the developer lounge needed to be made more transparent, the technical fireside chat was not mentioned in any of the planning screens and flyers, and the lounge was hidden away. Nevertheless, people showed up for the Fireside Chat (some probably by accident), and I had a great time. I could talk to many people and network. ### Sessions ![A panel of four people sitting in front of a presentation about VidaXL at 'A New Day for Commerce'.](/a-new-day-for-commerce-recap/vidaxl-forward-a-new-day-for-commerce-e15a8ef783_hu_c68858dc158e3d6c.webp) Real implementation stories gave the conference more weight than marketing slides ever could. I mentioned before that, for the most part, it is a Sales event and only for the afternoon (2PM - 5PM). This meant there was not enough time for many different sessions. But each product had at least one dedicated session about the latest features and one technical Composable Firechat. And as it is with every Salesforce event, an opening keynote showing off the roadmap(s) of the different products and some customer case presentations. ### Salesforce ![Commerce Cloud leadership and community attendees gathered in Amsterdam.](/a-new-day-for-commerce-recap/a-new-day-for-commerce-community-2cc42304c9_hu_d2596809a25da9f5.webp) What stood out most was how much of the room felt like community rather than customers. One of the biggest things that should be mentioned is that a large part of Commerce Cloud leadership had crossed the pond to be present in Amsterdam: - [Michael Affronti](https://www.linkedin.com/in/michaelaffronti/) (SVP & General Manager) - [Luke Ball](https://www.linkedin.com/in/lukeball/) (SVP Product Management) - [Igor Faletski](https://www.linkedin.com/in/igorfaletski/) (VP of Product Management & Mobify Founder) - [Kelly Thacker](https://www.linkedin.com/in/kellyhautjames/) (SVP, Product Marketing & CMO, Retail & Consumer Goods) And some closer to home: - [Gurpreet Kaur](https://www.linkedin.com/in/gkaur2/) (Director PMM EMEA) - [Mike Kolman](https://www.linkedin.com/in/mikekolman/) (Senior Product Marketing Manager EMEA) - [Christian Sylvestre](https://www.linkedin.com/in/christiansylvestre/) (RVP Commerce Practice Leader Northern Europe) - [Sander Felius](https://www.linkedin.com/in/sanderfelius/) ( Senior Technical Architect ) This meant there was a large gathering of people you could network and talk shop with! _It was also a big reminder of how bad I am at remembering faces and names, sorry \_ \_ everyone!_ ## Next year I would like to see this event happen annually. It’s widely agreed that Europe needs a specialised [Salesforce Commerce Cloud](/the-state-of-ohana-for-salesforce-commerce-cloud/) event, and there’s significant interest within the community to participate! This will likely happen if all of the boxes that Salesforce expected from this event have been checked. But some improvements can happen: - Announced more in advance - A bigger venue - The agenda/folders should include the developer session(s) - More developer sessions! 💯 - The developer (community) lounge needs to be manned and more inviting 🙈 --- ## Everything new in Salesforce B2C Commerce Cloud 23.4 Canonical URL: https://rhino-inquisitor.com/everything-new-in-sfcc-23-4/ Markdown URL: https://rhino-inquisitor.com/everything-new-in-sfcc-23-4/index.md Content type: article Published: 2023-03-15T19:32:56Z Updated: 2023-03-15T19:51:03Z Summary: Catch up on the Salesforce B2C Commerce Cloud 23.4 release and the platform changes that matter most for developers this month. Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc, technical ## Key Takeaways - Highlights the main 23.4 updates across payments, taxation, Page Designer, and hybrid deployment - Explains why new CDN origin APIs matter for phased SFRA to PWA rollouts - Flags Node and PWA Kit upgrade pressure tied to Managed Runtime support windows As the clock ticks on a new month has arrived, and with that the next [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/) release! This time we look at the [April 2023 (23.4) release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_23_4_release.htm&language=en_US&type=5)! Are you interested in last month’s release notes? [Read the 23.3 release notes](/salesforce-b2c-commerce-cloud-23-3-release/)! ## Platform ### Extend Payment Processing with Salesforce Payment APIs > Use the new Salesforce Payment APIs to connect with third-party order management systems or platform-specific custom features. The APIs support capture, cancel, refund, and updates. For example, you can directly cancel or refund a payment in an order failure event by cleaning up payment authorizations. The APIs are available as Script APIs. Salesforce Payments continues to gain love from Salesforce with every new release. The [previous release](/salesforce-b2c-commerce-cloud-23-3-release/) included the addition of four temporary baskets, and this release introduced support for numerous new customer flows. Here is a list of all of the new APIs made available: - **SalesforcePaymentIntent** - getClientSecret() - isCancelable() - isRefundable() - **SalesforcePaymentsMgr** - cancelPaymentIntent(SalesforcePaymentIntent, Object) - capturePaymentIntent(SalesforcePaymentIntent, Money) - createPaymentIntent(Basket, Shipment, String, Money, Boolean, Object) - refundPaymentIntent(SalesforcePaymentIntent, Money, Object) - updatePaymentIntent(SalesforcePaymentIntent, Shipment, Money, String, Object) ### Grouped Taxation Applied to Import and Export Orders ![SFCC 23.4 Release: Taxation Groups](/everything-new-in-sfcc-23-4/sfcc-taxation-groups-5ebd5c5015_hu_5125e2d2eed53aa0.webp) Figure 1: SFCC 23.4 Release: Taxation Groups > B2C Commerce now recognizes imported and exported orders created with group taxation and uses the group taxation method to calculate tax for those orders. Import and export support has been incorporated, building on another feature [released in February](/salesforce-b2c-commerce-cloud-23-2/) to offer greater control over taxation in Japan. ## Business Manager ### Track Page Designer Rendering Performance > When editing in Page Designer, the page, region, and component rendering performance is now logged in your browser’s developer console. You can use the log to identify bottlenecks and optimise the rendering speed. Page Designer’s performance has been criticised for some time, particularly when utilising multiple component types on a single page. Salesforce has been [working diligently](/salesforce-b2c-commerce-cloud-23-2/) to enhance the user experience in Business Manager, and with this release, developers are also receiving some attention. Performance metrics will now be logged in the developer console, offering insight into areas where improvements can be made on things developers can control. ## OCAPI & SCAPI ### Configure Origin Rules with CDN Zone APIs > Configure Phased headless rollouts of SFRA to PWA implementations with the new CDN Zone APIs. You can now migrate specific pages to a PWA origin without completely switching from SFRA to PWA. You can also create and update origin rules to direct traffic to a PWA origin. Good news for live and in-development projects who have chosen to go the “hybrid deployment” route. Untill now we had to create support tickets to manage the rules of which pages (URLs) were rendered by what system. From this release on, we can manage all of this with a new set of APIs: - [getMrtRules](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=getMrtRules%22getMrtRules-HTML%28NewWindow%29%22) - [createMrtRules](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=createMrtRules%22createMrtRules-HTML%28NewWindow%29%22) - [updateMrtRule](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=updateMrtRule%22updateMrtRule-HTML%28NewWindow%29%22) - [updateMrtHostname](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=updateMrtHostname%22updateMrtHostname-HTML%28NewWindow%29%22) - [deleteMrtRuleset](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=deleteMrtRuleset%22deleteMrtRuleset-HTML%28NewWindow%29%22) - [deleteMrtRule](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=deleteMrtRule%22deleteMrtRule-HTML%28NewWindow%29%22) ### SLAS Database Update (03/07/2023) > We are upgrading our Postgres database to the latest version, due to a mandate from AWS. This maintenance will be performed during off hours for your region when there is little to no traffic. The upgrade is expected to take up to ~9 minutes, and you may experience slowness but not downtime during this period. Whether you know this or not, SLAS runs as a separate service next to the SFCC Platform. This has many advantages, including a different maintenance window and fewer dependencies on the core platform. In this case, the database has been updated from 14.1 to 14.6, as mandated by AWS. ## New Ideas I had another look at the IdeaExchange and found some interesting new submissions: - [Bulk or Auto Run/Refresh Dynamic Categorization Rules](https://ideas.salesforce.com/s/idea/a0B8W00000NXb63UAD) - [User Search, Auditing, and Improved Filtering in SFCC Account Manager](https://ideas.salesforce.com/s/idea/a0B8W00000NY1OZUA1/user-search-auditing-and-improved-filtering-in-sfcc-account-manager) - [OMS integration status](https://ideas.salesforce.com/s/idea/a0B8W00000NLdunUAD/oms-integration-status) ## PWA Kit v2.7.0 The [latest updates](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v2.7.0) bring some previously announced changes to the PWA Kit, such as [Page Designer](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/develop/packages/template-retail-react-app/app/page-designer/README.md#sample-usage) and support for Product Sets. Here are some recordings by Salesforce made available explaining these new features: [Page Designer demo](/everything-new-in-sfcc-23-4/pwa-kit-page-designer.mp4) [Product Sets demo](/everything-new-in-sfcc-23-4/product-sets-244-mid-release-demo.mp4) But the most significant change that marks the start of the upgrade required in the future version 3.0 is the update from Node 14 to Node 16. Managed Runtime In light of the Node community end-of-life, Node 14 will be deprecated on Managed Runtime by April 30, 2023. To ensure seamless continuity of service, users are encouraged to upgrade to Node 16 and v2.7.+ of the PWA Kit ahead of the deprecation date. Start planning the upgrade to get the latest features and ensure optimal performance. ## Bugfixes Having searched the “Known Issues” section, I found it difficult to determine if any of the issues listed had been resolved due to the new layout and frequent updates to older topics. ## Updated Cartridges & Tools ### b2c-tools (v0.16.0) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances and administrative APIs (SCAPI, ODS, etc). It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. - support feature dependencies by [@clavery](https://github.com/clavery) in [#102](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/102) - this is a BREAKING change from 0.15.4 in the feature script callbacks for those who use the second argument (you know who you are). ### Passwordless Login(v1.1.1) - [https://github.com/SalesforceCommerceCloud/plugin\_passwordlesslogin](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin) > Passwordless login is a way to verify a user’s identity without using a password. It offers protection against the most prevalent cyberattacks, such as phishing and brute-force password cracking. Passwordless login systems use authentication methods that are more secure than regular passwords, including magic links, one-time codes, registered devices or tokens, and biometrics. - [#9](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin/issues/9) fix isStorefrontSession by [@sandragolden](https://github.com/sandragolden) in [#10](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin/pull/10) - ref same issue in `plugin_slas`: [SalesforceCommerceCloud/plugin\_slas#91](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/91) --- ## AI Automation to Augmentation: Its new role in the workplace Canonical URL: https://rhino-inquisitor.com/ai-automation-to-augmentation-at-work/ Markdown URL: https://rhino-inquisitor.com/ai-automation-to-augmentation-at-work/index.md Content type: article Published: 2023-03-13T07:15:33Z Updated: 2023-03-15T07:28:13Z Summary: A practical look at how AI is shifting from pure automation to workplace augmentation, and what that change means for teams and delivery. Categories: Corporate Tags: ai, technical ## Key Takeaways - Argues AI is shifting from pure automation toward augmenting workplace decision-making - Balances productivity gains against privacy, bias, and accuracy concerns - Uses Salesforce Commerce Cloud examples to show where AI can remove repetitive work As I walked into my office, I couldn’t help but notice [a particular AI chatbot dominating the workspace](/what-can-i-use-chatgpt-for-when-working-with-salesforce/). The tomorrow of work had arrived, and it was clear that this new era would require us to adapt. Artificial Intelligence (AI) has come a long way, especially in the last year (at least in a readily usable way). It has gained quite some ground in many places, including the workplace. And the benefits are undeniable: increased efficiency, improved accuracy, and cost savings, to name a few. But with these benefits come [challenges](https://openai.com/blog/new-ai-classifier-for-indicating-ai-written-text/), such as potential job displacement, algorithm bias, and privacy concerns. As we look to tomorrow, it’s clear that the use of AI in the workplace will only continue to grow. So we need to start adapting now to realise its full potential. In this article, we will explore the benefits and challenges of AI in the workplace and the steps we can take to prepare. So buckle up because the future of work is here, and it’s time to adapt. ## What is AI ![Salesforce Einstein branding used to introduce workplace AI.](/ai-automation-to-augmentation-at-work/salesforce-einstein-c26c4593ed_hu_68bc7e3118dcdd6d.webp) AI, or [Artificial Intelligence](https://en.wikipedia.org/wiki/Artificial_intelligence), is a technology that enables machines to perform tasks that would typically require human intelligence. Some examples are speech recognition, decision-making, and language translation. AI automates and streamlines various tasks in the workplace, such as data entry, customer service, and accounting. Customer service chatbots can help customers with their queries. At the same time, AI algorithms can analyse large data sets to identify patterns and trends, enabling businesses to make better decisions. AI is also used to assist us with tasks, like providing recommendations based on data analysis or even predicting equipment failures before they occur. The potential applications of AI are nearly limitless, and we are only scratching the surface of what’s possible. As technology advances, we will see even more ways to use it to improve productivity and efficiency in the workplace. ## Benefits of AI in the workplace The benefits of Artificial Intelligence in the workplace are particularly relevant to tasks such as data entry and creation, where the technology can significantly improve efficiency. AI-powered systems can quickly and accurately process large amounts of data, reducing our workload and enabling us to focus on more critical tasks. ### Benefits for Salesforce B2C Commerce Cloud A good example is [the recent plugin I wrote](https://www.forward.eu/blog/the-power-of-openai-and-commerce-cloud/) for Salesforce Commerce cloud with the following features: - **Generate HTML in Content ([Page Designer](https://documentation.b2c.commercecloud.salesforce.com/DOC3/topic/com.demandware.dochelp/content/b2c_commerce/topics/page_designer/b2c_what_is_page_designer.html) / [Assets](https://documentation.b2c.commercecloud.salesforce.com/DOC3/topic/com.demandware.dochelp/content/b2c_commerce/topics/content/b2c_content_assets.html)):** This feature allows people with minimal HTML / React.js knowledge to generate HTML by describing what they want! - **Generate Texts (Page Designer / Assets):** Need inspiration for an article or FAQ? Let AI help you out! - **Summarise product information for SEO:** Are you still manually summarising texts for a page title and description for thousands of products? Why not let AI do the hard work? [![Content asset editor using AI-assisted generation in Salesforce Commerce Cloud.](/ai-automation-to-augmentation-at-work/sfcc-content-assets-with-ai-8805d0d3cd_hu_caae0f5b2dc42ad9.webp)](sfcc-content-assets-with-ai-8805d0d3cd.jpg) The ideas I have to make repetitive tasks in the business manager easier do not seem to stop! Nevertheless, it’s essential to remain mindful of the [potential challenges](https://www.salesforce.com/news/stories/generative-ai-guidelines/) of AI, such as ethical concerns, bias in algorithms, and privacy. ## Challenges of AI in the Workplace While we can probably keep thinking of many new ways this technology can make our lives easier, some [challenges](https://www.theverge.com/2023/1/16/23557098/generative-ai-art-copyright-legal-lawsuit-stable-diffusion-midjourney-deviantart) come with it. ### Privacy Using publicly available tools such as ChatGPT is fun to experiment with. But they also open up the floodgates of many privacy concerns. You must add the task “**read the terms and conditions and privacy policy** for storing and processing all the data entered” to your list! Some possible scenarios: - Message sentiment - Scoring data quality of a customer - Data completion on personal information When considering privacy and regulations, you could end up in real trouble! So please think twice before feeding it customer data, and read the fine print! #### Built-in AI tools Luckily this concern fades into the distance when it is built into the platform, such as [EinsteinGPT](https://www.salesforce.com/news/press-releases/2023/03/07/einstein-generative-ai/). But it never hurts to read up! And if you have concerns, you can contact support to clarify things. ### Incorrect information While technologies such as [EinsteinGPT](https://www.salesforce.com/products/einstein/overview/?d=7010M000001yE38&internal=true), ChatGPT or Google Bard can provide answers, it has become clear that they can [spout out complete nonsense](https://www.theverge.com/2023/2/8/23590864/google-ai-chatbot-bard-mistake-error-exoplanet-demo) with confidence. When generating the content, ensure you or someone else can **verify it to be correct**! #### Feeding it contextual data to improve accuracy As these tools receive more information, their responses become increasingly precise. This additional information also gives them the necessary context to enhance accuracy. An excellent illustration of this concept is [EinsteinGPT](https://www.salesforce.com/news/stories/salesforce-ai-evolution/), which was recently introduced. This tool is equipped with the context of the record it is processing and all the visible, invisible, and linked information. By using all of this information, the tool can produce much more accurate and relevant results for the task it’s trying to accomplish. > **Context:** Know there can be different interpretations of the term “context.” As a language model, ChatGPT relies on a scoring system that considers the words provided to predict the most appropriate sequence of words. The more data it has to refine its scoring mechanism, its predictions will be more accurate. ChatGPT does not grasp what content it’s analysing, such as a Salesforce Record - it just looks at what “words” are used. This is precisely why ChatGPT can sometimes provide us with inaccurate information - because it doesn’t truly understand the subject matter. Instead, it generates responses by analysing and selecting words most likely to fit together cohesively. ### Short term memory Another challenge with certain tools, such as ChatGPT, that ‘remember’ the context given to them in previous messages is their short-term memory. Even though we, as humans, can remember the entire conversation and hope that the tool we “talk” to does the same - it does not. If we let conversations drag on, it loses the context given to them initially, which can end in frustration. That is why **keeping the conversations short and rebooting occasionally is a good idea**! ### Unemployment One of the concerns that people have shouted from the rooftops is that specific roles will disappear with this new technology. But is this true? With any new technology, people have repeated this line over and over again. I can’t entirely agree with this statement, but I feel that the contents of these roles will change. And **people will need to adapt** to these changes. And with many things, if you do not acclimate, you will become obsolete at one point! But isn’t that the case with any change? Take the auto industry as an example. There is a lot afoot with electric vehicles and the technological changes inside them. People in all parts of this industry had to re-skill and adapt to these changes, and it won’t stop any time soon. ## The future of AI in the workplace As the pace of technological advancement continues to accelerate, it’s clear that Artificial Intelligence will play an increasingly important role in the workplace. In the future, we can expect to see even more ways AI will transform our work. I expect AI to significantly impact “tedious” manual tasks, particularly when large amounts of data must be sifted through to take action. For instance, consider the example of search keywords. In this scenario, Salesforce B2C Commerce Cloud provides reports on the search terms that yield results and those that do not. Matching a list of thousands of words to another can be hours (if not days) of work. Why not let AI handle this task for you? You can then review the outcomes for accuracy. Imagine the amount of work that could be saved by doing so! AI is also likely to play an essential role in decision-making processes. By analysing data from multiple sources, AI algorithms can provide valuable insights to inform business decisions. For example, in the healthcare industry, AI-powered systems can analyse patient data to identify potential health risks and suggest personalised treatment plans. It can transform the way we collaborate and communicate in the workplace. The [virtual assistants](https://en.wikipedia.org/wiki/Virtual_assistant) we know now (Alexa, Google, Siri) will improve at scheduling meetings and managing workflow. At the same time, AI-powered [translation systems](https://platform.openai.com/examples/default-translate) will enable more effective communication across language barriers. ## Conclusion As I reflect on the future of AI in the workplace, I’m reminded of a conversation I had with a colleague not too long ago. We discussed the potential of AI to transform the way we work. While we were excited about the possibilities, we also acknowledged the challenges ahead. The truth is AI has the potential to revolutionise the workplace in countless ways. Still, it’s up to us to ensure we use it responsibly and ethically. By embracing AI and addressing its challenges, we can create a more efficient, productive, and equitable workplace for all. --- ## Cookie Policy (EU) Canonical URL: https://rhino-inquisitor.com/cookie-policy-eu/ Markdown URL: https://rhino-inquisitor.com/cookie-policy-eu/index.md Content type: page Published: 2023-03-06T13:35:03Z Updated: 2026-03-29T00:00:00Z Summary: Learn how Rhino Inquisitor approaches cookies and browser storage on the current public Hugo site. Rhino Inquisitor is currently a public, read-only Hugo site. It does not provide public logins, comment submission, checkout flows, or other visitor features that require first-party account or session cookies. ## What this means in practice - the site does not intentionally set first-party login or comment cookies for visitors - the site does not currently publish the legacy Complianz consent widget from the old WordPress implementation - embedded or linked third-party services may still use their own cookies or local storage when you interact with them ## Third-party services and embeds Some pages include or reference third-party services such as YouTube, GitHub, LinkedIn, or external documentation sites. Those services may place cookies or use local storage according to their own policies, especially after you start a video, follow a link, or interact with embedded content. Where practical, Rhino Inquisitor uses privacy-friendlier embed patterns such as YouTube’s `youtube-nocookie.com` domain, but that does not eliminate all third-party processing once you interact with the media. ## Browser and infrastructure storage Your browser, hosting stack, or intermediary infrastructure may still use technical storage required to deliver pages, secure the service, or manage network behavior. Those technical mechanisms are separate from the legacy WordPress consent tooling that is no longer published from this repository. ## Managing cookies If you want to limit cookies or similar browser storage, you can manage that through your browser settings and through the privacy controls offered by any third-party service you choose to interact with. ## Changes to this page This page will be updated before any new visitor-facing consent, analytics, or cookie-dependent feature is added to the public site. --- ## Salesforce B2C Commerce Cloud Basket & Order ERD Canonical URL: https://rhino-inquisitor.com/sfcc-basket-order-erd/ Markdown URL: https://rhino-inquisitor.com/sfcc-basket-order-erd/index.md Content type: article Published: 2023-03-06T06:41:17Z Updated: 2023-03-06T06:49:17Z Summary: Are you wondering what entities make up a basket or order in SFCC and how they are connected? Then look no more! Here is a small ERD. Categories: ERD, Salesforce Commerce Cloud, Technical Tags: erd, sfcc, technical ## Key Takeaways - Provides a visual ERD for the SFCC basket and order domain, including its many related line-item and processing entities - Explains why this area of the object model is especially complex and where certain legacy OMS-era objects still appear - Acts as a practical reference for developers who need a faster mental model of basket and order relationships When scouring the documentation for diagrams on the entity model of [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/), you have probably come out empty-handed. Sure, you find many diagrams on the entity model of [force.com](https://salesforce.stackexchange.com/questions/22720/standard-objects-in-salesforce) with a quick Google! But not so for SFCC, so I started to create my own and share them with you! The fifth and final on the [ERD overview page](/salesforce-b2c-commerce-cloud-erd/): The Basket & Order ERD! It is probably the most complex of the bunch because of the number of entities and how they interconnect. ![Basket and order entity relationship diagram for Salesforce B2C Commerce Cloud](/sfcc-basket-order-erd/salesforce-b2c-commerce-cloud-diagram-basket-order-erdv2-3a4ba08328_hu_105998c5a14c162.webp) Figure 1: Salesforce B2C Commerce Cloud Basket and Order ERD [View this diagram on draw.io!](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1&title=Salesforce%20B2C%20Commerce%20Cloud%20Diagram%20%5c%283%5c%29.drawio#R7H1Zd6rc0vWvOWN878WTQd9c0ioKiA12dyiNSCuNKL%2F%2BgyRmJ4aQTo0x7HOevZOlgEKtWXPWqqr1P5jxdq1IC1dSoBvu%2FyBA3%2F0PZv8HQSAIQMU%2F5cj%2BYQTFwIcBK7L1xzf9GxjaufE4CDyOprZuxC%2FemASBm9jhy8Fl4PvGMnkxpkVRkL18mxm4L68aapbxamC41NzXoxNbT1YPowQK%2FBtvG7a1Sp6%2B8OMrnnZ48%2BNAvNL0IHs2BHP%2Fg5koCJKHn7wdY7jlzTvcl4fj%2BDdeffpgkeEnHzng8UHEyf7w3baxvhPY4mfwfzBt2q7LBG4QFb%2F7gV%2B8hbYiTbeLsx8Nx0kUOEbl4OEWAeVIqC1t3xoFYTHwH%2FxvhA6SJPCOBkXDTI6GBo%2B39X4sDGw%2FuX%2BWKF38v%2FiqDHCHln%2F%2FDy2%2BC1OMgRVjD7%2BDFWPAYaz4P0y72sJwaW3pWFGQ%2BvrRl7sfM%2FTHO7VKPPfxx2xlJ8aw%2BLjlHc2KGVCMvX4uj49qa0SJsXs29PicWkbgGUm0L97y%2BCqEPhzxOGcgmHz4PftngTACYg%2BDq2fmBwHk46Hao91bTyf%2FZxrFD4%2FWUW0p8NuWAh1Zyv8g2Lz%2FU2MuKy0sTxMnhr%2B03f%2B3Hcs0FwgZ297J65wWeKMl%2FQ%2BiheK%2FHp%2BuZt25PMl0ciFSFr%2FZG2iou7KMJh2OQ93hZNPNHGrD0aYWi9KGG2GW1BqMhzMubA9bS2Gee5Rn0Yir6fki9tqLnhilolF8Y53R0g0TMYLcLm8ExHfX%2BTDZyXzGdDKYyZTpLk%2FYVa4XL%2FGdtTwkt5qiGPuB6zjKiul27WXE9IRWca%2Bi7j53QpGzIFfWRomsLufklBt2RIQzEQufdod5B5DAEehy%2BaoVI91pulhA4NaMliulOP1S7C1zd7sufoRnk2HOBym5i3kwnkDjredJiDaNcMPO8FafiOfFA6XnvbB485qQ2tNum532fKu89zD7f6%2BmY%2FFAcKT836s5Cd3qnAS%2BMiehD8%2FJC0065O1JB7%2BedMD9n7cnXfn2XvnIkv0Bjo%2BmoZqPITFGBZFbjeWREIi2380BJMmBLNyPKVB3OVCKI2kPWMnezujYHcrT8UT2dWVvg%2BLILr5QRyRAwSp%2BEDqcwwX9bl7ONLY1YGh1aDpzbMWo9shROXcksbM2k1u02zIc1GuHcj5U4%2BLNQ58TwY6nIeBE3rGB31XHADtnaMIPtbmDSLG1Q1t9hi%2Fhgd7glEV90uxv1hXdhtk%2FnmKruemj2f8PwtziErRub1%2FMB2yTllSJNgM%2F%2BS%2B%2BJ4pU8QYw3P17rfjJevz3%2Fhxh5Rk017b84uhlcVuM4t7SnhZZtv%2Bfe%2F%2FgKeDfSPTwdZ8PJaURUUBx1aehxaMVPY4Wdzb5zy6ekn84dHu4omfrevlhii8XFWzVDspBN4kePvIbX6L8wu%2FeCRC6w%2B%2Bvfj9oap7tFjOfYoorLyK7GF8%2B2BH1HDxefwrXSIpb8t%2Bj2T99Jdf2jf8OD58qSO4d8PxPYUJo8a7gADgU%2BPa3WRwGaC12jPKLFQOaV5rrw9%2FFSC%2FSi%2BfyeEBhQYvjkxRjD3fl1XBYMXZvSYfRI5AtH1b5hBoqfAYqXMKMXWgp6sH82Sfzf5wP7MOMo1%2Be6Tuo9fgqDt8B8EsOjd8RxGsWDcPFLSBegxuI3aHg99ENe9upI42hnc7Qju3p%2BxIMRjD8XREGIgh%2BLseIv2066ClEmCLeizBlr7W9ljXuL3p2qU0GTl%2FQu9CY4c0dXnA8ejzmmFKawR0xlpOt3BHWnK5y0Sqip12UnoJbWuVn9pKTNEKkV1k4lDnOGdkjShT7Oi6Cvf4Yn690vdNTIkeOYL941MUJs%2BJ20kQmF9dsm6uFaKniasNZRtqigV7bmRLSaDKxV%2B1Fu%2B3Pgz0Ut8Nut7snRYYWJsveuBBh%2FZEsaqu01U28uZHkVrjMBbDtFOfd2izZ0UbLnufoOQ4QOCQDRm7NNS%2FZzttBJzcjbJZpxbVxI58EIW0QqbwlN%2FtMxvZrw48RYxptjZXVi4YSA7VTXUC2LNib5nxrhFJqI72%2BwUGxr3DQc0414u2phv1O6bWZY%2FRBeg0kWshJayn2qJY6x0bezHBguTPMye6sv1W9ebQez2CuZy%2FDwbQvO0J7b7ihN7L2e7btzClBXSOtKGYo6vMxh5v1Sbdh%2BGQjvv6o%2BHpUWEAYxMl%2FYRQsjTgurwkBlCLExT%2F%2FzypgzNb8%2Fyt%2B%2Fq%2F4T%2FC14sNuC5ABFqWF6oappW7yMyKt4c5XKNI%2Bjm6fFGkgjEF3wPlE2mGpscr%2F45%2BytArXf29mR2NnNbT7O1XYFYkfGREJHY1%2F2pAqJ9IFVsNA4qUUAw9Rw2dGgiJghZfETmAd4NvWQXxeiH3QRF7JtZGoB5LFKYDm%2Bh2kXC%2BjQW%2B7o7YIPbKnne5u1gNiE8YCT1pImofPAx3G49zN15RtrlYaONlye5ohDFKdqshyQgxNzuu5Gq5CQocYKnaJwb083bbS4gcjXaWkMRjO1hLWifZdbuTt2u4UxWU306QZh0WU1e0Xn8KYFX914vHOVpVgiTnWco4re8oXYl1zCEdpOZZiTne9gOqtu%2Ft5T7OJ7myjc5I31Wna6GGdljZewP1JsujmYxUYtmxUI%2FfpLPJIf7Qw9oKteugADlNwFnTWQ1BKIGK42fUJV4fbqdzaOwOD4%2FfdrdESluvekrHSeU8ME6AUd%2BVKH6wDRN615c08JnE3mTt9nnemGCzOkm68Kd5B667pT%2B2ZuxtNQNASezjWW6BLrL%2BlWUTSt%2F%2F3h31DxewFvkJizzc7D6HBK6Kw2GsK%2B2zogcJCV0dhsTsSruCwVGRr7ksGq5GauSC%2BwWDLFJnPU9ah5hqxGUTLkoPShfVDABN4nvEwwLhBqj9y1etcWWioxDepxLtE9Wk%2BvkdVPwFiBw5yhyIvqerdAdKewxyMVa4mQOAdSp4A7GoSc0Dg15nXD7q9q2GyaIURIVCF1DmFzqlJMQGP1z3PTmV5Jbunst1F2CvuD8QHPExtVBVLjA4FdVzSJDvhZNiDUmjZlqaChi7LRQFxvgEEewCMtngYF%2BTNI23YHiHWDsBNrTUgJzZNDBR0HwMIlLdhQC7eA3B8ZyiJgZcGwaKnccbYmBK7MQXMsjAX2pQdmbhhxr0uQKi0OWNmGj%2Fp0D4nGPk8NBYtfimRPXTSb%2FNzajtcc3prviF66mbpSd5CNoyJgtu9VNUKGrsVO6MQ3QitmNTYXTpbeMU3m3pTZBRqQdadYjs4iG3HtqThLuSDyXDby0jBQSOf2ypkjx6OpMAdzVyXWxo4XkAJDZf3pqC6vjNBcrNwcjimjChx16biuYJPgP7U38XsqkwPA8CZSEndAEoxNp3je2zJtocs0jLZNX%2BfePoYvL3VWf35CQx%2Fjcyea4JeYTLMrySz5B1BXBOXHa0CTyujqqOVkfqGf09Ngf%2FhzMMPxf%2Bg8%2FPPhiH8IoL6cWB6i6AWlBOvIKj4HVQhxQvxdwp%2BWpPuAh5njjcx%2Bx%2BuMQAQ7KXBgBWKBiSB19aCwyewlZr8FrAi4fnTCS5zZbEsI6aCZq6cBLYUlQIhH2s7e2YfDrsWNtstQCLWhhstdE0ZXghtMypz%2F%2F0y0zgtKOCW0UwWk6GFEm7XEN0hhPl%2BESVTY81wdsoYyAaFp%2Bup4eOrtbKdB3iZqb%2FWzWUGj9qtXr7qLadptzNess64eGUGynaB6zzDj8vAwxCh9%2BR6u8307p53JXgadbuRn2%2FWhZ2sOyyaQMEg7WHhIT4qitrGnoXspIxs0MBEExdlxNbzMFpYcX0cWJsDzaNQO1YpbSeo9JpcjBIl4D2RyfBxhi3DpSIB1Kpn4LNOKhSOg1fKDGxnG1IjlOpaVHc8p2ijHwKtOWutARHNSm%2B06rHt5WKyk1chNBkTuNwd2ilchlaZ%2FjNS2aTCfGXWfi0l4GyTsiYTBjxedP0lqTDeHJv3HlNhxhK9zElLEHtCS50X0%2BghGSbpDHO0vyfnc4wPy0qEHrYCRyDWQ2hpxRgjYivt1dak3ye8gKYcWwB16gumf7MO6yZMv8mF%2Bau5MIflgh8pN2ho8SVTWT4uwD6dzVLa%2FcsVAvyuIroLYuhdhQA7USrLU615lQM%2FThv%2FLaZWQvMrWzsaBO4I5LllPQ6WOvqVCcKv7fLhnARcMYghLw%2B%2FH4Sx43PCFVfHyIpBouITgejrN95fB3%2B6zhUqSPiJL35aQT4NfsvYazJzwIrE7S%2FVSMSCxSqZtk7BPrBxMXLLmWu5O%2BHU2B8sJ8VHdJENKM4CeDub6k5LHfU9VgcX2Xglt3sBi3U3%2BX7mxUxLYrTFZEMBot3NOgsqlWdBl1w4pWZsK%2BJ9LURZZpG64pRoYwY%2BLM6dGWvZRzbAhN1T%2FrK8WNpeOlDQ4rONuRbVQay2mKA4rLvbchDquhgFwdxaz9k1Hw%2B6HQcIuzstnoNjiNcYPZN9aOnEMLenwqFFldW3bRSI1TBS%2FFkuSPvJ2tEXRKamgTLdiHlr2skiRxqKfVxEYBOCfZwXZGjHQZMVhBXPip7sbNj02OKplI4PR4LODlA3oVtWdYy6AyINA4VQYwVim4L171bufinx5oyzD6qZfce5Dr9QKw4oKphZ1mQpSEFO%2BFIf7KSa5vrDkN8v4bwrDUA28AVgl1Fzpkwj8%2BfGwhGk1Frt6D5Dd7HdBqEafXgz9n4IyTcC8a8JxJ8sR29Ie0Paz6BvP4GuNfq2qljjvPq2LoWJ%2FKVTBXk1K0rL%2Bq9ArioX%2FGL8GlUhBn55XfEECeGH0pDK5mXHGRBfW1fUH9YVJ%2BbKiefmqjvA8gHJ7uf0XI34iequ4QidtekJiI3HeblYlxnk1k7EXtePXC0ZBDugnezb2zCNol3ZiayP7OdhMrdMweor%2BzJjrbuCAybZJ%2Blynm%2Byhcu1ISzCeLZ9L7ToAdKfrdewbVOugjqwp8ysyVQVxgO%2FJ9l7rz3hdvORs%2B9Ph8vtIJBIdYEHks%2BbRspo4aQ%2FGedBZzx2w3FHm6aRP8GHsuLuQH8kcpazQ%2FPtpFdcZciwe8hzue5IQDqMXYpd1ljycmubW157R0rl4uFuN1aGNDD0U4jqhGUHAZT0CGbv7UwqBDg6tTRzhy9yXdp0mW22ddcLVchEcBdGAoynm%2F2Wz4cO4os5kS8bgfgdwoycbkHlFBOxJhkEqsg2%2FW36sFlLbEz%2FLdPHG6l41qKkK9aKVBgaWmx4xX0SEsP7IdXYUOFr0lofR6c3tRZ6RyIf1VoQcEeeAsVqkoGg42SgX2BgD47ql4knEoMvqJ3Imid%2BiqZjjXZqtNN1EkjiqggkXJPGAf3SlmSNdmpM%2FyOmf%2FCZjXb6y9rpZ3RTQ2vPK4Q%2BDjXXJITgmkwX6LgF1G%2BxmLc0Nfh6GHrr%2FfcLnRUvHK3LXqHOQoBDvfZhkQo%2B9NO8iJOr22HnOHbTCK1GaN0M2zxg6bWwzbpddypWixuh1QitWzH9K2w20gitywgtwd8Gdtk270dEVkOZL06ZT6fhPoFiV6XharJR4ON2E7%2FZIKE3LJKArn%2F167UqQ4lLqrKaliTwcWSoUWWNKrsdanrCXgynmIg1mQdwxTp0o8oaVXYrpt%2B0Ifnrquzn0gYbInxlWusETUh%2BQGshNdkr8G8V%2F1cunSDiuBfHRRe0DhVelY%2B8WdBqpNPN8scD2F0Jfzy0Jq%2FccbpZ0Gqk0w2bftOg489KJ0Xbl1mDo0jzY%2B3hU%2FyMgmro7TkF0ScQ56oEUU2WCQL9Pov5ISd1ISWFAB9IDXyq8T25F6vpX4Ecx2e%2BpqTEUknxZV%2F8jSrxAD%2FvFDzKxSUK2Kh7oQfEQ8LUeCfw7GUURjoyzlF2u6fa8bzHWkFfbof%2BlhzIPgy0MZrrB9uk1zMgljasDsDJa3%2By0YtvaeAKNsoFj%2FYSG4dbrNvb9PEWE7RjbNZH0fIdW3Qo%2BUNzpgXGvp8Peb%2BrwxKdxT6Y97hydwLem0n0eA94yirq6AaUY2LLcLXxbDAfTGTHQ6YtDxTZLICmSd7DphgjcImI7Qx72m3nvKq2aSnDJNJd5OyqT6%2BW6xa4Gwy3QskuZ4wDiaDiiTsFdnKdlLbFNOUBY77IBQvvdwcaNeJncT8TFqM5BwfTfAXtGamfpsBy5myH%2BFpDuNZ4J8CKCXyq0VujoF6A%2BpeK9883AWsyBZCKVeDfoKA2hYISDn0NJVbql%2Fs%2BCJyd27TbMh3Ua4cyPlTLUdVnBRm1Ch0Vrcez3BYGPXWWW9ye66DKnsg7%2FfmcZveaxTFDYT0G6EY%2F3YrhN10r%2Frp%2BEvxivqY%2FV3%2FVkOEr1V3n6mABAdDTNmXnEF41iSTIcR11Y2vXJrxQosJizub%2BappfIBX9rBvh1Qivq5mhX%2BOfX6r8P9sERGvSBpDjuGojvBrhdTOG37S8%2BOvCS4mCpRHHxWf7Gd3VcOHr1F3naphxZt2F1mShoMcx1F9ga2%2BV%2BZH37SoL0LliWfWqpSAGvN4X%2FGxJGWhNpwu0aSnYJAb%2BBsz%2FEsk8YOCVZEehNTkIaNNSsEkMvGHTbzpd%2FFl9NTCSwqMyWvxDzS4atvsjwukTCHRNiYJoTe4J%2Bgt7%2Bn%2B2bQoOVb%2F%2F3u5A9Fx2dw6VhV%2BycwVa07kCq6j6aFRWo7JuhGpeV%2Fk%2BWpNwgDWbXjUq64ZNv%2Blc0aisH2xe0fDjs%2FHjE%2Bqy39nRAqtJTcF%2BY9OUBwO6K1eCXhrYL2h1gQAg8nNSC6vpdIEdB3saqdVIrZvhmwcQvBK%2BidXkGGBNk8BGat2w6TedLv641PoZidVQ3Z9RTZ%2BAn6tSTTUpJ9hxRc1vMKWPqvVrFE3IUWv1y4qmmqYWWEVpRyOaGtF0I8zxSzX%2B55uINQkGWEWfzkY0NaLpVky%2FaW%2Fxx0XTz61NNWz3Z3TTudpWnFk31SSR4L%2B1Ug9CKszo40uf9%2BfAyStWWDB2tCz1ic2r4BMYTU37Cvw07SsWDxJLKyRWAluKSoGQj7WdPbMPh10Lm%2B0WIBFrw40WuqYML4S2GRWfmvcLGkanGj%2FZMprJYjK0UMLtGqI7hDDfL6JkaqwZzk4ZA9mg8HQ9NXx8tVa286CM0NBr3Vxm8Kjd6uWr3nKadjvjJeuMi1dmoGwXYM0z%2FLhE8yFC78n1dpvp3T3vSvA06nYjP9%2BsCztZd1g0gYJB2sPCljZewP1JIoraxp6F7MQo1SAw0cTCIfA9z8NoYcX1cWBtDjSPQu1YpbSdoNJrcjFKlID3RCbDxxm2DJeKBFCrnoHPOqlQeANeKQv5nW1IjVCqa1Hd8ZyijX4ItOastQZENCtdzKrHtpeLyU5ehdBkTOByd2incLv8Jl%2FgnI3ceoH4X6rsP9ukxGvyBvBf2tKikVuN6X%2FE9JumFieSWwUl%2FV1qa7iyw7C4SC%2FSi4fwI4KrocnXLs1O0NkCvzt0znlfmoHY05u%2FhWo1SSfEcX7%2FL7C5t8zrYcmUrBgkP5iqCpHXvyj2WrLhh9SKi7jImt4YBNRItkay%2FQXeeoDUa%2BGtNUkLxHH%2BSyPZGsl2Q6bf9MloJFsh2X5unayh0Bel0KeTc59AsquSczXpMMRxDcFvt0UIu2Ip9nr%2FYvzQD%2FoSySF4TQMNoqI7WpOg2CQo3ggHva4uAnhN7gNRsYzdyK9Gft2K6TcNNP5sguK97qJ0PTLi%2BIekV0N3f0A2%2Fc52GERNWgvxG9uwlPS%2FcpUVevXCr9BOJFKhpM%2Flt4iajhhk03yw0U43SyAPOHglBJKoSU4gm%2BaDjXa6YdNvOmL8We10WLuSjGQV6D%2BknhrW%2B0MS6hNAdFUSqibNhER%2BnTE9%2BinomlUSAr987J9QSSdIrjjUglU%2B8MqNsAz4fjv0JtmvSfa7Hdp4wp4Ap5iUNev%2FZLMpVqOYbtj0m3YYfzXZj0nj4q4ZUauw6PBn9FJDcc8piU7Q9uIHkvGImtQP8rhY%2Bvrt5cE5lTs4X7R7ygmU0qsG65ctiyJqOlmQFT3KmrKoRindIF28rnJ%2BsmbJHwQqVnkbqdRIpVux%2FaaVxV%2BVSqOoMPHiIoJvBj%2BklBrme3kB9TubU5A1%2BR8gcFy7%2FAvs6HV%2B53WqJeilWiIh4nJqiaxpIgECx2GWRi41cukmKeMB%2B66FMtYs74NAsztVI5du2PabNhJ%2FXS4NDPNn1FJDc88sjT6BNVcljWoSPUDgt0rsy%2FunSxU0QcALkyEvuf5E1vSCAIFmAapRVL9t1n6NVZ6wOv4Us7ImO6AgL42iahTV7dp%2B0xniryqqYZBGy2L%2B6sYPZus1DPla1dgJ%2Bkf8gBorE0ZqnDn064ztwbAQ%2FFwWcwpNhcDkkaa64O5UIFDTJAIEj4M2Tf1TI6quHei%2FRCyfkO9KmCUI1OUMgBXLx42samTV7Vh%2F0zbirworJbKXxiIInB%2BSVA3LPaMu%2BgzQXJcwqssbAX%2FfpmYPJnPcBf%2BNvo2P9gW9fPP94LHjIsmHE8NH4%2FhbrfTrtkur8p54xRuha9Z3hWEepSGCH21vgYDkKUy3psEFCJ5iB%2BKxIjqlwlMybe2KwqLFlU01eM4EKW3MrPioI7eLb0ITY4tLWrMJLCzmYRgaoeXFLSCChmtmYmz7vjv01xhix0xvieHhcNOBFKaXdRZUKm6cAb6ZFSddwZJF99SBb%2BwAjOxxRgtCM3Kl9%2Fq0v%2BQCg3LNdWTnK5vuqwOEXds9HXYEs0fZTL7pKYstR%2FqR7LSjUO5Bay9szTbOcISq6iCcDzYGpGr2ItSVAAmKD5x2HDoLMmq7cYFgv%2FdRu6PSaIcZuF1UQa2wj%2Bp7NPAjGOctPpeGexlk9m2iOJJFtp2cHyV7FEQ1SURnsU0O45GxFCcJvtj1dcXfTTWvxY60KZwOUaLrBwtSyRod910me7pq%2FhNNv7oMB%2FAG9hoeSGx%2FWDbA5Dgmt2m3ZTqo1w5lfKjGxUxQ1a06mUfr8QyWlI0RDuC%2B7Ajs3nRDb2Tt92zb2VGCavVbeMxQVCPlbm4C1KVtQL91Y6E3OAtEVAyiWMUgXFWGU9X0raxieJOUgUd86K7cp%2BH1h3vkTlWf4y0GV3UCuIp9kZWD11wZ8oqSoVVt5ipnBAKdYkbUpUxAx%2Frza4yMjmPBYktG5qnBUmUVbBsrA88X7e5kRESjApm34yHguhqJDQFniM7kSV%2BMErcrd8I92E5A2idgY5z1oVVbHo13G5ndtWhxxoPImJliCh6ZowzeOCYE6C29OJ2F6lvJxFroTkcCfxQusuJL83ZnggwRlZghY54bcgjCTG3Umguc4LVLj0KmwA4MY7hvGBN5g%2Fa08Xi9EXnaXY3HrupFymRtrHW2jOj77BQcSla3K1EiFurdTmsijim3Twfe0BeBed4v4%2FEj0Z066YIoYYcW7HmUTTqtwFNJH1Hs8iyyO1TEtbkYO8VvUN41Nh1XoWHMRRey2d9SwMRrxesRooOY2WK7bqAlK%2BMrMcaGmb10TPjpHNNppmFNPwsQqlj6%2Bo3MTC2Z2ZKtZGbSdlzcdG2SyuN1GugqaaxTaiT0%2FWJm8GIuubTrcEpnQ%2FU7gi1P%2B1zDzG5qAoB1q%2F3Q79t35O1H%2F8ZoVZCqioLVjV95z6ACyLDj8NPrnG0IhF8b2Sn6f4NgXX4BdIod%2FMZKZxlLBdcBtHWiZSGT%2B7LiKGHMQSoUEB47SuGdMZXZMeSF%2B6GHzvxdRwE4Oe5FBiIHvi1kiwIOF04Oc3zETwddP5ms5HhEz%2B0eMYSSkld4jInP2gvRxDIHnQzKGwDRSzhc5e0xstmwSBdOOIrnynX8KdDCylX5SZxyEmrTwS4wTcryhqhM8Rkw3aGRz056%2FoB1p5mqmlG6F329tZLcaThOdFl2BmFvtx3mUscvzpMnbjoIxhYbdkxsCo3tjIp5N1P3gtAV%2BjsDYgnWsLSVPiU7fX235HhJVK2u03W9ZAeMMgDVgF7hMGi3L4POjl9Ok70%2FXXWWo9TNnYz0l6pKFE%2BV9wfTSfE2Y7%2FomWiooqNuK13iC4RuWM%2BXQR%2F8%2BILHZeZjXV4BdMMb%2BbH9SUmFKI8XdNcPJm60AmfipjNWpoFoCXuOavWfQlLuoAxJZU1I6jbnQJNd8Gc3paADP41ZO14WNp0USGT83KbqDcW%2BAop9wtyGT8DcJ3e8IPCnvS3OsOUFCNYlN0C%2FcQeVXyHMkJfPHjukfF4kww6sywqAK8r2mrzvJu%2F7FrnpdXX%2FL3PJauZls1lgk%2Fd909bfbH7xd%2FO%2BAz1dJj8lxRqWe15t9Du3vgDBulQNGPmlRvNL17II5GX3ocqlrLNtZQuCdfkCcOVWgc2G6s2G6rdBFE%2FY%2Bf8UcxGqS12Amx0CG5l009Z%2FcJ2NTPpzC1hMkIaB%2F8MrVw3z%2FSEZdYINMH5gU%2FUyqb3GXR9nnfwWY6qoZ33Dxu49GwhXDOJVBSNlM9%2FXpR5YlbesGiQrxmDsXOZ9EmH3sh4DJz5YIQsRp8iDheq26oArSvS%2BIOzoskKWLdfCNpLEyQMMjxbbbLIbeJMpby8GIAyjO2y8HiSRmYjD%2FkOCoenZwoIyJ8k4EpK1BUzhcJP7qBtTbW7ZASJ1se4DI6vfos0e2ZdTX4btVDdGy8LqIdrXppulNMPxdrjyCg%2FGE8NhGCnIcIetygUx2usasjThhSDYgc5WX3P5EAn22HQdKdB8I3O9Vm4n22nHVCOp05oT3GaDgRsn6WTgIjRDxd8v9TnAoFRZk8FiyNLpTMb70VjsroRh3sFklCK2WkqEoeiipAvvWAF2mRiFe7hSrl%2F1Oqkp%2BKvRLiRYdNHfgAAtdTi2%2BMY8jCx2hjdglzoGQGA8H0%2F1xTTducOlVlYBE1TcCLrvUNoDIp%2BA0p5oEtYlIcAV3Z1%2Fm6IrqzH65XrvjLKrqzEmE8PSvKYa449OgLqMDOQW6mR%2FAfPADkU6l9HxdYv9yCkKQZuIchNRvlL8RU%2BGv6eZi3VtCpAbqAZtIsqN9b9t%2FYfAUhNR%2FnMRZYoeGfFPJd40xPa8EeNPAM11RYzrki2Q31c480v2TEaQrwViT%2BKE4LpFfeQUteKNHGrk0JUSQvLDc%2FUyc7GubwNyw3XijRxqrB%2BED8HhRg79UTk0NCzP8H9MFTUE98yy6OOAc1WyCK5LVUCPy3Z%2FgdX8kJv6GTl12a294LoVdbSilLTZL7kp8b7qWfs1cnnAzGspcoXrFvrRilXfRlo10up2rP%2BwNWojrf5aifeh7dYPiaqGHl%2BpGPsERF1VcThclzKCIo21XbUY%2B0T1%2BEn8Xl0nAbSyerxpuNWosSuetl%2Fko6frgn%2BaeVmXaIA2leSNGrtl6z90VGnU2J9TY4zmhVp5W35IjTX8%2BErV2Mch6qrU2GFX3WpHflzF%2Bwus7Te36kJfduq67MLXoaar2hIqSkkbqdVIrav2AF8jm8jHp%2B1l5mVd8gJ2HJ1tpFYjtW7K%2Bg8tUBup9deklhIFXnB%2F8R%2FSWg37%2FREp9QkIui4pVZehgv3W3NQrl0yvdiWHiY%2F2ojiJe6rrRYFVFl81oqkRTbdHG09YmX%2BSeVmXZIA1hViNaLpp62%2F6UvxV0cRoiWEFpb38iGZqaO6ZtdEJGlP8iDaqyxfBfuM2QuR9C%2BL7%2BrTrFUfHu2VeVhwdlrMqHzpeEbluxFEjjm6RHp6wTv8k87JuzR9vdstsxNFNWz%2FUiKM%2FKo4ed8vsheUHkALdcH9KJjWM98w66QSdKn5CJ6F1yR44%2FPus5t5koApXhVVt4XI0CFYcXTgw4o01zrL7VtX2Mve7xVSMlw3or765IIwdNjd%2FtEvk0IXlIj2d0Lp2GPfkp%2Bku2HQXvE3mip6wCcBJ5mJdggFeUQzZ6LZGt92O9TctMP5sd8FepBvRD%2B7c2TDv38a8T6glPwGEV9X1EK3LgSGOqfsvsOg7ALr%2BNTcIQF7qNZggLqnX6hpmEKdpmNHotUavXSVjPWGbgJPMxbqkB6JpktHotVu2fqxpkvFn9drjQpvgb4s7FUR70f6xrbIaontueXSCzhc%2FIY%2BwuiwY4hfW%2Fv2Qt%2FohWYUfznEZZwbVGctpmmM0sqqRVddILLGPT9bLzMW6HAmyaYjRyKqbtv6mIcZfl1WlmvrBxbCGG1%2BpEvsEVF2XEqvLayGhX2ptIFK1ogpX2dvrBVKwcvzhHDhesX57PHiHv9UJBnrzBfx%2Fv6%2FdB4jjF9WBdf0%2ByOMsgSYdstGB1%2BiWvsiET9jl4CRzsS6%2FgTwO%2BzY6sNGBN2X9TY%2BPP6sDhys7%2FMF9lhtKfjOU%2FJTq8wStSX5EfdZl6ZDHWTrXb%2BoPFgnCVWZKnMuOTiHtoENhW520gyDsTA4Vr%2BtWQla0jPuCtJPvpZ1kmKuNJMWdNtVTYdOC3L437uwcdgTh%2FdgdqYPIgMJ0D%2BNYKYoMBWFpSEsYwRnxCIkFW3TVx2iuIISCpMswFMZ9sT9o04LZMnQQ04sXUKWki1DgdrxYLs9h9Jw9ut70u4M1vrdhUdrNTb83XEbFi7vuunQL4XKGrfLtlkg3Iu9A06mILEaBMQey8STYz4oTjnVVaiHbYDVHx4m%2BG7vjGTherCRNBGNFGhm6OS%2BcYyE4UQ5ne902MIgDyyb7pG%2B16X7gTsgEpQWYU1eLNT1hrO2uvUOXxQGrCT2gNFV289225MhZL2FTuZe2x%2FEG3C7ATFUmBtRWZpHHkiCHYBiyK7wzPUoVcadq07GvL5WMa8Td1%2Bntl7o0nHE21mVnkMcR6F8i7jaFuBMexd1AYqV%2B2ZpH4Ozcpt2W6aBeO5TxoVqOqj4ryKhVSLxoPZ7ltjDoqbPc4vZcB1X2RN7pz%2Bc0u9csjhkK6zFAN9LudmwfaqTdX5V2j0t8pcILy3lXXOIHl%2Foa%2Bnt5GXWCziWVMqpAhTv4fDIKr8nKKS796%2Bzod7mwT9sMQry0GRA6RCqfmczBil7ayymMpaarCAQch5e%2BoLXCOS%2BzsWBxwliRwHjfp6MkTWaiQQl2lxtyK1csPuQ9ZUtSjhrJ%2BGZhGCQ%2BMwUKmoETtj%2Fj1mufd3AH84ewwPbXK2s97aCjLo1zPLRC15K0VENNDtpj1aZtSADm5kpiwEG4hSWlvwv2%2B%2FFSbs37xI7YEkgKuw482SZ7iIYDtbvgt5OobELZ7g1FFvXj8p5hrMnaPgtYEIhGe1%2FzyvaNMRHbwKjkicV%2FlvO%2FqiD%2B35ohXwtH4F9qZ3C%2BGXCIlv0Ex3vgdDfB8MA7iLwYwyuDG%2B9Suvht6nYmmta415O613fJ3OP0eZfKfQJyDs2%2B7sAjKlfF5AjifmHgGJdA%2BI7Evw9NMFCTjgUB5bM0dMsYPr76ZD5alFBRFGT%2FxgxfPxq5f9fwfuqy6MM7nv32Knzx8OfkpvjmA372OD%2FjjN7kY%2BV9qn3skeFqib01XhxV9fAeD1XKSfTsLYFpxmWr6H9Pt7jh2v7ZOx6n3etTHOwRhdGXRBAGwSNzeTjnZ49%2F%2BghxkEZL4%2FG4fyf%2ByqkK87GM5NWp7k366bZ%2B0AHXZHJBwG%2FdxuDauxm%2Bzt8jsde643xZE3hNzhAEVO7X1eTvNfl7v4%2FEVNER7MOz9TJzsaZVDQQ0e3Q1%2BXs3bf2HOG%2BzyPPnFnkOqzuSkawC%2FWfWdhqOe%2B6VnE8gzlUlxBE1iVAQeFxfff1W85jmWeWAflu10789tS7io4iaJBwIrNgoqFFLjVq6Eb54QMFr4YsEVDcXK5ZMG7XUqKXbsf7DUkqjlv6sWvrZXLiG%2Bf6EhvoEDl2XhqpLcIJ%2B4XL9o7nckegV66VXTQIvu7hE1C2cQ5VZbU2TwEYu3QZhRD48WS8zF%2BuW9yG4kUuNXLpl6z%2F0ZG7k0p%2BTS0waF7eteAA%2FI5MacntuSfRxrLkuSVSX7gEdp3vUW02FM743maOxW3RQ4FuT5hLLUYeq7EMP9oPieW5FhyWr5zYEE6cwoJpGHRBUURL%2B3mrUB63olQgbvRBhMzpNQMjfU77DhKuOO4zHtJcUHI429YKmOdB8uh7DhrLwiR6UcckaXhuZymk5nEdYuMFQol%2B8l%2BGZbnsxWPtJhviUtSw%2BP73oQBvfBINucWvydC5Z6oLvqKvRmMjpuZQmRlkW5HYDqb8hoBZHdcmynGk%2B7S9nqx3r4xyrCnSnN%2BnsMXaC7VpDK4gHBAkq1BIdeb68XoFrCWM7zlLvECiGTaeJC%2FPr9hDcB52pvtb202CKbUBR76cLEdr5uuiyXb%2B34EVy1nE78Cxgd4PxZtfvcYmMZhxQyjTF94Y4nUFtVoAWHCrQnlM%2BY4j302k8le9FJK8O8W27O2nxDhopFFR%2BW6gTZoWYHMngclHevZRct4p3wj11jYgIy8rZM5p6qzP7C9ST%2BPA0vsgsPXDahnr%2BPer51J%2F6RwP1DZc4N5c4JZv9OHy9VSMF3wEVO2wi2N2hkOkFxoF3h9LL78FcXWoMdLwhTGOBv4DNgjBc0Ur6fI6yLqEDPl5sbOhsQ2d%2F39T%2B%2FCwmPz6PLzNLm8STP0tnDzyWSfwfi6Y2TOL3cNlPYNd1cdm6ZBX498Xz3za3N0YrjBU5bt78C8oFEAR5SWgR6HX6CwRUtLQ5yaIjWZf%2BAlemv3y2WkAWl7FkscJcyUhBCminDfr%2B0oK8LJ%2F1tTWQLUrOqNFOd%2BaNkq6uA4JirpEOp9s9f4BI3CSTMK78Jguh4GQrAafW%2FcQufpSgFZtQ65iZZIs1Ni8JHqmaBOz3uyN57he%2FIjg8Ygt0nW1oZdvp4NhqygPkCt3HxFBuEfP5UgXbvqlkyabrcbgY%2BUu%2BvTTGvVl3Dc9jVTB1sbiJtAh1ejMo3Wx4FRxFOq%2Bx2UIi8qWpINi8bPg0ty1hAw6UkN9bFm%2BvurxtLwsr6DHrwcBnOwbGJbRc3Gnaz3Y6p9Jdl4%2B9oa0BkE9MFVXYbJI8k3iHhalRjm8jnnY2xbv5Umvz3qAnb9FdFE15fG6Yu90AkyI8N2PxOSFtkmC%2BRF6%2FlAZwxhlZlwQD%2F94kmBX3PAlmZ9mINR%2F4aG%2B%2BwkYG4IoK2Bkw7GMKjDxhMJsfgRiFMNKKfZ4CE5QpME6TAnOTtt%2BkwPxZ4dayzYQpeb1ZMPvE%2BOH1iIZB%2F7qyg0%2BA2SdzbHDy7hB2PkeSDVmXZAP%2Fwor%2FXxW8%2FLRgO9rwpEqvnS9JlKzLp4Ere2E15QpNucKVzdQvstWvZc2cay5CQF3PDbjphdWUK9y09R88Z6PV%2FpxWe8oZi5Of1GgNNb5SJfbp%2FLCrqHYoN7F426Ejx4shX7G2W7Str7mzz1oIjODkkYVAr%2BwDqeiwjpygvXrZQb3GMqqC8gsCwpfvmUc92VvNxQEbCBnLldJkviGdhOkWLKyV3G8twnYcbsZJgNKGF%2BGMau1YGGQ1OMV0uTWcJ85IY6gJgY%2FLN%2FMDaK5nJstQrcGYYVScy1uE5OT7SeC1N9t4E%2BC7TqR3WlEJzIlJsioPd1IDoRSXM1TYWeH4btLpgwTJpwLS4zt8Bg47o40kbBlMXluOCdBTYqq4aLazrJ7CuhSqr5OVRaazNEO4wdTqpaiceUQ2BPppR8PXDD6EV2LxfahhNsXyTmgSBBsx7QFYSkp5kYropN2Zu%2F4gAgBolrFEqmIiu%2BvF05vNv%2FrSXHrCrc9Rw%2FNNlrrUBASpilG8s6b8gckSjqPFMgEgVsm0LdzhrJUZxnPJKwU7H%2FpyOAIJBBndb89jaq1lf9dZOp3REpW8QTxCRU40%2BNwCyXJ7n3IPCFrfJutxWvywzbOH5MHptOxEzkNTF48X5QtwKzW37ZTclpsC7cziL2xWbrkKJ0w7KvdUVZIyn40uowblNtZ8WyxMg8dNpTzvtPgPIEnl%2FuT0rlytNifMBIN3S9VAUQPe7zryHERJRXEBqjg7v0O2NhOv3Mw0JqZN6q0oBYNkV9x8Wo6c4m9C1r2WWOY6DufhPJOHQlZ%2BTn%2B1Lx9f%2BVH6ZTrjGulkTKz5rk%2BxwDSb9%2Fs4MknleI8aCU5pHI9LA0mZezFBI9Ks7bkdZRdovLQB%2FdhtS%2FsyGdSeOY7D%2Bby%2BzpaOmg80KsYZe5aqyZKfqTSzGzGtuVzefmtqccQewhequdMQ2uhR3paWwnQh28mI8vXFLJm2%2FAkAZyq8TFfRAhIZbJ627PImDVc7eZ5E2Izou3Q76c9oFd1TO0%2BkQHrPR67np4NBq7wDYxHqdiYEF%2B65dj%2BC4449s8Rc6Y%2BzrZVKWK44otpuD0hDbhcfilKdKdE3xp1yhyaaV51%2B1ofjpSGsOHo2KAwNXkGtsUYt%2FQmp2ywqLbsal7KgpXuqwa%2FASVAc1xutXHaaL2CW4Vm4t079WV%2FynV06mgIDWZmBoD8NLGoDmF7kAgtvwZMtIg%2FaEuDj9LqtacU51vAe0O%2B3DBax6WauzPEFuOcmeRBT4mi6LzMjJmuv2xOm1DDaBB3Vmc3AoRmYir8qv3V74fpRb5qzbmAW1xOJGQ9G3TjisMV46tMz3Zi6EbMiJUbOw40yzQBRp42ZoZbm2J5u%2BJ7S9cdOoLYFQ%2FCgMbQwRuPgIQxHdSaqncGl%2F0ipSUzgCbHYQRKMJmvQ2qGzHZT3ZbY36WWygQqT0qY36DKDRpnQSf15tF%2BV%2BwQjdmalSwVXWshkn3YsfbnIHWrKzGaDVpjHfJ%2FdgKAWMx3Rdco9jQUiVuZMjjm56owpNlByYzsaQx2%2Buy0dQ4tf6KPygc8o0DBCM5jza3onB%2BGyvdr2JlOb9V3K0gUIRcUQl7qLlr6FJGCxRn1inm97cb6P9hxpMNm6JY3WcKLRCq9vsN4ApOn9cAol6255c%2BKk190P4O7OJHvKPiqzQMo8le0uZpDBuIezfYRgRR%2FeOWQw5D14InvKDkDVQZKypZQZ7sZMS%2FCXLrJVNJdpOQK%2FdGZqMKeEYlbQm%2FL%2Bj4FJL0VUP%2FbRLbsYp3Z5hcU8JQRjESv3udRWtupNB1tTKwxlg%2B7QQAmyAQ1YOQAW0Mmv0m6yWwyDBRF2B1lLGUdx29mg%2BcTcDeN0q%2FeDkBR9Rihhr4x5WpLbknqTebppGy1amJA2PQFVZDVPxqs5gGOjCMZnrj6KtoS9gJcF9jCtbprty8wbQJJtsQ3s8gWtWuamM%2BUJxozQgRziOkDrPUQp8MQCXKorjUpwS7hZPtm7HX%2FNrzaKoFuhPBtLD6aFj7HZZqOVaJsN9CwVWyssclYotLYm7QGOb3UHHVhAe7%2FNFhblLfyuL5l7yZBdk8sEZOiQvsjYQjBgYteWKcAJNoqyBjxeSs2ISWQSpEYE0xeY8cgIuxhmk1SXW%2BkbcBSDS7ULt3jR3sy43sjM88gbDYSeps8dhCGgvcKyRPl0SicQChPRCwunHYj2CuwPTDCRdazTVYvnD0DzkB2G6l7GO%2BN8swnKLYBte4ZZxD6gE6LLbQJDGKixWX5nt3zeHbJvkVqcmIJjzZO4s8t7xDCI5GXXzzfbzbhr5BuJX7coUB4zWfHfpgXsUIKAfGhPDMDxbOEbSGvKedkQ8WULXFATQec2BCWFCkL44Vxn%2BnjPaGF9mO3oAmZAkgchkSuDCxxDHSrtMopgbUGeWoTieIBFYkCueGkupgsGn8giX%2BLQZFO436E4RrK2gKOKTIHIom2J4SgX2sOZz0%2F3nU7HE3vTjtyfrtzOAG5lu6xHK4S1nubeyIRnJeyLkg4PS%2FwKMEad9tucooC2k8xaETaIc7gHQTrVi8fdVTnZWnYWydhuoQ6Mbhxgeky3RKvTC%2FdtGbbCqMspaq%2FrqoNxmcPfzybpcrSAige7gLoW7C87xTAzlgRJ6GGoKysolFneaiGteAgktEHKy6uhiMrrAq%2BHSKAw5X7ltNYhaN2OF4u1WfrOCNvH22jXn4g8PrUKmlw8JX8TTjhwiQoy5fjbWExNO8kBjB%2FTPsg4WFtdk9aAmkoSo6z2VL807MUGWMojGxws9kQ%2F22dxr5x6vrdtu4QtDyG4%2BFbmbD1fSGtjFq1hcGqvRb6LtvuMifTjaDMDu9te4Ul7wGbnhcV3dzIUUQd2dxHGbVcLSBBbFF%2BeXuADzd0lkhM4aDyQS3XEz52J2uqtKDqcg50SxfkpTO%2FHmWJgZoQsTXutEd0Vym9kHeIHvFVWZ%2FOTeDWdSgRlO4JRMgQw64xXAEpgpDDvrwOmRN3eQNtOS08J%2BOjQwK00BEow2QTbcpHEJGYphUlOLG7Y7bjgKCXS9BY2JTE7yiOYdUYZHTNaKhtbhliO2jqLnemwc2cOcBkVAXSXjRmCYJLQ74HKPPRUtPCmrMGOaQMdFBfYyDvtnrgQxFTEs265TKTAMOsMUH07IMXSo2fU%2F264MOM2hEFdsilyHM07kTBYlbVS97uKTsxVEutQb7J1d1CEl75HhVqDzXrW2yUl8pkhQ9NWLI7nnl7Qcppdi5m3AhfFHV3ZZQYqi5UCYNHGMFin9obXE%2BAFn0xZQ%2BI0CQzIkgLpBNTGStxr%2B2bJuBea2e2a0WaLlWRoKoI9LqWc%2FhaPuF1UEgV7CW23OYn4e3JCrZiBE%2FeBjZG2hMAJKHQsaOo46LE55%2FB0X%2BMpeDVUu61ZiZruxgYmNJp6oxbpsdMWtqQ1sIvuN8woADl7r7JbkUlyJQmFch2WDmBOYvcR4nTzpTqEMpHL1Nkmlne%2ByQkIs1gDQ3YbSSjaa63ZjQPJY5VE5t1JuFdRRXR3e1oIYXCPk44%2B9bhhnkjjvrVm17kj5XrfhYN50G1FbS3a%2BbaBwCDcU1a%2BIOGbVm%2BQK9iC8IB2pNx6DdVtTNW6LFTkK3tufWCqmnNRLgNenDA0w0SXUyTm17Fmknum23f6O34wNac%2BJcoMLGhzX0rK6SMyckDY6d5g0KGyS4alm%2BIBwwPE%2FthmJslegOe6LFu%2BxsgbU0Nb%2BkiByLYZkf520TOj7SRSsLbbZrx%2BWvKA1f05bW7eNeNWqbqRiYMEUpdzp32u63XDwXyWrUZDULS3Ia8xQwCTY8vLbGoAL2jW69jqJJ3DVPHc19CSnqWthAIGUsguc4zqr0x5MdGMnePIciEM71WWxWbUcLzGqZxFW%2BCOYMqMcm6j0DnrIxbdQSYeOhgDBDhMVdAdwxK0U0jYcvHWKJXs0hFnQjOhrn1C1W1ih1QkC5xiQrlzebAkBIuVSt%2FDlnIL7bdscZ2nPkz0FroBy5MyJBShEU4iHUZImBRWNuOSUMee0qeGiUjCKUxteJfkeiXvAuHtjsD7GslsTFxNFjPTH44DAVqRrVaOLwIz0gYPIa08T01MgxVkmUxTStVllXXG%2FbAUtRu95UitnJ114U0GdD3VKgNV2gafpjOe6M5nQYp2tDDknP1QGyxb017hWjC%2F%2FFjsEiGt3S7stOzRzp%2B00K06b2UtjUsSczHshaskdMIyqrMeiLPuiO8teWaZAPS6PykjdI7eK50ztQb4fkeiI96e5V1l0Jl1uI7rTvbQkluPS7FmbwwZH%2FnrNmzSLddDlvF0ZFjRPfUUWNQFNUNq90wvXwcjwshyMd%2BunYLP4z4TJooHEs2UvPYpWZd3iRz3pmqW%2By653HfYMudHFvvqciyR4%2BLecstjEkPvIfx7i336%2FWJfIVPm4TIuQ7CqP11FHLmnmIL9ZNRuZE43NEsHCjWemvtkBIQriO%2FPSS6aDdnNwNUUtKO0R8tFllnsXnISB972xxlKrxx%2Btk%2BX6UacyNgW69LtbuiTA8TT5ZEvALqPUeKus1TH5SKF3CW70HglF%2FgPlISIBNbhjI7o0a7ndPhY2A2pTkDBTGfUS%2Fm0AMn5gs0GJobuMTJvbdWpFRO474oiGq7gLtvfSj2otQA7Wp9dWvMJO10S3R6LS86gYDHb%2Bb7bKbPSWHUfaXwHHxdXXEc9NQmnq766m5JlHwavq2%2FHmA23RIRq5EMltH4pO%2BxsUwisS41Ev9An5WNLgOuBmmQZq%2Bw1pdvdiXqya6%2FjpMxALo2o3Zt4ZfRb67W3GMrkopp2LMyEeUGApht4WtAGepvjJpxnOr3pGVMC86dImRy5I9Pp%2FdrDPf%2BYLUsSQChoue4mbukoM2Jmq2NmjhgmSiohkhbvy0mdldu5Wx4%2FKtdQvA6eJb1WvMoZZg2Hy8U04MwyzIAS5ckFcx0QztTd9kMrpQI%2B45cUylAQJRsyUV64bZFi7gdM1l8Jo2F7wxojiZiGnDfe8z3BZXxF7Qy2oBkVc4%2B291slsLt9vdcaQFLkOGgm9ME5PkK7czcfcomfB2urs93kosAN1l1kZNMMIFJtep6NeJnZZ1m8nILOvBXMdhu1a4Fsj8nciGkRirXbuyzvZa4K7NU1xLcGPoaP1v2dFE72emrpfmfrbzuS0gageB5Y4zhShQ7kiqth0ErnE2rm6dqYXsODbWewsgf8hsfn09DerZfbcAKYu5m8GjKTKbfQ%2FR0%2FW7pTJtzpE8KPO%2FN%2BHEIy081TXnWkmJFQYATbLW6yNJIe1AEhgY6IVrn0OttAyFjfBsEeXFoYIo6g0AItY4Jt17M9rG3KNd3CYc%2Bx1taaA6bsyRnesUUH6oy0XVk6TGvqACNGqikuV%2BNVd02Vz0hNVXrpobwVOF3bt9W9m6oMlYm6mvLt9dQet4hZPAsWrmOmQHsR25bWWcpCvuLsrqpHTCiVK1cr3lJksC%2FCYik2w2A1K4NRS28fu8FK4sAVuM7QfEYGSLlSlI9yZjK2%2BwN8rAkWNibgWFLETHJHzhJyHHU%2BGLTnnT4kLlhkSxUPGBP8IMv0dSKxgY7TUS91ZG7ZJwxBpceI6Vi7BED2ajZoweAgR%2FENM8lid7GKkF1v4ni%2BT4WDbRcarjtzh5SUtS3uB3nE9M223MVSHRuiC3BGzdEuDbrxsKd5JuXsCGsEFlZK731gG8AqsQiRbtbeLPHxMPF0YYNBPW0qbOVFPnMW%2FcEKFwfoNEx3fMrlZecdGxh37fZ4IkKEtrEny52Wzjuxw81BXUmZbqYKOTpbeFo5kzu0Dcj0JhwJHcUbjBJ7K6MesvD6ne4onwJcGSvmDWBBKJi%2BACdm3hbJREPzLquo6IQwRx5gYKybrM37PkBk100xkQdXQpI4uOapI3C9AktVFOv5xNu5MQSH8ubeqjwP7QZIazMrBVWrpw18pMd4hNkV6VLyzFftYdwu18dFHvNwhFBYwuEiqIABgiFnhL7Yk%2F20XBHIuMaJXbsTq2sXh36uQLBp8vIT7eII7GW3OBKoyCk9VxuqcoO%2FGvv5Qm%2BNpllc0yzuyib250Ee%2FPgsvswsbZrF%2FeE6FntpUPo6jRPPuC9S%2BYk6loZK%2FJ5%2BcZ%2BBr2vqFweBNUnZZUjT0C1j%2BPjaU8xFixIqioLs35jh60cj9%2B8a3kMAiz6849lvr4o9NVIzF8TJDfTNJ%2FzsaX7GyoydnUzLqVQ8KxjESYjEURIHkIfJWr46u3%2BVxEAUJpDD39jji%2BzucRre%2F7J%2F9otiRHbx9Epjexjziyf5cCUSQorHhIA4jiAkiJGHV9%2B%2BUvnqv0vd%2F7Z%2F%2Ftvxxd6k1HGQRstHszjE7ornahnJy7HSSmptPjJcrdDjxouzVxnu46FKCSz%2F5sp%2FR0cEphkXn%2BGZoRfWp%2B2fveMRmY6nwtNH%2BuDsQBsScBoSAN5B5MVIQFmB%2F67XD186%2Bfj0Hv3Z6hD4JSjlBrkRBaNA0vx9LaSSVZD68OeaIPW5ln2Jq68c7gFo%2Fyv5HAphMIjiBIngMEbcV1z%2Bg1oIIzGCxMt2AQCI4cA3sBY8vtYR1sIYiAOFfscxlERxBD0j1iIVYAtBl0FbCHy58y6Kfh19q68AlpW9EPHiKiCEIs%2FP%2BaGDCAK%2Be7wt%2F2D%2B4dN8HfSxBvRvFvS1fQn2gl%2BgZXp%2B2Ac%2BAPtHIF%2FPpMn3mfRNwP4Bqh9wFz0fpB85D%2FxskI5UIfoB5s%2FOn78D4d8i0E3nzvNiKRXZmvsSSZ8A4KxIGq%2Fs8Cg4dnL8hL8WgeAGnubrvXfCELfLmf8B5uwBAcEq9vylWAT0cArwEVOJ52BaeaHz0GOyCkwx9EJgihzafjyS0P%2FOwJBR5CUHB0kQPZDfNwkyDsCFRnnvuBMw5MOCfIPqt8eQ3%2BzhdXp4Jz5Bj3sfiDP%2FFXZcTWpPQZeffnl2pjNBOFEB4eS5%2BfDF%2BS%2FZIOWtIqVV3Zn%2BrBEFGPkiI24Cye8GknGELJgdjIAQQeDE%2FSb03wg6ICQAkhiAE2XB81NY4eFKCPbik5wv6FAdRz47yj7x0aPui5dC3UPr9QZ1bw91D3GHs8IshH0RZouhP42ywB10hLHwM4y9x0Uch5%2BW7L6VF1F5pQPIlnD%2FMhoBApderzt7QOIQf%2FhGdsSbkYSXhZYghmF3xDvrcx846Puxh6ds7wbbbw7bdcPUUjcZXiC0fP9hKhBe1%2BLVE8yVvyha%2BfVKsAOhu%2FJbANgdAHzEF%2Fz1IDR%2BhM9ncwRVF%2FpTfuAoS%2B6MbuGwL%2Byn3ML7B53ALUCNW7jNhcZlGhc3pbi95%2FQGXw2r%2FHWMJ5%2FDaoHCzzC%2BAF4IKzg6ScAQCaMoBhDfQnkAPA7fPMf5MhH6R4MqxKVSOX4oFRpq6qFulncvgzQM%2FIsEsKGPpMQ1Aex3U%2BIQkiAADCMgFMdRDP0Wsj7x4QtncVTi6CG34JpxtPqMhZO7I1%2BWdIHwY8Oq0%2FFcpIHhW4XhReCnMWvHBRz7yUXQGHwjwe6EUZA%2Fj9vvLzwCJIpgKEzCePEyQh4CJV9ZeHxJiS8d6Dh7OeDFSW9T%2F3e7aGu7xWEWpeuREZ8XZT%2BS59ZEFz6Z5YaAKIQjCFaYCw6i5OHFL6Dmmwj9D0mPXnzC2csA6yGP4vwLiYd95E%2FHiiG4bAByxIof66rfChlXHYNj5B2GnZhMN5V%2BNwvvmus%2Bo9DA%2FyvmXfk9AvP%2Fzgr1eEOof55Q43jli1%2FN5EMgBMcJHAMBDHxR8VJ9pfP4hcMi4suVRfIywRIYOLVbAFEUvjsqVSFgoNYtfOCYE%2FiEpmLxZn1CmTsYFidRLtj6A%2FxqKuGfx%2FmXAe8z1oCThYIAyLIkBSVA9IwdlIiqFkqHzIWzd%2FXAXkInDJ2%2BrUdxF%2B%2FQlyHw4lu%2FU7VYcRAIwNgdduKqRaipWrxZZA8i3YjOXa8IvpEz%2BEEo%2F7uRnDMWpBM1YZsL5%2F5VojsKXwbd%2F4Nw9Az5fsgRmEMYcoeTtXiOEGWkhjjJcTCB3oH1h8E4Dt8dgmZvHnYC79FUct6s9ygw2de1SB8%2B6oND4OiszgSpdiZNAvpllg9OGyOqkxcg%2BUbTlAsFiYhzr8q%2BkX6OQSf3RwSJ3%2BEvsf79qFHFQeWdukNOvJpwCJI1HuIGPcSRZzhvyAj%2Bls74wyGj8zVGeQ%2Fkz6grvgfqB3C%2B3xfhkc1fMv3mLVBG4CMYB%2Bp5Pkge7f0JEuA7wH98RDHynqs4%2BlTFCH6HnjgOBTcVrDfvJy65wgA0SZxndywFi69ZcT5hROtdP4PhMI4SBIZCCFEuVl7W7VxqseLJvz0FkE6%2FWIERLwVLgfX43eNe5G96CBAi7wjoJMeRCHDyMlgYanzLrfsWyUhWgX5Wj%2FLVhNVmoeNsCx0virQuvLJR6Qoul5T6deT%2FTu4%2F3BS83jyUXiD5H3gjzt9E778TyYFeRNRxgvgGtB4R7MvC6NlR9BD%2FwU8ejS8gErlDjjh08bRqifAbBxF3xKmjLEjdpASaSVm7v%2BH7OdYkiEEEiZKFBQMgAX59%2Fr2XYn3J7k14Bc%2B5VI41dBR6hE8ueFHoqYTmSYOS70RdK44ppmvxzPATT9em0vJm2dYFd1oEyTeCoU2I813t%2BgLez7hUVvZ%2Fe%2FHnjIyL%2FIkY5iEL7ZDMdkIIB3H0EGr8%2BMpZxUEE9JQTcToIb6opbxbCL7DbF0h%2BNb36hkj5WcohSRwiUAAr%2BDUMA%2FBDierZKuVB5EVDwLNuSF5J1z%2FabPVfYgSOQC%2FR8RByvII8CQw90soA9E67VQwEvnsETryTJ%2FHqU%2BEEdHpJ0FRi3qw%2FudwuYyD5kb3Xm13G3hUE4OsOKGfaZR1Hy46GIECg957rjPIArHAgB69yVU2s3spwQ9C7I9%2BFY%2B9lxb17zAmguym1vHXoFvxtcSeCaF9i%2BDnxm3ijpUojC77VmxsgAYTE8QPYfgPPy1yElxH6f2lpjwLkcq25qyQBem5EPyqAuXimQlOaeKN7Hzxi7Vnh9XvFJn8XYN%2BPu4BAGZslUQRHwYI9Q%2BdMCwaKq5PFyw%2F%2FPsVkLoSw4Lk3P7g0pCJNLd%2BtQuqDfT9%2Bh0VUmslr7KyC2d9K2DdpcW1zf1%2BV8hh1eShi5IOILluOKxfwMlDjZd5IuanbQe0lqz5s8nDILb73KSBeKvpvxPTfcy04huAAShAQjEIkAp6z9W2Vazl7OOYppn20BHCGBBzieINMAMPu3gnOkyh6yI375mH3%2B1OcOMvukMnX%2BMnbC%2FTEoWsn5y52f0wdbBJ2vhLhqcqMPEftSZUf%2BoH9gg69tH6mwda5N9eEMfylC0IR%2BA56saZa0fwKQ44apb8%2B6gQoD735gEqTN3a1N%2F7p%2ByEvm7Agh5ZaVQ%2FhhXir%2FWxNmc5te6DhPQSce5WY%2BGpFwE0JlM94oWeliRULDT9TqfiEVD%2FUg%2FHkCZ%2BvQBMmkDu0fvcMGIfwQ%2FvDtw87gVdAGuS9WeR9LJDsHfrqnlUD4E3S%2FtfLJMHXa6v%2FyiSP9kz%2BRpioOFkNzBefA8JhEoewx3%2FPuMZbJQMO1Y1nh3j0qEzrP5LETg36CAFgd9jLzrsIUg%2F6VcdAAEbcAVjtcTCGkXcw8d5xJ%2FAWTYHXzXqLyEjSyGe0%2BOy9EUH8e61J%2FrCreJnO%2BbJ8nvxGudfTLxfP%2F69yBOhH6%2Bn%2Fpf%2FDT42gfj6jE8aO1iGQx8%2F2Jn6jGPC9A3DyPQ9x9JFwEr3DX1zkBN6hqR27We9g%2B9vAXl7ANXw1UfTPu4Z3VMTpfMUPdtGtchbwR53Fd1UDcsTM%2F4MPDclPqBqK23mHo59yBlXHgBgE3ZHQifG9qeW6WXy%2FxN5LZbe5Jj7%2FRWyva6QF4ggEECVpJzGYAB46P55ECFTGni6Z9X%2BhqH%2BZEnViKC84NnHYLukAyxheD%2BVVxyAIckeeuMsD0pR23S6Sh%2BWZpUA33LNieZMM%2BjUsL%2BAaepuo%2F3fiqq6q%2BrFnNV0oUVwLBB7%2FvTC4IxdqynbCrJ9vlSM0FV43C7pLLTGsoDTC8yEu9r2o%2BV9G3OdJlffJLM%2Bz7gEQ%2Fk7k%2FGVT7%2FtMSowkMPjxX%2BTSoPrR1jnfbIz2QyCKNjVdNwuii2I2u4Z%2BVOD0FG5%2BUeb1wHI%2F9NZ7Qzf051VSl9gBDnyY%2Bk0o%2BxxVueizWqaytunr%2BP2BbmgwjhMQAaAIVOI5dOnexWcvnjpbNvx942H8JfsmkPoQSNUxOFZIlRNvBX1oflY9dZt6%2Bv%2B9Uen4j1QVGhVDIZQoHhmJQQjyvDfJaXdNqVluumTO2qHD3ku%2BBV5GxJIvF%2Fz%2FA8%2BwUzx8yLw%2BcLwC9e7gdxrTlp2oiPcOO8F8hRrid6vEL4wCL7g%2F%2BTnp2BsBy5PvsHjL6P%2FRPoMAjCIYQJIFbOEE8K0IZh36PxSmPJfbTwHO08M%2FBP0g%2FP8HH23gAJ889wBEsLujrXPJx0Tp06F4U%2Bh3qy1ZLoLh36szvxFk%2Fn4b2IpGU7%2B9pRVcVVd%2BdnQ%2BYdJwWfJ93CLknQ1pP3DMCSC7qRC8Ucheal6old%2F6jIiNfi%2Bf9%2B8i9gd2hIBAkkAJEMUAiPiXEvarUbySY8O%2FoPVr9RlxmLgD4SOAficAWnUMiJN36Ilr%2BdCmlu9GcV0LQ9c2dNaOlwXWnLUlINoEys8F73iB6QROIjCElemph%2Bj6DcL7uXN8T4vnAH6E5%2B%2BQ9A8ccwIwb0rvLg7mBgHC4NnBfHBv9IFfNvMoPr0f3Fv0VrMLLCq%2BR1XCg%2B2Xs8lPynOeEfsRshr76wLqD%2FF0qCKefpT28O3de56ezm%2F2Ei8z155Q%2F9tlHWdMYTj0g3u5W%2Be5k9IOIexDx6TTQT562JjhUMKBoHfYiRuwok1h3c2ubVL0yIiToWGde%2BdNpGmqcTYuDsLl9g84DgMIWQAAckYufmHyfYDrX0K%2BX%2BanEGB9bsq7R5wAuom6KYl8a0reiDp%2BJ43sVW4%2BgMEEROIEDsEI8Jhuebrc%2FMt0Oa6eaxdKzf%2BpAie0KXC6WRoTRvbSoPR1GiclkTlr4jwCfBE2i6E%2FTWQqwPSN7vKnAdMnQgSTAHDOxFuiCk2hC6EpdGpJScJHzVpAAL7D6ltDkjB%2BB7572Pf5zKGvWOXEhJto%2F7t85oVu%2BE6XpYvpgsq09sOUuypd8B1yctgmuiEnt0dOFs9K%2B87KTOA3csibGMv71KSuXOjsVOVna4TOvrPmDws%2FDGqw9aax9ZBKcqibPifGQk2bi69B7PthbOhlHfP32l7gCIbgBIHDEEwiZXXKM8S97IYxb2xnDJwZdA9rji%2FXB%2F8j0FPrRRAm0bvj%2Fs3gibcHw5rKnJvFcM11P9Qp4x7rL9IbA%2FreysifJtKvmxmRMFy2AIUQuABi%2FMQLJmgB9BiAwTBCnLVDHFKB4b%2Bh9cW3iDPy5s35%2BJ6M5NHuYsShT%2FO3tmR8DCy%2BMX2%2FFqGvyOR6OW0rM7mub9p%2BIgKIv%2BRAn8%2Fi%2FdDsgS7Edf4DwaPY9X%2FooS75hKVwEEjcAS8X7gtZgBZo9Py0FUyMgO4g9DTHgTh%2BR9Rk6Vad5WhjcPAwcPjiD9j2eNw3kQOrmZ7gG5mZb0xP3i6v8wjgT5N14QZL54%2FN1mdZ8Pf%2Fft2Tvpfn8%2F%2FbO7vdNm4gCj9NL0Nw%2Bc%2FLJiiKXAQtir6AaimI0UQyJLtA3r4rS7TFFXdX5s5wLWquFkZE2XLMj8MzZ2a4075xTivVaGGVQpywY1IHK7YiVfwkJQtltdeXZ%2B%2FBx83mX9QrSaPpSpJ5JYkYCtpcINEo%2B5WhynqlBdfhiYZQn0RosZgLOr4SVmhm4ktDw4%2Bfp3c0wQWLAFQoGkxQLcYPO%2BrTZrn6vQXLAyrLqU9MJspZM5BBGMowXHNdqkgkbQPz37P01Hd9VnG5qfcefBaYIa9vtaB%2B3LYoad%2Fk8%2FrrBpPSPLc3zI%2FFennLjD53%2BZ61QLw248yRTxGCHbYHES3CVk234t%2FtJcZoildqkWfKja2bzm5LMxSqZ%2Fdfq6%2BoagmfNsrxltWSCN9pxMIU%2BZcKn22C3YHn70pg7omXLY8tPI03OuSD4KBL%2FvNqoXvYH9jGSD7NfH7LAfOIL5In5iDmBtBjw2R8Yx13LWMOz7JUtpdSOUTG%2B8uFOC6ab2BYD7dNtyDO2mENW2rLp65wcmTF2U%2FVrmAOuI96%2BI%2Bk06S%2B0%2BRUfsGN4XtUcvCJGDcc7Y9MbodLll4wxyzlbkE5ekyiXvt6xRzpuWOmc0UwQgwfA6lF1jvwgm1Lvv1qT4K7p137a1ltn%2FOlmEeBn9al%2FYb53vG%2B5PN7NBl6YnTZP9Hg7RLJUIdtFwSA9xT3oKUZF9VCtIg4I6gzCk58nA%2FU9tLdCYdPgVq2QlUkiptEKaaKOAr9AF%2Bv4TQP4ylOR1YMB8ipRdwbpoYbIUlrLQszifrXAQTWAwVQokeKpZtzTg1G2uf72nz1dIu2r5pwSe5kyKK3bb85XhFGymFWDADwN2Ld%2FjW7jsOhsXZ4416wCGDX0iCEaiO5zXa52n5ctW%2Fz2%2FL%2BscUIojZKTUgy47kI3XD1dB1yJ8%2BEYuVz6OW2oLUehoUM3qWovmQRAKrtQICVJ0jdRoE5c53A5WTPAVv0u5aisgFSoZRBR6YPXwLGS9J2MgGct8cr8EA%2FS7VT1YY%2B9%2Bv%2FNvd3K8SIR1LJVGbEg6hgRW78wpJVIocrsU2d4cYamvUGySq44kEd%2Bprps7F8DTCSqUqq0hmr98gd0rI7DdMMBN2P4%2BQEmGw4D%2BRr52c1uroIUL86JWUb0tTJzZNbnFLV5nnD3CXYfTHfRggBShS0YBdyF%2F%2FLp0qSSoOKIlYFOc3rdbsXPc5ER1gLldbgCHUDPt5yU%2BxkQvpGp%2BmLa0GBX%2Fm47qhwxmsmhntDqsa4Myn8fN30q%2BKx1yRRvUL17mHxcz807%2B%2FtYr1bPH8XzKujmqbk1RL%2BzmrmPQU2ZtokFfCqq21MJ3Vz7glTUg4S%2BpJFAHimMova8fx53VLtCXlMu7qky%2Bhph6Ph7LaPyHwl2e25yyxUGwkKZ%2FbDEo6DKEqgWiUy3ApbpCuuTVAhRe2Y%2FHO7uVvtdu33RqSkzwxhqTMciiLxzqhZqpQ4dFkAtOP5Rna0BCGYBHbWhRFkROHaFOK7p%2B1%2Bu%2Fyxd0KHTxKN8Nq0v9z79eJ79AoEQmtOhE4m2IZaK%2FdMuD3COp22ztKP5UDlW3%2BhcRlTZ2F14oWz4GKFUB2USyPYWNVbGyEzp8fWARwBVAdT6RFwtIJij2jU1BwIPV4fKXx08XkxpS1dqXA9RfxiKcNGxEDGaAVkfJgK9zphzo8wP7XICMkMdNhPM7DqZj4q73MNp0TxYYqbuMZ8UlyfNKDM5DlNkb5UfYDDBr3i2jHbBb0RwMCmiq1Kgb1dPXxf3K2W%2FULNCMqvNUlw%2FOA%2FuiIVxolFPZd%2BebMIFR1NMnYZXusFo5ikpMHL0GTjBet4V9pje%2Fg%2BkVoj20s3tOWFiteqzeXi1xNrsplnXyeQ6olHW4yiUVsnbIrFLgvSx7D80HgLfl8w0jMd6%2FpmpJNdak2jpABvEe1p3le1IN%2BuHp%2B260%2BLHa445CbB%2FIbFoTbI7kgyp0VDNXXr0YV4%2FjKPJuDcwcv8LzWWryhnGlj88VTGWS2VsbtDmFyxvqoCd%2BoOkR18a%2BycLIAyP8WHHsZPElzrg%2Bsh5EXFK%2FUPycNr3P3Vy5O8p%2FOTOqGNzbbiJqbpyz8XwamZx9Q4G12pGLLSvCV24GpzbeNEViARuJhGYBIagamt3tFTvWOlJCzSi8lS0925cThnu7qAw6KIDKHkMTsFmgQThsWTmZwYbt6RWGIVH5sBpTRXzMuRZQASLdVRVq4iYFfR2EuE2ji6pYYfqKXsw8psueZ6KfZfrMoGhu91EX7UI%2BafNdNiOXZauNgwPb7AixHrm23EWxc0LIwjT%2F9UAMcE1VpWegnAt8lZMjHnHhA2noJksM4Lm3BJz3RfmKPmBnLmRqdNn7P6GPz3t18dWwKAbyqbrDbKL6PiKGJ4noqDODrJiqgoU81H7UCwov6LV%2FMztMojnXJMxJOTxmSe1JoLdB5ptWDhE2DqPG5gc%2Fc07KQ%2BGHljR0x6mHd1bthCG7wJ8d%2FPzteQ0ys17%2B72sCvhtiAVm1UbhO2%2B3T88tG%2FyXBCMqrb6SYFYLQTOuk27ExBDNqPrhformYUy2mqpwrMoqA12M9EXr5aErx6WNiZzY7iEnkwiOZWPkbyZSWSX6%2Fe69atxnP86XFiNd0aGJyqRnYi8tBaNyGbGKcMhAwdgpu27vvLOwCmlLROwl1fJqY6s2sgZ247rcpXLW7fjntkThJXeCnN8hg5wUIa0M%2FIXg7HFhnFhx64MdgnCZX24DELDr8vldrVDBee0hgg3HNeeYHNvxWpDTN8GoofnNFvXOTaL5eVT4CwkACvwBI%2FwjWI8Do73Y0qAw1aqIauew19Wj982S0QM%2B0vstZVPIcmA8FCi7SgAcCca39jjM4jD73kUagrCDrsuF087kJazxnUgrIbdUslF3nomHDC8qeytWnj%2Fs9it8MFNttdc4cFG7eTdqWWqN%2BrN7jcfOWwPXeDmCbFdInV3vXQXviM%2BN84bpptBugvX0j3IF%2F3r3kr39svtZk%2BA15dvFw%2FfvmyWq%2F0r%2Fgc%3D) ## Additional explanation of the Basket & Order ERD ### Post-processing APIs Before the [Salesforce OMS](https://www.salesforce.com/products/commerce-cloud/ecommerce/order-management/) (Order Management), there was a feature called “the [Gillian](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/ordering/b2c_order_management_for_developers.html) package” within SFCC. This has now been deprecated and is inactive by default. Chances are slim (to non-existing) that you can get these activated by going to support. For customers where this is already active, they remain there. Though I have no experience with them, I am unsure what the “plan” is for customers who had/have this active. Why did I keep them in there? Because technically, they are still part of the object model, and some may still use them. I did, however, separate them from the rest. ### Some “functions” missing I have tried to include as many functions as possible within this diagram, but with the complexity of the basket and order model, it is not easy to balance layout and readability. For this reason, I have decided only to include the most “important” ones (but not to worry, 90% of what exists is in this diagram). ### What’s that with the product, catalog, and price book To keep the complexity of this diagram down, I decided to forward you to the other ERD diagrams that I have made explicitly handling these entities. If an entity is in yellow, it means [the ERD overview page](/salesforce-b2c-commerce-cloud-erd/) contains all of the relationships with it in another blog post. ## More to follow This is it, folks! All ERDs I have in my possession have now been released. I created an overview page right [there on the ERD overview page](/salesforce-b2c-commerce-cloud-erd/). ### Mistakes Don’t you love being human? We get to make mistakes and call it part of the experience. Please don’t be shy if you spot something that needs fixing in this Basket and Order ERD. Let me know! --- ## Campaign ERD of Salesforce B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/b2c-commerce-cloud-campaign-erd/ Markdown URL: https://rhino-inquisitor.com/b2c-commerce-cloud-campaign-erd/index.md Content type: article Published: 2023-02-27T08:24:42Z Updated: 2023-02-27T18:57:17Z Summary: Are you wondering what entities make up a campaign in SFCC and how they are connected? Then look no more! Here is a small ERD. Categories: Salesforce Commerce Cloud, Technical Tags: erd, sfcc, technical ## Key Takeaways - Maps the main campaign-related entities and relationships in Salesforce B2C Commerce Cloud - Explains helper relationships and the hidden Store Group feature behavior - Calls out where Business Manager support and storefront support do not fully align When scouring the documentation for the Campaign ERD ([Entity–relationship model](https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model)) of [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/), you have probably come out empty-handed. Sure, you find many diagrams on the entity model of [force.com](https://salesforce.stackexchange.com/questions/22720/standard-objects-in-salesforce) with a quick Google! But not so for SFCC. That is why I started to create my own, and share them with you! The fourth on the list: Campaigns! And this one has quite a few things to remember for such a small diagram. ![Campaign entity relationship diagram for Salesforce B2C Commerce Cloud](/b2c-commerce-cloud-campaign-erd/salesforce-b2c-commerce-cloud-diagram-campaign-erd-4b241c1470_hu_d47f897a604c6b61.webp) Figure 1: Salesforce B2C Commerce Cloud Campaign ERD [View this diagram on draw.io!](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1&title=Salesforce%20B2C%20Commerce%20Cloud%20Diagram%20%5c%282%5c%29.drawio#R7V1Zd6rMEv01Weveh7igm%2FERnOIUTdQ4vKGgoiAEcPz1X4NgFNGTGMEhnZMTpZjp6l21q6qbJ5jWl3lLMkcVQ1a0J0DIyyeYeQKA4wD66wpWGwFF8RvB0FLljYj8EtTVteILCV86U2XF3tvQMQzNUc19Yd%2BYTpW%2BsyeTLMtY7G82MLT9s5rSUDkQ1PuSdihtqbIz8m%2BLJr7kL4o6HAVnJgl%2FjS4FG%2FsCeyTJxmJHBLNPMG0ZhrP5pi%2FTiuY%2Bu%2BC5bPbLHVm7vTBLmTrf2cFvCNtZBfc2t%2BVlIYO%2Bk09QHKialjY0w0LLU2OKNhGHliSr6Oghsbtl1ZT6quO2KYEktmMZEyUkc5emw4ZhIsEz%2FJKIhuMYekhYVgZOSPTuP1VPZhrq1PGakhbRL5EiuCeQJlI863480eh20p6cByE5%2BoWiJvUUTZT6k6FlzKZy6IY8mSL7D2JzM6FNRo6u%2BesXI9VR6uga3ae4QEqPZIdt4TfPXLEcZbkj8tsmrxi64lgrtIm%2FFtL0Zhe%2Fo9AEu1lefKkdTfmHHe2oHGB8bfc1fbg99JcyoC%2B%2BPkTrBjyuGyCkG08ADryfXyvISDLdk9mOMu2r2v%2FmH42ybFSG2RohadMi9QTEgkjq86Uwp8SG2i6Wlp0qYQ8gY%2BiVXkXS2a4hQ9Zea%2BuxoA5GI4lszbMrMc0pfLPdpPotrj7I6lVNYpugUOTqNRW1U666ns3zM%2FRFmY1mvPJe74wrTNFalbINffmitWn2VVtIlU6WsYRh6Q1dhdJBf4r2x1Jt1ow%2BMxn2u2xtJUwLtixNuEktPxnWBu1l1RCq49KqW5VUrtT5lLMVvS2LolJlinnpowffWk6vtP5oEvW8Skv8ataxdH7a6CmrgtrU6XdozsiOURzXyYoDuPrn8o3TZPgye82vJu9KNrcqzZV8oT%2Bu9tPDWbdaNh1CQrfxgv5DmeDWJfX1s2vzrOZ0J2%2B53KTNwHLHKdmfaAtR1gbTttrRlo0WSQ7LVZap9ug%2B8zYXM1RFnv8%2F9g7r9Up6r7OSEbLNMhkhI87u0D%2Fuu%2BDbfTeJvkn5VyNpM79vPgFGQycQZXW%2B12mZz5lrTMSBMXWebc%2BUCmgD0lx%2BrUPfhv6ndwwz8giSpg6naO8%2BeiYKerCiLllDdfqsea0uMF8Sa3OzuyLH1SABoLNuRT1fhQTCk6LH6jyrqIncJy64YDAPzqirsuxeDLo5C9lz1XCFmmNtLvnITbg3%2FM8nQTIpHnqn96QDSVc1hEWCYKkSevZif6ND6IlBiZcGPS7yIjTFQU%2Fk2Vf57R1p6lR5Dlpe8JwAGomNAPEE8vjV9wJBHXkd9sCwkHYCQkS6D4i0oevKRpDWjJmMPp%2Fd75JuSu4D8w%2BBdKgXPiySbZ7LgdiMkHm6FEhDtsBtLreNsLtwIXfBRRYV%2BZjCRukzW6X3e0Fm2%2B%2F2j%2FUbqPLXghRN7fkZIBUA1y6YQSZFcxF4RqZo%2FveQRh93N6i7060rWrZbcVUhjHBVwaH6kOTvdYc5rjt00q5qrrbwXNVSz6yihwNyRg4Kn80m4yhFARQ1fsAXzVa9Cmag%2F1JpFyS6P2lzlXL3kyio70RjziIWC0SdV6HaoIZLgh1I%2BXe%2BpYrce41e2QQF1i%2BQeEXbENlcsV4pG%2FrMMHpVKat8KG1u%2BSEQnYW5LrwIqjVglYFdLRFcUxx00h0p1yqK02xBWXdNpZfP9St8lW69veS6wrw%2Bzsr57idXbX729Yree1WUVo1Vq7OmhNzUebnYMOnPQt7mpcxy1unp6M7aeptqmJKxKLWZJTRsdaIOK%2FWlmTNa9Xl1wRcmtDXNzmt8Vaw3KobW6Ghatq%2BwLEIREbrPBrmy00mLWg%2BQGWOZWkMoL18Eu1tjW8Rbe7q0MyO00ZggO2WhUjLAjMnMuuyK6Wde6hkqP8iMcx55hhnsrO72Xvo8ZzWm3sliZ%2FUiziqf4rhb8lUbI0NHegGIxkiZTRXkeBLuL5vefEH%2FQPx%2BJ%2FYN7sYv%2FT4qHfNLkacZEQCDbApE8GxE7S7glnLHXQvmR6oX%2Bew3wiCInADncfXnGVGfKL0iD8X8MYoEo7cnNtSJgGE53ByHS84G%2FtiDpVm4p2zbeP6OrpE8cahowX6%2FUTP%2BuJqxP%2FdgD3zTbq3Xd8OoBWkwmjhwWGsKJJgyL5NVemXWS0Oms%2ByRnC3VPyVTG7zCXuFlYKFrziFQF8UZ8hvnaWmQYV5Br2bOx0AscoXuqmc5bWWczqqztEJ90rA9bitTdjSuzbsGizRKHMuD%2FgI2XvLV9ajab89KxY9%2BZvKB1nTIVxWZg1w69%2BHGKeqUuOLH8%2FlCLq1yWgW2rVLJmq4%2Fx0hHxsUM7QDjfVZlzCBoWi5Ln2rHzLQUx%2FWDW1K554ZxdZ0RC6PsG0uMB%2B%2BSLtCq3RSkZaEpjvlew6kZOb2cXrAfC6Zv9msVQhhVFbZTnBWQvcnVkCnLTeam0KCF0lAofXQFUXkziXw3MxwTZXrhGrFRNfPS77WWryMTtD449rVUV2fQjbem33Y80b2%2BjhqMpdx%2FBx0ePKqxIc7psdw5XmtsPTJINkZ1Se6wSxLez488j1Anba4%2FQNmmC%2BXs6OO1UTDK6rS0JihnTSzM1YdAylqWrNhWZUUMnZW6EG2t%2Ftr%2BaL1O5dpKJcsNFd1RscyRhSH6UihmJ1njrYQcR5DL5N%2FTYrM%2B0LtMt9pUG5NmVvuoiP01PyyUq4V8s4s6UUPvKBPoFOtr%2Bm3Fd7tMzpQoslVlRmSDZKqUWBmllQY3r6ya%2BdbbG6cbojBRC6QsnKH4D%2BtlPYLiB5bzhvgaccjXdkQbvkbcGl8jQYqN4GtpdOaepe4zti18nMvYSORk7f6Q5yQbrptCwP707fjTl2N93we3YC3qNvvZCDZFH6YjSIZORbA%2Bktlu%2FCsQPFEZw9%2Bfnt5T8PLHxG2b8boGcSNPlMmQBKZumLrdWZ89y4MN4PJWXFjqRKcMVypg8obJ2wOpfhBlx%2Bztz7E3Y2YaV%2BJu2Ce%2BSfL1A3C6KfZ1oqCHDBef34GqHQ0TuI5KFO%2FnjsQDwmGFG2Rj4TQaCQg6QTrGntAciOkYpmN3Zi7O80mZ2%2FJJTxRRkOECHkzHMB17INXnMR37o3SsZhm64Z38OgNysJ8cn598QYb2fby6JYYGTlTHkOGKtXvRvCOKtKeQd8C4GBYkR7iCy41UhIg6qcFAgRTAhAsTrkfyOgM4vBGvM0iIR3bKcKgWEy5MuB5I9SEmXH%2BUcKVnNnpqipVHGm1eiXRh1%2FcaJOoHGHRTJOpEmQp4CPp%2Bg2yJB%2FtjChOtFjw1ywXA6SnMlv6Gy0h9u9Mm0ilPVBsAnJ7CbOmBVf8G5%2Ba4T7ZEpUjye5NzXIksEXVjZvVRh5WVMEGKiQxhFzZm1vN9LDnFeiKSBfGynhPVICA8Xde9qMyNF%2BWFSU%2ByKaITk1uA8KBPnCLCpOcxPb%2FbGuUPTyTwQcSUM5j0YNLzKKqPJ7j4qymimqX2FdEwJtdJD2H3Nl5CdJ9zTcAT1RowPIXAPWjMsVlL7pAokUSgVIlYphOTScCIcesKR0JvVBNmSpgpPYy7GODhrbiLJ7L0MBziRG0MWAISJzolZkqYKd2L6uPJJBJPD21LPpIkSnXHsJJKC2GX9irk6AfQckvZIniiOAOGizPuQpM2xodg7nCk0QE7SnRuB3hibgd4xnt%2BMDvC7OgOXcTbGuAOT2TzYURyF%2BeRMDt6FNXHczv8jeI5jx0lQIywO3sdZnSZKRiSZkbUiQoO6mev470NVdrMiu%2B9tetmGVB4rvFEC%2BmCl%2FJGtnhEJBoX0mEC9HheYIB7N%2BIFBm9NjeyUEUP6MAHCBOhRVB%2FPtfBXC%2BnqmoGAC7WAx4SuUEqHPdx4SdEPoOaWaumoE8Ua1P1VX%2Frk%2Bp4YUbIVc9SJCRWoyLFFOCeEKdHD%2BYW3NaqcOpGzp%2FDYIkyJHlj18YQKf5YSGcj3Rj1rpilXokTYv42RD11msoXE%2BdCJ8gzqDl%2FadRdlcgevQKLJBOeYo05Mt0CHa28xJcKU6DH9wtsac06fSNbT%2BI20mBI9sOrj6Rb%2BKiXavgKppklXeg0SdnJj5kX3OedCUK0XWbaOblSRh0rdX7fVAslyBMsyFl8yZSqHJN5Wda%2FDZujNFjtLBwZN4qVBj7u4Rh1t3522%2FIk6KUvVabu6nyI4SLI84FmaZwkK0MHajreWZ0gaclTwl%2FFXZpZ%2Bv%2FEWVjsLNcVSUeO5qraRTVFDbs7EAwqQFEWyLEXxJMMHa4%2BfyV37dSpvabW7FD7ZUapne1Nl%2Btq5EaFmHSrOnsjVkZMKbyma5KhzZe%2FYUVrr71pzceCrozyH9jAGA9ulKF9ajnRPWu1s4QNJuB9sL%2Bl7XQNXdVzIXpMpwH%2BvrH3z8wtzjWz9v%2B2zGZhj%2B%2FJ29%2BsVGHQ0fMqSPdriibtQk9wbc9EJWQT3%2Bgkm5bks%2FwDa7PtasYyGUZGmq5OAy0cB7vZJ3wzg7oZg9lH3wBhvYXgPdGmC4Sgekv4n%2BAXo7mNs1IFjwVgyAmSDFyPGjbJkMBNi4I2cD7pHTsAzKWbvFBzH7h7wG3uQyBb6oi9g31zI2TAfBLQxzMcD8%2FHwsm8BvWHJilU7QPueG4XdMQbyrO%2F8Yyt7pJomupx%2FHyx%2By0KDsxxzbC9cKN%2BxGB6zhAzPMTD4%2FI2fTu8aDTJFABbyLGD8TzY2oxEwz2sYjcA1D2zGxY0Gw3D7BgDyVMovdjtmNtA%2BqeAFQ8d3%2B73hwJMCJc4PthP9xWo23r1OgUAcgT66%2Bqnh3oM0l1SERF9FDXvAr07d3jZ13GPGh%2FwU93NOsaEUIIJShAzC6RgOv2ciImM428a5ZxOxH8chOOSEkiwXfP7GPhCAQRSC5XiKhYhHAHKfZOyaIfczPntBHdoLLmZzsdo3F0lHchiM1Bipk0VqCiN17M4878EoQW%2BAld9B7gDFzwTq7TF9sN5H6pBnHyNSE8kjdbRjfy3gxlXEDxubsfdfwxZnwIQifg7GOBT%2FUzTmQv7tLhxHRkPOw2fXTO6hcyghmlywnjlE52BeyKThGdD8pSMvbCgfQEJAewN3TwXsSY5J0cxF9uOQiOEvG7EJajSwOXk4c9Kf2eixKFbsxgTy2JjEb0xIeNy3v6AxCUXtj2QEkjMfRLLm43LWgub5Q9TnqNNxeuhNl%2FfrvRiwmUriZEqARWzxH3v93r7giTAftGLIdme%2BjNWqHInsx2orHiQMtJvTJcMATt2lcQheUrBrHGDcOd2EgzsMgdESo%2BV5aMnGi5YPHTTfT0Lu5jsvC55EOIpO7aKpO1XybpyG3GLtT8AUNVlOdRHm%2B9AaUS0TE7LGg5p4FNnDxjDs7dunYgXP88b1YFfTK9Kg9pKDO%2BDpzmr4lRNEn78Dz1vJQUbBZdzjfpJ2RAGG1IeF1OSyjOBIYBiHe%2F%2BFq%2Fs1d%2Fc%2FjCcCM2NPDCaNmXhw5IOSd9NS%2B4poGJNYsfIa4c6HwMqHHMISoOMeYj52TTKDhx0%2BLIAmMAZwM3oAAyjOFx3zOGMfAhjjID%2BCobxXjP8jo8%2FS%2F9rt1yl9Bg%2Fye1CY7hszM%2BYZQBiM0Wdi9A5CXzIgEBpyd82AQDDVxy2Xev3GvcVD7h42pppYqS04Mm4DA%2BifjBJEhVXjLphNNEiAFi3D7Wpfm1uSOaoYsuJu8R8%3D) ## Some additional explanation ### Promotion relationships You will notice that a solid line does not depict the relationships between promotion and CustomerGroup, SourceCodeGroup, and Coupon in the Campaign ERD. This is because they are more “helper attributes/functions” made available on the entity, so you do not have to traverse all the related Campaigns yourself. In reality, there is no direct relationship. ### StoreGroup & Store People familiar with SFCC will look confused when they see “[Stores](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_campaign_Campaign.html?resultof=%22%63%61%6d%70%61%69%67%6e%22%20#dw_campaign_Campaign_getStores_DetailAnchor)” and “[StoreGroup](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_catalog_StoreGroup.html)” pop up in this Campaign ERD. (or maybe you have seen this by accident in the documentation or IntelliSense) Even though this relationship is visible/accessible in the code, you can not assign “Store Groups” or “Stores” to a Campaign in the Business Manager. It is also impossible to manage Store Groups from within the business manager. Or can we? It appears that this functionality is behind an undocumented feature switch! After creating a support ticket, two new features appear in the business manager. First, we get a new administrative module! [Campaign Store Groups demo recording](/b2c-commerce-cloud-campaign-erd/campaign-store-groups-sfcc-2023-v2.mp4) And suddenly, within campaign management, we get new options! ![Campaign Details screen showing Store Group assignment options in Business Manager](/b2c-commerce-cloud-campaign-erd/campaign-store-groups-sfcc-1a646a927d_hu_e7dc8e27f9d179ba.webp) Figure 2: Campaign Details configuration for Store Group assignments Campaign Details **Unfortunately, this Campaign feature does not appear to work in the storefront** (I got your hopes up there, didn’t I 😉). I experimented with the [StoreMgr.setStoreIDToSession()](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_catalog_StoreMgr.html#dw_catalog_StoreMgr_setStoreIDToSession_String_DetailAnchor) function, which did not activate an In-Store-only campaign. These scopes are also unavailable in the SCAPI/OCAPI, meaning we can not use them for Headless applications either. If anyone has gotten this feature to work, please let me know on the social channels I am active on! > **Thanks:** Thanks to [Paul Shaver](https://www.linkedin.com/in/paulshaver/) for telling me about the “hidden feature switch”! #### Import It is possible to import this data, as described in the [store.xsd](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/xsd/store.xsd) file: ```xml <xsd:complexType name="complexType.StoreGroup" mixed="false"> <xsd:sequence> <xsd:element name="name" type="simpleType.Generic.String.256" minOccurs="0" maxOccurs="1" /> <xsd:element name="stores" type="complexType.StoreList" minOccurs="0" maxOccurs="1" /> <xsd:element name="price-books" type="complexType.PriceBookList" minOccurs="0" maxOccurs="1" /> <xsd:element name="custom-attributes" type="sharedType.CustomAttributes" minOccurs="0" maxOccurs="1" /> </xsd:sequence> <xsd:attribute name="store-group-id" type="simpleType.Generic.NonEmptyString.256" use="required" /> <xsd:attribute name="mode" type="simpleType.ImportMode" /> </xsd:complexType> ``` ### Slots & Sorting Rules It is possible to assign these to a campaign in the Business Manager, but they are not accessible through code. ### SlotContent, SortingRule, and PriceBook These entities have been marked in yellow as there is a larger entity model behind them. These have been made available in other ERD posts I have done (or will do) on this blog. ## More to follow You can be sure of that! Next is the basket and order ERD, so keep an eye out for this blog! There are still quite a few entities within Salesforce B2C Commerce Cloud, each in charge of an essential role within the entire flow. Next up is basket and order, [so keep an eye out](/category/erd/) for this blog! ### Mistakes Don’t you love being human? We get to make mistakes and call it part of the experience. Please don’t be shy if you spot something that needs fixing in this Campaign ERD. Let me know! --- ## The Salesforce B2C Commerce Cloud Data Model explained Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-erd/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-erd/index.md Content type: page Published: 2023-02-26T19:09:43Z Updated: 2023-12-04T13:38:39Z Summary: An unofficial overview of the Salesforce B2C Commerce Cloud data model, with a full Lucidchart ERD and guidance for exploring the platform structure. Categories: ERD, Salesforce Commerce Cloud ![Full Salesforce B2C Commerce Cloud entity relationship diagram.](/salesforce-b2c-commerce-cloud-erd/salesforce-b2c-commerce-cloud-erd-0bdb8b007c_hu_c7ac82843566a3a5.webp) [view on Lucidchart](https://lucid.app/lucidchart/f1c8c33a-d575-4761-ba41-245c9762a5f8/edit?viewport_loc=-362%2C21%2C4352%2C2276%2Ch24CqrZw216W&invitationId=inv_9439a330-b96e-4081-a588-e91ae8b714a0) ## An unofficial overview of the SFCC data model Once upon a time, a budding developer wanted to work with [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/). Excited to dive into the platform, they searched for ERDs to help them understand the system’s underlying components. But alas, there were no official ERDs available! After a few years, our intrepid developer set out on a mission to create their own ERDs for Salesforce B2C Commerce Cloud. They spent countless hours reviewing documentation, analysing the platform’s architecture, and mapping out relationships between objects. And after much blood, sweat, and tears, they emerged victorious with not one, but multiple ERDs! But why must new (and experienced) developers and architects understand this? Well, let’s face it, the Salesforce B2C Commerce Cloud data model can be a bit of a beast. With its many objects, relationships, and business rules, it can be overwhelming to wrap your head around everything. By having access to these ERDs, developers and architects can gain a deeper understanding of how the system works and how its various components fit together. This can help them build better solutions and save countless hours of frustration and confusion. ## The full picture For those who want to get the complete picture of Salesforce B2C Commerce Cloud at once, [a full ERD is available on Lucid](https://lucid.app/lucidchart/f1c8c33a-d575-4761-ba41-245c9762a5f8/edit?invitationId=inv_9439a330-b96e-4081-a588-e91ae8b714a0). This diagram provides a comprehensive overview of the system’s objects and the relationships between them. Using this ERD, developers and architects can quickly grasp the breadth and complexity of the platform, as well as identify areas of interest for their specific projects. It can also be a helpful reference tool when designing new solutions or troubleshooting issues. However, it’s important to note that the full ERD can be overwhelming at first glance. With many objects and relationships, figuring out where to start can take time. That’s why I have also created several smaller, focused articles that highlight specific areas of the platform. These provide a more targeted view of the system and can be a useful starting point for developers and architects looking to dive deeper into a particular aspect of Salesforce B2C Commerce Cloud. ## Diving into the details So without further ado, let’s dive into the different ERDs for Salesforce B2C Commerce Cloud and see what insights we can glean from them. ## Ever-changing model As the Salesforce B2C Commerce Cloud platform evolves, so do its entities and their relationships. While I have created several ERDs to help developers and architects understand the system, it’s important to note that keeping these diagrams up to date is a challenging feat. As the platform’s entities change, I will do my best to update the ERDs accordingly. However, due to the constantly shifting nature of the system, some diagrams may become outdated over time. That’s why it’s essential for developers and architects not to rely solely on these **unofficial** ERDs but also to regularly consult the official documentation and keep up to date with the latest platform updates (keep a close watch on my blog 😉). By staying informed about changes to the system, you can ensure you are building solutions that are both effective and future-proof. --- ## Salesforce B2C Commerce Cloud Content ERD Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-content-erd/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-content-erd/index.md Content type: article Published: 2023-02-20T05:40:33Z Updated: 2023-02-26T17:52:51Z Summary: You have probably come out empty-handed when scouring the documentation for the Content ERD (Entity–relationship model) of Salesforce B2C Commerce Cloud. Categories: Salesforce Commerce Cloud, Technical Tags: erd, sfcc, technical ## Key Takeaways - Provides a visual ERD for the smaller but important SFCC content domain - Clarifies how classic content assets and slots differ from Page Designer structures - Acts as a quick reference for developers who need a simpler map of content entities and custom attributes You have probably come out empty-handed when scouring the documentation for the Content ERD ([Entity–relationship model](https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model)) of [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/). Sure, you find many diagrams on the entity model of [force.com](https://salesforce.stackexchange.com/questions/22720/standard-objects-in-salesforce) with a quick Google! But not so for SFCC. That is why I started to create my own, and share them with you! The third on the list: Content! Probably one of the smallest diagrams in the set! ![Content entity relationship diagram for Salesforce B2C Commerce Cloud](/salesforce-b2c-commerce-cloud-content-erd/salesforce-b2c-commerce-cloud-diagram-content-erd-1-9255609590_hu_636011cd401ccea6.webp) [View this diagram on draw.io!](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1&title=Salesforce%20B2C%20Commerce%20Cloud%20Diagram%20%5c%281%5c%29.drawio#R7V1pd6o8F%2F01Xet5P9RFwvwRnOpUbZ39hhIQZSri%2BOvfoGBF0ds6a2nvrXJAAsk5O3snh%2FhCJo1Z1pHsfsmSkf4CCXn2QqZeIAQ0S%2BEXzzJfWTgCrAyqo8n%2BQd%2BGqrZAvpHwrWNNRqPQga5l6a5mh409yzRRzw3ZJMexpuHDFEsPl2pLKtoxVHuSvmttarLb9%2B%2BCJr7tb0hT%2B0HJgPD3GFJwsG8Y9SXZmm6YyPQLmXQsy129M2ZJpHuVF9TL6nOZPXvXF%2BYg0%2F3JB6B%2FGe48uLfJSJ7lUvg9eCFFRdP1pKVbDt42LRMfIqqOJGv47Ftm78iyLfU012tTAltGrmMN0ZbN2zLVmmVjwyv5bREt17WMLWMRKe6W6dOv1aXNtjTTXTYlLeJ%2FRILgXmCSSPCs9%2FJC49tJLu083LLjf6SoS12ki1JvqDrW2JS3bmhpQ7JfEaub2Tqk7xq6v3%2Fa11xUxdfo1eIUez227baF3zwT5LhotmHy2yaLLAO5zhwf4u8lAbv6iB8oDORX29Nvt6Mp%2F7T9DZeDjO%2Ftvqer61N%2FOwN%2B4%2FtDtG%2BQ%2B30DbvnGCySV5c%2FJDtKXbK%2BwkYvMnqb%2FN2nUirJVUtMVQtLNPMYNMScCYzITJpRY01r5wqxdJkYKyVhGqVuSDLZjySQ7WuiLgaAp%2Fb4EmpP0XExyiK%2B36lSvyVWVtFHWJbYOc3muWtFwO2XKi%2FEkO8Zv0Lg%2F5tFntT0oMXlnXkjXjNmb3qLZd30qldppxhHUwge%2BCtTGf%2FKjxkyrV6weM1R7HbYyF8zcSJaG3LCSHaoVpTUrW0J5UJh3ypLGFdpfcrpktGRRRGUmn5UaXfKj6XYLi0adqGY1WuLn47Zj8Gati%2BY5rW7Qn6Q9Bm0rP6iCkgu56tfsg9Nl8m38np0PP1E6My9MUDbXG5R7SXXcKRdtl5Dwbbzh%2F6RMcIuC9v7VGfGs7naGH5nMsMWQxbZbGH3hI0RZV8yW1tZntSYAarHMMuUu3WM%2BJmKKKsmT%2F108YJdRSYeCFUTYVtsgwkYcHdC%2Fjl3449i9Rmz6HehE0sd%2BbL5ARscFiLI2CQUt8zX2OhNRsUz3dbTsSgV8ALBn3%2FvwO9V%2FXZ7DjjyDpGuqiT%2Fdw3WCcMWKhuSomvmqL1tdYL4tzupmN02u50ECxKWuTV3fhQRiacXV6r5quIm8Ghc8MJgEJRqaLHsXg2%2FOwf25ZnlG3XVWl7znJrwb%2FmdNACbBk8vil1ZFMjQdY5EgOJqE617srXwI1xgp8ZLS5SIvQkcurpFX3%2BXXd6RrJnoNWl5YkgAam60A8QSw%2F%2Bq7gaGKWcdIsRzsnZAQse9DImkZBloZkro1lvHr69KM28W759UZsAt1t8%2BKbatq2THbEbalKwXWra7Aay2viWK2cCa24AGLhimmsPL51Nrn%2FSBIrcMufK5TkMrfCxM0FaIZMBHg1iaWkUyC5iLgDCRo%2FnREo%2FezDerhfOuGHdu9MFWajmCqcNd9ADjdd5j9vkNfm6lmKtMlUy107TKuHJixMqTwVa8zLsoLMK%2FzCp%2B3m9UyHMPeW6mVk%2BjesMWVip0vIqd9ErUJi0UsFA1eI7Uapc4IVpGyn3xTE7nPCj0fERRcvJHEOz6GSGfy1VLRMsaW1S1LadRALW7WEIj21F7k3gTNUVikjMoFgquLSjvZljLNvGimc2jRsVE3m%2BmV%2BDLd%2FHjLdIRJdZCWs50vrlz%2F6hklo%2FuOULPCauVxXcIsdVLM12z6K5cd8VJqNm53DXxnLaNF1WzJmhZazIy0RtpQU0vVmZ2xmtVJecrnhrRjpicVvixWayVLr7V1Pd1DLItRRCS9usFM1hw2qYWCezGWqdSE4uxNGHUqbJP4aJmzUaqPDxoQoF0USgULjpnUuMPOmV7qrZqiskpqkFlqZzIVc9XN6KWP46oXik425qpn4ap8guPuiarW%2BpaB%2FQIStT4am8h88caaiBc2uXqDf%2BHleWfMDR6Gl%2F4clfbxUsw02QheyiZghMzGyu4MtJTbTy2YX7leZN2vjMEY8sV9b%2BVnZITvbWsgz89esUQC1%2Bu0fk05KQ6GvIMnqR3nADyx6xksebpf8Pv9gv095dwhk51Kt%2BcNe%2BYkpT90SbVSFwA0mbfhPDm3qwWVac%2B6gBtJ1S%2FJ1pV3spt7Uxx8zRmMwqI4xkRvkpSUFPMOuxV7MoBinst15l3HbaFBMq2Nk4j6osnWoIVMtj%2BoTDoWi5tcHMhKb0rW3rLlRb%2Fca40L%2BUYvNWzgPW3wrmH8ziQzDW9goUqJc34wmUzlwjyjl8iWUyg45uJrgH1kkE%2FRLrQ%2Bx2XGDgY5i0XpS2vbqSZyPeLalIpdb9jVMBgx109%2FsMRA%2BZQMgdZGdUGa5erigO%2FW3IqVMYrJKduYMj27VykRQr%2BM2HZ%2BnMMdRKaC%2B57McGILNVooqEKh0RFE9GET2U5KHRBFeur1Ov1y6q3Xbc7e%2BzZsNjj2vVDVxqQ3Ppr82KCOoeDEDcZS3u9OhMJn7R2IYyKWO4ZmXiwig8nBqJDkdkOSWP78iipsBWl90YDFEZ0rpvuN91rOKmpmYUFQ7oKY2vOGAGQ9DUojpzQnVHeuTcWRXn1vNZrvplyZa6BY0%2FAd5YscyKn4TS6fHqatjwJmejCTyn4mxXpVMTpMp1zXasN6Wm%2BUxN6CV3PFci5b7%2BAgqhltNCTdfHVBf8z5TofJ2BIFmmWmD2qAKVNiqZ9ENW5SmtezzY8PzrBEYajlgCwc4fhPS4uewfGDnvOOBBaxK7A2TCuBRdybwAIwwUYIrCQuuetoYYm1ho9jJRbA7GrzBxwzOXDTIf%2BY%2F57Af88nq34ORsFemAiP1UI2Qe%2BO9wOGTkTIKsCsDz4JtA5knvAP51hEhGMRkY7ljVUnwYZj%2BXaWjrZ7w%2BphT%2FR3cFTkjpU7Qxhh5OhLOfMZxBzH0rcTc%2BBAqgsgYjkXy7m%2FwGoDSL4XWksdCMrtdINY0MWC7olcPxgqjxXdX1N0GUuXce3fRNDFvPvBePf5ROQvAPCuVOSBzB%2Fwu6nhu3DnxLY33qFS2552Y2nmikqNPdDgR%2BR6xUotVmoPSFeZ%2B6KrB5IkwPYocazUYqX2RK7Px0rtjyq1iqSiEnKlmqTe6JGbmOBeVBL9HGnuSRLBA2kwYDsP5v49JmrK9iFlEgAgwhUu1S8F1xvpBdvjPLFOinXSU5LFAAvvhCzCAzkPMGKaOdZJsU56FtcnY530h3XSjQRSTHevLZp%2BATt3JZoO5JpA8uG8KCJ%2F9YGFE%2BR2F726XEd1YB0KuD3gEgunWDg9J3ukfhy1VwnKA9P8MGLWNxZOsXB6Fte%2Fw9UzYuF0FeH0iVSv5JtIp5j03kY%2B%2FRx87ko%2BHUgAgdvLITykJz2CTqKY3cVRLtcvHVgAA0Y8bh%2FrpFgnPSFZvK%2BVAMgDc%2F8wYtY31kmxTnoW148XwfirOilpGTZ26VstgxET3Atrosdc4II8kOxB%2Fm619LDLyEiRxktHvXny5rUWS5GlUX99rLdRkTx0MZcWjNznEVQcF9ZTV513Ig8sQUHCWE%2FFeuovkMoANO%2BFVB5ICyC3R0hjPRXrqSdy%2FXgJir%2BqpwTXdbTu2L1R1t5J5PheHmt6vGUEf4E%2FdyWzDqSGkI%2BX%2F%2FlQXzNyqsK66hp%2F5IGVI8j4iahYYD1ayB7HMu%2Fr8XnyQOIAFT8RFQusJ3b9eOWIvyqwqrrl3nTl9pgY36kGe8wlJ6gDaSdeUyJZRVV%2F39p7JMcVHMeaftuQKW9ZlkdVl2G%2B%2FCJPfMTG1k43uP7au%2FN64t723WjL37gTmmluy4uZBMGRgOUhz9I8S1CQDva2l3t5BtAkRwV%2FGX9naubH23JjvrFRQY6GG89ztZXNxA25KomHFAQUBViWonjA8MHe%2FSV5e7%2BLWm7NN7e2C9srD0fW2On5buGPMeBmVZEbMnk%2BctDhHaRLrjZBoXNHea3%2F0YqHH9%2BB8rr1CUtRRp6w%2BfZy7HvSfOMIH4C242B9ST8LjTgt5Uy9PEhA%2Fmfffrn6OaGT%2F9G3XyrLhXpH5%2B%2Bsvx9fhkdhZ%2FoTm2pWSTLnByGUj4LQdd3dDYRuDsWEcXSnew2AFWCORkOGBDTL8RRLruBujaskAbCJY4LX43HVG9oNl8RRMAytUYVdBFq5XWgFl8bWa4MpjMH0OcG0p0ujkaZgiPBK2FkD%2FezIuoeVHsozggnvTggmsdSP%2F8RgQzLl8j9I7FMjMAgBIxtC4E1AxK%2FURRE4qrA%2FjcDRBBkrg0QwJhXMz3D05hmP%2BAh%2Bs7qOoyH%2FQFocBY7kRwvkWM9DkA5qzH9QIZrA8cLjvatXeHwgEuGgizrxRYIuGDLZjDruuSVl8IxozIKejAX5rn453rPqho9GzD%2FNZw7BKAQ8YDmCC16Ph9Hogr5xNURlVs15EVgNiMtRZCbAR8zNGMLnB7cnOGAZhJtchSYO0pvdD%2FDseclNnGP5pEg%2BGnczFx8fJJmY%2Fx4H597Xey2VYiBSA8Ru%2B5IyPGZHnkCLExulLCF9E8%2F3FHV%2FiH4mpjw%2FnThHF8AT4cxCjmUSTAisd9GdCFLc937mdIAP5nNjgH8ygMchtE6T%2F%2B9%2FlwR5Ogb5I0E%2BRNHPONKBz7Wfol8T0oPFdjchnbwWpLPhgT%2BGOzemA45KBMN%2F6%2B%2FQoLjzAnS8ul4M0CcCNBUD9CMBNEgQkCV5FjL%2B6%2BUGUaJmhG6Fz68scQ2ApgnqvADNxQB9UYC%2BTJr0jyB6oo20ro7Wy%2FdcdKyEiFH6SJRO0Bs4HY2eR%2BP0zZgztYvMF582vPY84aEVOuOhwx%2BkZz%2Bj40dIxiAYnsXx%2FWmd0x5VZlhqS3oyZ3joK3jaIqYzz6Y3r5zBCPfkhscZjKfSnm%2BQZrfyCjcxG2xD9nrv2SGbjoDsq03c0OF5lfPP3AACsImtmZg11p5LRdJx4viTwu7ln8KBx2aZxk%2FhHH4KB4RH%2FE6h01v53%2BBGSB1Frh8oA5yHVILmt5CYPO94Hh1%2FD%2BzTjufZkopKyJVqknrRxyJPS2L9w4gcHtE4c55TaEjjipMsUU%2FdMBfG3DOw4Z%2BPb%2BBNx%2FIC7ftwR7L7JUtG3hH%2FBw%3D%3D) ## Additional explanation of the Content ERD ### Content vs Page It is essential to understand that there are two systems in place to handle content in Salesforce B2C Commerce Cloud: - [Content Assets in combination with Content Slots](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/content/b2c_content_slots.html) - [Page Designer](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/page_designer/b2c_dev_for_page_designer.html) Both operate in different ways and have a significant differences in features. So be sure to check out the documentation if you are unfamiliar with them. ### Attribute Even though “Attribute” is [not a separate entity](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_experience_Component.html#dw_experience_Component_getAttribute_String_DetailAnchor) within [Page Designer](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/page_designer/b2c_dev_for_page_designer.html) entities, I decided to add it as a separate one to show which entities supported “custom attributes.” ## More to follow There are still quite a few entities within Salesforce B2C Commerce Cloud, each in charge of an essential role within the entire flow. Next up are promotions and campaigns, [so keep an eye out](/category/erd/) for this blog! ### Mistakes Don’t you love being human? We get to make mistakes and call it part of the experience. Please don’t be shy if you spot something that needs fixing in this Content ERD. Let me know! --- ## The Salesforce B2C Commerce Cloud 23.3 release explained Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-23-3-release/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-23-3-release/index.md Content type: article Published: 2023-02-15T14:19:00Z Updated: 2023-02-15T14:19:11Z Summary: 23.3 release overview covering trial sandboxes, log-volume changes, Shopper Context enablement, and the refreshed SLAS admin UI. Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc, technical ## Key Takeaways - Highlights the main 23.3 changes around trial sandboxes, job logging, Shopper Context enablement, and account security - Explains why the release matters for ISV onboarding, SLAS administration, and headless storefront setup - Calls out the new public cartridges and tooling updates that extend compliance, tracking, and authentication options Another month, another release from Salesforce B2C Commerce Cloud! In this blog post, we’ll dive into all the changes and improvements coming to the platform in the [23.3 release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_23_3_release.htm&type=5). In recent months, we’ve seen a strong focus on updates to the headless APIs and Page Designer, and we’ll examine if this trend continues in this latest release. Are there new and exciting developments on the horizon for the platform? Let’s find out! Are you interested in last month’s release notes? [Read the 23.2 release notes](/salesforce-b2c-commerce-cloud-23-2/)! ## Trial sandboxes ![AppExchange partner program artwork used for the trial sandbox announcement.](/salesforce-b2c-commerce-cloud-23-3-release/salesforce-appexchange-654f2875a8_hu_c2920098496fb6a6.webp) > B2C Commerce independent software vendor (ISV) partners can now get a trial sandbox environment within minutes of joining the AppExchange Partner program. ISV partner prospects can opt in for a 90-day trial sandbox when they register on the Partner Recruitment page. After their information is submitted, a trial sandbox is automatically provisioned, and the ISV partner receives an email with their sandbox credentials. Getting a sandbox environment for testing and development [has challenged potential partners and customers for quite a long time](/how-to-get-a-salesforce-b2c-commerce-cloud-sandbox/). But this process has become much easier with the latest 23.3 release of Salesforce B2C Commerce Cloud, at least for ISVs. _A little glimmer of light at the end of the tunnel!_ When ISV partners sign up for the AppExchange Partner program, they can opt for a 90-day trial sandbox. Once they register, a sandbox environment will automatically be set up for them, and they will receive an email with the details. This is excellent news for ISV partners (and the third-party ecosystem) who want to test and develop their solutions on the platform. With a 90-day trial, they can get a lot of work done immediately after signing up! ## Platform ### Successful Jobs Are No Longer Logged > To increase the efficiency of log volume, successful job steps for custom and global jobs with dedicated log files are no longer logged in the global job log file, Splunk, or Log Center. You can still review successful job steps in the dedicated log file. There is a [limit](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_development/b2c_understanding_log_files.html) to how many logs can be written and sent to the Log Center; in most cases, you aren’t looking for success messages. Though successes should be celebrated 😊, there is no need for them to clog up the general logs and nibble at our quotas. ### Buy Now Items Get Their Own Cart > Shoppers can now use Buy Now express checkout without losing the contents of an existing shopping cart. Buy Now express checkout puts items for purchase in a separate cart. To use this feature, upgrade the Payments plug-in (plugin\_commercepayments) to the latest version. Losing your basket halfway through your shopping experience is never a fun thing. For any projects making use of [Commerce Payments](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/salesforce_payments/b2c_salesforce_payments.html), this update is a welcome improvement. The plugin\_commercepayments repository can be found [on GitHub](https://github.com/SalesforceCommerceCloud/plugin_commercepayments). Access to the repository If you don’t have a GitHub account, see [Salesforce Commerce Cloud GitHub Repositories and Access](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_development/b2c_github_repo_access.html#github_repo). ## Business Manager ### Guest Basket Lifetime Limit Is Increased > The lifetime limit for a guest customer basket is now the lesser of 30 days and the registered customer basket lifetime. Previously, it was the lesser of 7 days and the registered customer basket lifetime. This limit applies to input validation in the BM Basket Preferences UI and Basket Preferences Import. It also affects resolving the guest basket lifetime if it isn’t set, for example, for the basket cleanup job. This update was moved from the [23.2](/salesforce-b2c-commerce-cloud-23-2/) release to this one, as I covered it in last month’s release post. ## OCAPI & SCAPI ### Enable the Shopper Context API in Business Manager > The Shopper Context feature toggle is now exposed in Business Manager. Use the toggle for each B2C Commerce instance you want to use the API. Before this 23.3 release, customer support had to be contacted to enable the Shopper Context API. The Shopper Context API ([part of SCAPI](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-context?meta=Summary)) allows you to set context information in your headless implementations. It can be linked to customer groups (segmentation) to activate experiences associated with them, such as promotions. ### SLAS Admin UI Update ![SLAS Admin UI updated in the 23.3 release.](/salesforce-b2c-commerce-cloud-23-3-release/slas-admin-ui-1dc5370339_hu_29ecbbd60e111368.webp) The [SLAS admin UI](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas.html) has gotten a bit of love this month, and reported bugs have been worked on a resolved! _I cannot comment on which ones were addressed, but we reported a fair few ones that got resolved in this update!_ ## Account Manager A new release for [Account Manager](https://account.demandware.com/) has happened, containing the following updates ### New Multi-Factor Authentication Error Message > During multi-factor authentication (MFA), when a user tries to Log in with an insecure Device, Account Manager displays the following prescriptive error message: Your log in request can’t be completed. Set PIN, pattern or passcode to secure your mobile device and try again. ### Use the Last Log In Date to Track User Activity > The Account Manager User Detail page now displays the user’s last log in date. Admins can use this date to track user activity and identify inactive users ### Prevent Org Invitations to Deleted Users > You can no longer add deleted users to an organization. Attempts to add a deleted user returns the following error message: Only enabled users can be invited into an organization. ### New Account Manager Password Requirements IMPORTANT! Account Manager is announcing an upcoming change to password requirements for stronger passwords and better security. These changes are not part of the current release and are being announced in advance, so users are aware of them. The new requirements are as follows: - Passwords should be at least 12 characters long. - You can not reuse any of the previous four passwords. - Must include a minimum of three of the four components - numbers, symbols, lower-case letters, and upper-case letters. - Should not include parts of the name, username, or UUID. **These new requirements do not impact existing and unexpired passwords** and will only be enforced when a password is reset or changed. ## PWA Kit v2.6.0 A new PWA Kit release happens every few weeks, so this month is no different. In this release, the biggest modification is a performance boost to the “[Mega Menu](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/develop/packages/template-retail-react-app/app/components/drawer-menu/index.jsx)” by lazy loading menu items below a configured ‘depth’. Want to see what else this new version has in store? Review the [PWA Kit v2.6.0 release notes](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v2.6.0). ## Bugfixes In this and previous releases, the following bugs have been marked as fixed: - [Release 23.2 throwing error " Initialization of bean failed; nested exception is java.lang.NullPointerException" on SIG](https://trailblazer.salesforce.com/issues_view?id=a1p4V000002MoxfQAC&title=release-23-2-throwing-error-initialization-of-bean-failed-nested-exception-is-java-lang-nullpointerexception-on-sig) - [Delta exports running for a long time](https://trailblazer.salesforce.com/issues_view?id=a1p4V000002wFDBQA2&title=delta-exports-running-for-a-long-time) - [Storefront Toolkit: Popovers should become scrollable when reaching screen-height](https://trailblazer.salesforce.com/issues_view?id=a1p3A000001H7STQA0&title=storefront-toolkit-popovers-should-become-scrollable-when-reaching-screen-height) - [SFTK: Background color bleeds through to storefront](https://trailblazer.salesforce.com/issues_view?id=a1p4V00000040GaQAI&title=sftk-background-color-bleeds-through-to-storefront) ## Updated Cartridges & Tools ### eu-price-indication (v0.0.1) - [https://github.com/SalesforceCommerceCloud/eu-price-indication](https://github.com/SalesforceCommerceCloud/eu-price-indication) > This repository provides a set of tools with which merchants may build ecommerce storefront compliant with eu directive 2019/2161 (referred as omnibus directive) Some [known faces](https://github.com/SalesforceCommerceCloud/eu-price-indication/graphs/contributors) provided a new cartridge to assist with the new EU directive. ### plugin\_slas (v6.4.0 - v6.4.1) - [https://github.com/SalesforceCommerceCloud/plugin\_slas](https://github.com/SalesforceCommerceCloud/plugin_slas) > The plugin\_slas cartridge extends authentication for guest users and registered shoppers using the Shopper Login and API Access Service (SLAS). - Fix a bug where geolocation information is incorrect for newly logged in users [#82](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/82) - Add feature toggle for SLAS session-bridge/token endpoint [#80](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/80) - Add small delay in between e2e tests to avoid SLAS rate limit errors [#79](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/79) - Add a changelog file [#78](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/78) - Add support for SLAS session-bridge/token endpoint for new guest users [#76](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/76) - Add multi-site support [#75](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/75) - Setup this repository for Github actions [#74](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/74) - Set feature toggle for SLAS session-bridge/token endpoint to be enabled by default ### plugin\_datalayer (v1.0.0) - [https://github.com/SalesforceCommerceCloud/plugin\_datalayer](https://github.com/SalesforceCommerceCloud/plugin_datalayer) > Concept to add data tracking into SFRA. This plugin provides an implementation blueprint on website data tracking (server side data and client events) and creates a sfra datalayer which could be used when connecting to other tracking providers like GTM and Tealium. Another new cartridge is available for SFRA to provide a basis for GTM and Tealium tracking. Always nice to get to see different approaches to these kinds of use cases that every project runs in too. ### composable-storefront-pocs - [https://github.com/SalesforceCommerceCloud/composable-storefront-pocs](https://github.com/SalesforceCommerceCloud/composable-storefront-pocs) > This repo is a composable storefront implementation with various proof of concepts baked in. It otherwise closely tracks pwa-kit The month of February keeps giving new (public) repositories. And this time, one for the PWA Kit, showing off some great POCs (Proof of Concept) for Page Designer, Guest Order Lookup and more! ### Resource Manager for Salesforce Commerce Cloud (v1.1.3) - [https://github.com/SalesforceCommerceCloud/resource-manager](https://github.com/SalesforceCommerceCloud/resource-manager) > This cartridge contains a Business Manager module that allows editing and publishing of resource bundles. - Fix user interface locale by going back to the previous locale by [@guillaumebrunier](https://github.com/guillaumebrunier) in [#16](https://github.com/SalesforceCommerceCloud/resource-manager/pull/16) ### sfcc-ci (v2.11.0) - [https://github.com/SalesforceCommerceCloud/sfcc-ci](https://github.com/SalesforceCommerceCloud/sfcc-ci) > The Salesforce Commerce Cloud CLI is a command line interface (CLI) for Salesforce Commerce Cloud. It can be used to facilitate deployment and continuous integration practices using Salesforce B2C Commerce. - Retrieval of organization and user level audit logs ([#341](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/341)) - Management for API clients (incl. retrieving details, creation, updating, deletion and rotation of credentials) ([#350](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/350), [#351](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/351)) - Migrate build process from CircleCI to Github Actions ([#347](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/347), [#348](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/348)) - Minor readme updates ([#345](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/345)) - Various dependency updates ### Passwordless Login (v1.1.0) - [https://github.com/SalesforceCommerceCloud/plugin\_passwordlesslogin](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin) > Passwordless login is a way to verify a user’s identity without using a password. It offers protection against the most prevalent cyberattacks, such as phishing and brute-force password cracking. Passwordless login systems use authentication methods that are more secure than regular passwords, including magic links, one-time codes, registered devices or tokens, and biometrics. - improve debug logging by [@clavery](https://github.com/clavery) in [#8](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin/pull/8) - replace jsonBasket with SCAPI merge basket by [@sandragolden](https://github.com/sandragolden) in [#7](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin/pull/7) - replaced the use of the JSON basket in a profile custom attribute with SCAPI [mergeBasket](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-baskets?meta=mergeBasket) - updated README to list out all the API calls required, indicating differences if you are using `plugin_slas` with a **public** SLAS client or using `plugin_passwordless` on its own without `plugin_slas`, using a **private** SLAS client --- ## Salesforce B2C Commerce Cloud Product And Catalog ERD Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-catalog-erd/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-catalog-erd/index.md Content type: article Published: 2023-02-13T06:16:52Z Updated: 2023-02-26T17:51:47Z Summary: Are you wondering what entities make up a product or catalog in SFCC and how they are connected? Then look no more! Here is a small ERD. Categories: Salesforce Commerce Cloud, Technical Tags: erd, sfcc, technical ## Key Takeaways - Provides a visual ERD for the SFCC product, catalog, pricebook, and inventory model - Explains the complexity of product relationships and the helper APIs that simplify working with them in code - Acts as a practical cheat sheet for developers and architects who need a faster mental model of the catalog domain When scouring the documentation for the Product and Catalog ERD ([Entity–relationship model](https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model)) of [Salesforce B2C Commerce Cloud](/the-salesforce-b2c-commerce-cloud-environment/), you have probably come out empty-handed. Sure, you find many diagrams on the entity model of [force.com](https://salesforce.stackexchange.com/questions/22720/standard-objects-in-salesforce) with a quick Google! But not so for SFCC. That is why I started to create my own, and share them with you! This is the second one on the list: Product and Catalog! ![Product and catalog entity relationship diagram for Salesforce B2C Commerce Cloud](/salesforce-b2c-commerce-cloud-catalog-erd/salesforce-b2c-commerce-cloud-diagram-product-catalog-erd-1-786d548825_hu_77b1cb8ff5a2f793.webp) [View this diagram on draw.io!](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1#R7X1Zd6pK1%2FWv2WO8z8XJoG8u6VRURFRsuPkGnYC0Ajb46z8wmq2GuNOoMYZ9cmIs6YRVs%2BZctdaqPzDjr%2BuxGtlCaJjeHwgw1n9g9g8EgSAA5S9FS%2FbcgmLgc4MVO8Zuo78NfWdj7hqBXevCMczkaMM0DL3UiY4b9TAITD09alPjOFwdbzYNveOzRqplvmro66r3unXkGKn93EqgwN%2F2hulYdvryhXef%2BOp%2B411DYqtGuDpogrk%2FMBOHYfr8l79mTK%2B4efv78rxf7Y1PXy4sNoP0PTvsHkSSZvvvtkyMNc%2Fmf4N%2FYHrqeB4TemGcvw%2FCIN%2BEtmLVcPKjnzQnaRy65mljpOpOYA3CKG%2F7D%2F7bQodpGvonjW1zmp409XY3cdsWhU6Qbp8cSv9B80ukPVUzPVrVXSsOF4FxcvZtm1l8USB%2FZ6e%2Bt%2FtWK9tJzX5%2BhuIrr3ITzdte37jdvVyacWquD5p2N7Juhr6Zxlm%2Bye5TBHveY%2FXXJCAUQJ4b7UN7wFF8Z4w7Q7ReDvb3WeV%2F7B5X%2BaOD33500AUe3bZxb93AlR8mnVspAzyhxe%2Fi0UJM3gaWtD2%2FB0vagH3bhywD%2FIxlQB%2B1DBCFdraR7S0Af2Ur5L7t0FQICP26pSBvWwp8Yil%2FIHi6%2FXfGXGw1Kg6TpGagO97%2FLYfdHhfyFtddqQ0fkNriUsHzA9ETyZcdXUJb%2Bd%2F5JSarzBoMemT%2BToSKX6PuCOltxoNaPUR40NJkT5s6EyfiZoglyUNdt9tcL5z5zkitUx7GLkh9ZNRJZUymtU53GoqBtmjkB1onXJcEItjPBkb%2Btu2qtq%2B3pZlRy2RxPWDlJha0WWYsq%2FlV2BEMjBJuEzKKYvXmy8kqU1nXHY1aTOK1WJJPUQIIG5N802nTlUkgaEw0ks%2FfblgBU%2Bl4DtG1KY0iyoaK%2BpKPxG3DTefzuu3P8x5Za6Fdm6WleE65EOImZArVB%2FRUyD9RfARoZbaSj1SdqY3EdnMghr5AkK1eRxzkGxT%2FU3J%2BZ%2F%2F3qlPmjwVHiv9e9UzoUXvmpzAbfnfPvEnHQ9%2FueMjrjgds%2F73d8YrNxeKBpdkekk%2B6orwZQu0E5ducPewM%2BLDtBK0NgKQbYBVlQwo0PA4UkljIACvNnBWdeP3OeDjqBEY3c8D2wMm%2FULNNgLyV%2F8E3OZcLpVZOvqAaW%2B8xtNyfLhSsKcrOwJU5ryfQwoag%2BLZI1WUFG%2FgT04U7zf4G5TNUVv1FczjTpayZeZxBQVJxzCY08hWRbfOCKbmU3RctdbHiqY8Y%2FMMORY9g8LtRbql6i53B%2F4EwLz8DbTjLo56AzRcFx6WnYZD%2Bl2wZPpVvAEbrv5%2Flf1m71%2B0xotIjqJ5jBfneen5TzPzO0r4aW07wn7d97BTwtyV%2B%2FraHTWlhQhSQn%2FWlSdvZ0K41v6%2Fpf07%2BjIL9rsv9GX3HMIqLyb9cnMsMJywavTR%2BvuQ3vkTxhf95J0DoCd%2Befds4VX3Hy%2Fs8xeRn1mInb9efrYg6hI3XV%2BGZaX5L%2FtsZ%2FctX8pzA%2FG%2F%2F7KlcnTwBh%2F9yA0LzrcI91FDg299G2zcwaqp6obVvzw1FO922GFK3X%2F5Vc1TStjWYfesJihbPpHgQFd%2B9At8tsMTJtS71bOXsi5XvzJ597lj08ZG%2BAk27T3H4CYCPaDKEPxHEK6JMkNATSJTIKuwJBb%2BOYWjasjkcNBu9tWrZLqC4yP%2F7DyTRCtouA23gE0TeDNsKx8s%2FwWxntReHqb%2BuFIjIPzcNy%2BzvPn1BHTVOqcIj9bfNDIx9C9fbmHE4yJXOy8Y7Zxj6vOHuHVnGn57%2FXRzI3oSHAzB4A40OxeUxJO2h5cXQzbWTjosP86EJRiAEQ3H0%2BXX34aRA6SccIBH04Gf3IbveYfj2TXbwpmvGTo4IxTme2wKj5hRQsH33JogVj%2B4shMWmp6bO8tg%2FWIZCu127xXBwsEk4nSZmeghTuQ2o2cEWuwHk9SF26ImR5BOKHMFnftOeQPDY%2F%2FfvvVACPoHL50t54wAw%2FtY5Xy49CRexbu52PHcxMHZ6Ja%2BOlfcBy0xfHWsL6i%2FP4104j7%2FdX9GKT9y5%2FwwA4Ve8AENKZA1yrjO%2BlxIQb5sK9ufrDjSla2wdaPxoaruJYrmat8jHmho8oeZDR%2B8pc3OTrkBqkDkYOYIn3UKR29BI6EFaX1advh21Fac9bTmbuMdqPBANx7Inge6Ib%2BTva5LiMqYyCvK9IJTToGyG4T4cTMNC2MN9GGNdTCYElwBwfdpTqb4xtrk6vhoHPjpgQ0zpK0121REtnFwAPWDuwtSoXh%2FOJ6Ja89jWuuZ6dk%2Fx5Ho4lWfqxuhSSGyGCiMQa2iKrcYOpQQrN2c%2FtNxjaq66odxlshl2hbxlSBReOXc0oGeDKYC6xDBhml1iHC5lZtAbSLKSNTpA0BtNun6%2BYTvDkXZtbqddBRfneUPDyQ%2Fi9afzQEGkynn2FV8C%2FhlfwvU6Hfl2p8Nfd7qf4DwL1brpSkPeQ2t0c7jhYJpPEEvruU1RsbEBDXjt7irqMaysYD1HRTojes0lrgo0AU5haIZngE1zZSj0DEosriXprALREvVBo3%2FYsegRjH4%2Fw13JzF%2FnQevGjm5qYeh%2Bjw%2Bt4rx36EN7Pzqd86Hh5CuujGLgE3k9H9petZUN3kRlaHclrhCAONZWMP46kAUEsJJAFpi4hK2ciUEiL6Kuult1JahTey6KCY9Hi2KqfbnqSXMO8TdyGms2yM09G8DMWgp1C%2BCdpYTQh9iJF6%2BGtjzqSAEgxwNs4iaMKGRqKLd4qMOIq6bWEDuhS5OxjC%2FG3Y4Jyfp4aia4IaIm2CEtwIAMnuohTQsV8%2FtSq4UFUZz1gYitD0KMDeaThQCEWVyERMTT9XQ1mE1oNRE7YDOXcetVmxs6MV8zCYKLOi1AIvtGN0LQftJ0aKU%2B14DieDLDTBPL6YnTZi2cbKQw0fPjEQmjdDsDNERZQTI3orGiw2Soikq%2BB7KASTwztHqCtNrtvGG8lrRZsBj2W5rpA8WIQrQhuIUPBkljG6FWaasvBJO9P5rsRr3uTPgYCPxMfeUrWK3%2BEpzASqMi7IaqMRuH9upTF%2FUbUQfvy0ne2nfrfCcKLGDSEHpzM%2Bo1pJ7Lt7OpF%2FkDK8vYhkdTvGxZdTxhKOrj5v%2Bwg9KDmD9S6axfqrP4YJnfobCwl%2B%2FQWRX9vUOd9QF8eltoEU%2Fw62AFEideJtiuIbTOhBiCl4jgr0ztgtNYAHistEqiwHP1BZZYCwgDFzAW7IyxnMZQfS4SvM0mz5Hgs5lMTJxNMF%2BStNdWuLYAjLQpiM8NW%2B0vGT%2BFhjDUCRScoUdGexg21RaSQNQi8YxglIlQD%2B3Po0i1Yj6RxIweeZTi0qY2CroQXut3slkL97vBpIjTZosYodqcRZAh6Uq57LFifdqbbKexKB%2FPxkLXXvtdY4NspI3VFmMcZ1F3MmyadKLzc2AlgW2V6ftqt9V3oHnYGYByrLY7NVeMwNGGE9pol0upYMgyfDbiaCDkB%2FONz4LxCGazaSci%2B6uMB9s1aqBBU78IQYd0jLF8PO0PcZWPIUQZe%2BlM7OI9gpwk7a47iT1DMyNiiUGRtUBluMO6RCWwvsIw0Xf3xlv1tjMBBmBJ3sVPUFhzBVtzf8O%2Fuc1qIBiIGG6SQJDAZqqqXqDKmaJ7nQ0sztcir3Bo3xGpAS%2FBLt7eCB7tuVyXb1FSs8F0xhJX6arHsnqiEla%2FVFh149BY6On3yKqK7N6lrno%2FPp3TVcBrXQVCBPoSHH4NYXUm%2FAREPmRrJQP31tBO2q5qattbmFsWiZ%2BYEQmdtH%2FYlEq70i3EFHRsJyXiG0VKxrl9KOFXrOMlfb%2FMOk5n0t%2BhpN5pIq%2F01qBthEKut4CcdzWRXHnwNOgv19QSoQfOuNlaT0QgmcJY6AuaoPq4Ehownmy8zYxypratgqMll9EMYZLyWEb0EdGfcr7oqbgM8U2i33UKGBY3i2V9kf9hLuwFafb6k5mANeOsxQ38dcMbo3jHW6nChMNiymoVAszMZRndTIZrR%2B6GOuZauoJ3MyrgE0N1Cbdbd63udLwWQ0qctTJFVB2iNZkbnOCPDZo2RaxZV4caLI1SrbUZykC%2F7qAqmS0msU8GA83MeEf20R4cLcBJ2Jz1QSGFiP58LRGeATcWnXrm9kyulrWWZp3XZ6LOWAtFbEcpUAQbNorQSgMgNi2nM1cSEvdSxZVqNXeMwe1J2krmRVax4U2DsTPx1oMRCOaqEcdEDdUxaUmziGAs%2F%2FeLR4cSnCc%2Fw0Ov1z337rw7IqHYaxJ60PRMQqG7I6HYEwmXsFAqdlTvmIOqpDrViC9w0Hel6rwinX3VM5NpGOf2CQF0bv0QwIS%2Bbz43MF64MPLX%2F%2FL%2FX%2Bhpfh5M9QtDfv5dbPed2YsVnfgqnfgnXX3pk%2F8krO8Hst2n0Gn%2BDPS0h7VDqINzWlrCViHwCSUvAHhnYmjA02jp%2Bzevbxz67oXN7me%2Bj4ZLqMxrcwHrORcLcjpfeXU2W%2Buutmy2pUVifnugWliDqbksY6nZpKCmR07JZjTqi9AC0hvCmFdR3R0TQluZA7zTAwZLPEpy%2FuaTDuwMEGsN4FO13iNHDk30umiWAAi0acBAJ98G4GrNvtAO%2FUUYaqLKmUNzTKyHFDBZRRu%2BQTnxFDenidgCCJmeTpiJWhs16YDjzY0SmVq9pgukiI6kRk2hlv0ZZ9SVOSHKc90XfK1jmqMu7ogLWc2Z7LLdHETonK8npMquFxOtyGYZ%2B2NkEKnhqjXG1nCYOK5jCf11VAtH%2FaW4InkXjQNu2SVFuj8QQm8w8TxON3E8RxIaLu5NznYDd4Rspvk4h2PdAdVeN6hE6eIjQBoH64S1i2AzAJy0KaEVQguMXSh4hulso88i9Sk7qx2Gdj1qp%2F54%2F31%2FB75JB73DaJUfyWfJJ4K4Jzo7sEM%2FNwwIGNjmIjCDLTkF%2FuDM8x%2F5f9AN%2BGdFEH4MP%2F04s3jFT3PG%2BTrsAIXxJ6hEjef67xL09FyUymmM9w9w3D%2Bb1RMA3nBE%2BjCjxI4T83GsxIlOAq8fOQ5f4IGfiTSBSqKLPxHUr%2BmF55NXp7abwlZXpkAowBpuxmRRv2Vhk7UGEonan6uRN%2B3AGt%2BYxkX0fQ6xNL3IedySUacs1oG0brScQXST4JVMi9OxOWM4Z8GYyByFx7OxGeD2rLtUQjx%2F5vTMmOoreNCoixtb1MeLVnOos%2B6wKHYIdpwcnGtMbVh4D%2FoInZGz5XJltLKaJ8DjuNWKg818llvJrMmiKRT2FiIW7f2c7bY6dyYROyqKQNDASG1rhefV9zGatzkJB2bTnupTqJPIlLrmZXpGaoO0G9b8NrPChytMj%2FSuAFC2aOKT5oLP0b%2FWLQKd3WVEDVCqZVGtoULRphQBdYW1ZkAbXRVDii2yDV0brTt2BI2GBN5p9Z0FXLhIGemAGVYxKZ%2Fps5%2Bbnb9apzwTkAKdTp%2F%2BkIAUX8GUfT3CoUDrG9Li2yJfl5W8Gz1XJEyLioRSRioKVotUBByJmA0OQExEaMFmzAGxFDK5PpIkwg9pynV40KA%2BYfoPS3oewvSrqJRfHpWSQ883JVZXBPe6iujDISaFDR977PGXkJFDMMLQp7IwucvEl5wrbwKdxmL%2FAIvZDkTEyajzPBcElwxZEFTSCBMljSRW0lhktL86EYKXNAJlx8TvWrgRGHlknsh%2BUupwYQGyxNWIIMjXDRM%2BE9oClYQtf0K6tbmQX7HcqABXdzHpBjN%2BtOQKvePNrQk2FOZ8Uf5Kw%2Bt8TegbeNp2O5E54JI%2BpOmyZvXtBWs6g4Xgz%2BZFvSs58saSL61dlUcndsqsIIduQNEsp4C4TtRwpQcZJD5IAdzGFxpIE0amq1rUDCaLQmw1KAxieAFi3CBBWXYuF3IuC5FBbZyY9jYjO57QqiB2wHaRkb1uFRnZYY0hSC5OBxPbdx1tMAPFLAhpV1dsIvEQ2zF4tN9T0CbVX87ESbfd6C7bFNgkecAfBKsiEAWsj8K125kW0xX5M6KZjgk7SegLq2lzWYtAV9vQqLbMoBZLopOh7Phw1OliUyZNMx8AsnWVMvAljvqpoJUr9rwzRTOg0xiBH6LPHAVbtw5SsuUiJVvinJKUbCGo8x0l3Ja92nBqMJd7RdkrhghQVXERIbHWqCQxNZ6nFzhlVWWvHsr2zwQwQCUBlV%2B3%2FSJZTU8Eiy2S1dIJlcQcGhW1BAtTpCDIH7ZnK7XXzN%2FiGGKK0dglUYLDk3hNzZtI3QuHKtGMgO4K9%2BDphhkBdI3gUUzJhwTd7lmDLp0PaTRI4PEaTyMDiL1xCLeEbroJTEEgUXNErZUZhw11xuf7RQobVzNdEEdTYoaN%2BoX%2FAnaJZqMVNv2%2BNPTERKOLRRTo1qAJdoCuPx6y9ILB151GbVTUVlSCZBiNRuQomYt138glDk1B0yYJBlK7i%2FHUJph60KDDRkNLk3wGERzJrYkjtmmDtjrUzdaARYuVTugW3CviN1N1aOQPikZdQ4FCnB93111p5WSQHWMN1W3omw2MUVTxjKEaRPZYcTKMeQjsQyoe07WWg%2BCB9onKIVVPveueem7dqdNqqD9FuBRTZPcrCFDiuPotvo8zuIXrDD6zehRUUoizmsqppnIeD4XhTy20c71OeWZCHSqJ2PsJUqGayqlM%2Fz2mX60x9Vunchg1Na0wzqgkyW%2BOf7xmyw1ndCqae8X5nA%2FAzT3N58BngivgH5ib%2FgRAf0ozfIpyrcx%2FwMHc4MHwBcInW5OlG59Ozdyj6AKJ44QMdD%2Bg3WSQO7PiCHw6O1iJrkp0PSbz%2FNTiDNfrlGem7OGSmdFKdFWi60FMH6mWJfmtomsXP0elaexoi9QUQsP0vkd3VTz6xjz6gqruwyuZ3IWq22fylw75H0ubuw9rRMvt6FW854EtIui1zOsCMo3YVxjbJ7ch%2B2T2mwyLZ6IW4E8kzlcyrZJpP4%2Br7kHyXrjqmQAFuGRBoUqmVTLtUUz%2FDutEVDLtJjKNWqpObuqOl%2B%2FynRKtIsV3o7k%2BAE53pbnOxLYgP9ED8Mq8foKOwm4ZY4icKReBVNNdlY76HWTyvnLmkTMRDUg13VXpqAc2%2FapcxG%2FVUbvprpdFInumHsbG94ipiu1eWSD9zNIRyJk4FOQ0V%2FIHmMz9zzK9Cga87TQTeqYkA3Iai1zJo0oePSZH%2FFQi7PU65ZnQAKQkL7KSR5U8ehTT3w%2BglTz6pfLocLapbS5NL%2FkmhVTR3SvKow%2BvhXMX8gg9E%2F%2BBAj%2FPXt49PXmHwgmFvjGJCj1TuQItqXdcyaZKNj0ed0TvK30fPTO7j5ZM9VayqZJNj2L6VeWKXy6bxKi4gG8Mz6v477coqQ8A0V0pqTMRIOhpBMj9W9LzOAWcDFR%2FyvLtnjX6qcGR5PMRTtuJV0PdmSLnBHZ61N1SuiclzZ8TBE9PBZe0QYej6q6tiAR%2FPfyWNRbFxk8bny%2F09DrBkvNg%2BKvGXYAsUtJ4mgMJw58mBN%2BjX3Hs9dJpCAG97oEQiV6g%2F52pAoIiFxGwHS7kLU4wp%2FZcECR%2FrmckxraGks%2F5ppfEene1afQIT4WLMcnZZBBpc8YC9EaWG8774ETAs9jFIMnPuq3aEGzKNUXJ6iMen8SsYPU37aKYuqkRvaXWgtsLbVTI1BkhGq1pKA7spQT67T%2FbArJWJLXEtmWynsi7pB9O0Ckn1ftyxKxCEdVS3mjNO6uabXuqzwa0ImWJAzpWmHN2dgjPh0lzUUPMmZ9iltvYbNh2Nx7k55LilmFlvVx1tgYbpItShE90ZHKVpcZEns0boZFQyszXEn261HvK1Aq6whB2IYfQ7b7ObPyiLj3URmdDbdyom0TSirThFMgND6KXkbxAWVNF5aoQ%2B5d4%2BqeKHVyx350JsECvUoz6%2BhrVzTWqcFCIfSBs%2FUTM60LsNCMsx77pqKNFZzhbhIZMmrMFNeClYgWdWnsjeLTnct3mnJKavNMZS1ylUh%2FI%2BrEz0SboD6x8V57Gk5MR%2FA1dUay2fPcJG6fMBNkncNzCk4GdiX1Aq5rQlWf9VwD3HijvxL2IQWc6ZVUTuvKsP7Dp7%2F1rlWf9V3vWv8mpXpHi%2B3K3fwCd7sndjp2JV8F%2B4sTN1phKjGxrSz8scumlmsJNxrMzQRJYFblU6avfQTKRd3fam3TKM0UqsCpyqdJXD2z6exd1pa9%2Btb4abp%2F%2Ft4isigB%2Fk5Z6PxLdlZY6EzqBnYZO%2FABTeh6oflSOPImTN1RMZ6bssZIp%2B0oxVYrpAWkj8e5ee4tOiZ%2BJJMBK6lZUiqlSTI9i%2Bvvaq5Vi%2BnWKSbVMwUzVgWp9k1Sq%2BO0V9dD7ceae9BB%2BJjgEOw0O%2BQH2stPOTwBWMjwRp%2BPTPsWibGMIu5bRXUNUgSCE3U5V7Y9RajUlS2lUqqpSVY9HLfH3d9ubdMozYQL4qZe0UlWVqnog098XbK1U1a9TVc%2FzUN3Y0b9zCdKKK9%2B7QPsAZN2VQDsTXYKfRpf8AKMrNa4fILgwAPpOwXWm4gJ%2BWnGhElyV4HpM1om9u9vepFOeiSXAT32tleCqBNcDmf6%2BBGwluH6z4OKDafg9equivjfXT%2B9HoHvST8SZWBP8pybo%2FdCqzyBBIt8ooogz1SnwqjpFJaJ%2BBZPcA%2BKdMMl9uaLSTllVp6hE1AObflWd4veKqFw90WHofpN6qojvd0ioD%2BDPXUmoM4ElxE9civbVvOc9aqVXE04wgNxQK52pNEGUJLVXWqnSSg9IGO8r3Z44EwtAlMwCV1qp0kqPYvpVpYnfq5X%2BTjgNVM37pkITFdO9sjj6mQUliDNBIMRPlNnwGzL7jQqQzwYG42WjGlHSiJPXMsULiK7T4n4gWLKuy%2FXGuDO1KohqfqrSXL%2BDeN5Xwj55Jn6AqOanKs31wKZf1ar4rZprqMaO%2Bs1rklbs%2BZbs%2BYJC7mdWwiDPBKKQPzDa9CcEBOZwBx49eAS%2F4RwXeaaKBVklVVV661eQTvL9vfYmnfJMsAGJVHqr0luPa%2FpVFYvfqrcYNTWtMM5y7PmmkMCK4l5VFH0Aau5KFJ2JOAGB06JSP8Bkvml4uo2cQvYLlO%2BnrzAEuqGcOlOjAgSq1akqPfXTeu3nSOV9ZeqTZ%2BITQKAkkrcSVJWgehTbr6pU%2FFZBtQsa5INlfqO2wipJv0dYVTT5XiXZzyxoUdjTmRH91EX6GWN7RNP61Hj2YQW2Xwt0L8Dw1%2BGDCP7aNPZtX7OLM%2BUtQKBkrSuYxFAE%2F5dxnOd6s2G3x4W8xXVX6tj2EYFsNNaLsLjYuAkIwVjKlkhOyjgu6rcbLuaRC3w5EjyfHShLF2kmLXUI9ockKugQj1s21fCVaNBcDuXeqr%2Bh0OGAJ%2FPbQEejRgLCS8NUxDgaGSBkC5u1FTDNsB4zgSX3%2BBVON4xQWS84j0V6mLgeWO0W5bDGiFpzRmMSxYBdyMBe0BhGCaoM2P4QWVpzgBRnllXTmfoKMFW4riwpDYTYlU7oGNvO9%2BhNQm%2FhaBg0Xlqok6lMb6k5PTzODHWtI0o%2F%2F67jRE%2B5eaBOnSk4p9creRVIFqkO8r1H%2BfhBt%2BkQM4kWv6l1M0VeGbMBM8sPXaMgdPq%2Fqscd9LgXdPsYhbxepzoTFQACJWtV%2FdOp8Y5OFQ1nmmwna7YLqVNjPPHmuQ11G1Lhy1gpPUmYjzhGrXvT%2FMbQXh0jPchcrIDNKkXtDd5nsdGSXdobY5kbYM1MF8IiTg12Q0Bd2OyimdlcrrC61ik%2BNEKDzAzMX9LQKlo2VnADLuzZRqawP8n%2FgjGym3W7gw3RXRLIZiqsiIaUcWZropAjPb%2FbnJRvhcD6ZrIJ8r%2BkNBhRgppuOKBVIzZs2%2Brx2WylJRuEDDCdIutKSNQ9BjDa7jJcNUesQCmJsICY1aSpeW2o05NG7XieEQbQw4hY7uEUqHZ745TvRaPpXOquRN8c0SabGw%2FNhlQMOfxGbems4NCDYEiN89s98gHRo4eYR%2Fdm%2FMiNeg4uCvVF2wH7Dg1N58NWFMF9PFx1ZN%2BwMKYxUk2xo6YKiSvLDuGN2gOr16Y4ANQ4ZzWjwS43guox33SZhEVcyxjxq4bbnBu5%2FdBM4uMznp3bfv71JxCTAroXjPFhYMbWsp45Fl3vr4eCVpv0JHkRE7PMsutwc%2ByC867c8Tb19awn%2BHyGhayH1VZDN5el0ITw%2B2Y2QEJjAuZmTAeg3VkRyNzDG%2B5KXEZZgq8n8ETpr%2BtEDZknrbAW1CTP4Zh5KPT70STy0lBomRiwmi8zS7bHmez3eR8WHCp%2FrWdIuIqguTtviuOBk9g%2BLTsKo9tOc9Kat5T8Pg%2FlDSAHnNoXlUXTUv2cvnQMbwVkdsbhfX1tNjTddVBIHja1Ws0eeSrTduMUWzjWjI96TBa6E5tThhg%2FaQvLqbxmuWTUVAlZ1LhkLtZJq8W3ayqCODNxtQhgWjYJCMfnDjUYAstIDFu8mGKyw2i8O%2FVa4Ggeh0Dsa52OgyS9WVvKQDRaGmpDDzRmQEf9Fat7sRZv0rgXxXYyTawGuuGV%2FKHMfbseGuGEtrB5pivJpC5KKgj2SD7EU3wtMtIo78wYqDVanmmNVF3jIA0n54nUFjdyGnEy1hn60qqmphIhFx66%2FIms%2Bsp0EbhJvG75w0loQE2NWQW%2Bl4gzH03mgGKPkxZPZIDqpvhYXXUpYk4bRE7Q4hrrZ1Lh5FBBsjkvumG6mHddpoVsxiqdSAiFJf1BJ6BjNT8RGI8ND7FyvpoLC61TJCkIpgibmTUZthXDRgZDW1F9OoBxFCQXGz0j6QBvZzlUdOL8fOaouWQ7i1E4wVq1DqjREzodAo0uqnX7eS%2FHzOUmTIdzvZGfS%2FGb9kLpDhszvLY6cIZUw9O9Dk9nQphA4DRnpNICt9QCCHQc2wbC%2B8jIm1jGmTgaEChJXEAIUEWRL6oBpd1jQ37FcqP8ApWCtrgY0DdZs5m%2F56ia0uMm9VY3Izd8M5GRNa6mPgk3xcVA6KX%2BYIJKkIXHKp6%2FKkam93u8Psc27XEShfOmzfuIzM4L4OyMx%2FXpsKNGfX8x94sRUu9QS5sR6FHd9eJw0NLzNrLp%2BEGf6Flblw8N6WkqrHK0Y8QFnrorpqbbjaYyFu1CYVA8o9WAMQ2HsN5sbpbihG5zjZB3IEZbTQYqY6y9kd0lMn5Mh3aBzGiHpGOqOLk43BCsWXzdTTqxpnwrGntm6NaGtXp%2B5pnpqcFqCOFYT0zmrqNXsPoKVuH7gtUz1U9A4DMLnL2T9etzYcV2AXU8G9aJEG4EIxxvoAAEjyTIhwd9g52SheVFVtJmaZ8ZdsGOaouzedasdXsrYpp%2FmP%2BMwXE4dZBxghXOyvx%2FQoxJg%2BwNiHgtdKIlnujxAovCxGw1Ulz0SGiZ36BasCE7MVm4QnF9FCvdaVEFpgZtproYrWmXAfj10IQlSlstl6zs94huE1IXnDZQFJ7oe2KL8giyjYKMIS1Xfc61UkgoAh%2FozRRw6TCBMYKE68TMivjO9kJrwRgmZiytzOpSZlN%2Bc%2Br0iJZQo5mc5HOMgLYofh3Ow1kQFDLaoNvWyg9nk3FdDu0OE1A1Vq5j3kS2tPGmNRfoQDO7EtJQZbOYngU2loxIMmuCPUtneGzad%2BRGt%2BUrJMmowtpc9EeKopPFhYSrcMXGbSVBwGVxxQC3QR1hrVNLiBCcpt1x2HatF3RcdyEY0pBfNJN5KM7bhS2JkWGM%2FJRfEMpEnqcq21rkLJFGNq6Qf9qhXQlKNo7bhfWRumhnvS7eFUS0Oy7mjC0qkvPDRQkV1db%2BWK53OGxurtpCI%2FM8CYCxAVCIDMHNn%2FdonCKE3aJIxc1svV2jED5UO%2BHGt%2BnWhK%2Bve2Zm82IL80bztR9RYaK10lkIDYgR3oSGdU3yIBcHfKDjq6DTQqBWO1iRcwB1W%2FNkOlmEMYSMsVqnjkZbr0ZhSJI%2Fwzw3FLjQn5riHFsC0UANaAAvpKhD0ToRq91Zl1gM6uw6M%2B2N5kw2Xsi0yYhZhPVVve0EHT7U7b497vRa7ZYsQemEx1uuUEeGjJP0spoar8W%2BNJlx6JyztOEqBZYStGoxaqPGR03R2pj2qNkXc2N3RLc%2BUYFg7C3mMZ1K2qC3bjNBm9fHLd1jenKuDRzCgqz6HNdaqtQBKRha0e141EJrEDw3TH%2BoC3W7JjJ1s5kYE2e6cFscW0sRtSGzMpd%2F446IpgpiY6tiHp2u%2BfU%2BG2PspD%2FT8%2FGijrBxZzKjNKdBCA0bH1OEkRL5vaAbOGHpfGr0CBjrcloF73cN7%2BeimsBLTNdUj%2F6zrBlE4ZMgJqCkRvT1TONcEBNYEsQEaASE618b%2Be0T2ky6KdPGVJotBojVjOdnfCaJjSXcX9EdtwGDrAovMKNTl5WOa0gKReYkO8U2HjDTrEVdoSZOTgh6oaFLK8WeebIvw00tmUfaWpx1mlxxXBfo5r8HMgp3FmZIdT3KlMeujeO9fnM61Mla0pYgUPRszO03uElPrAHkyFEIqbZc6eYoqI0ESiPMMQtlIjRqAyirMZbdSakx3l3KscW2MJpo20S6BPwYgeBUKYZZQUg8CM7IRfE3PbVy5kKSqsPjAU9EtZHBdwax6VDb2ViDd8XaQoArLD3G0k%2FFWFyvw5yLLwJL4osuQ5VtTU%2BTFctmnenMlVf8FIBkf2BCUn7bcq0npwOxBWzmcBuSSYbiZHUwLsSo7yaMuXEkdcnYhZGRBLlYUMvCj47pW7IcEN02apC2QcRWQZXzTxLRK7iAjIzEGltsFGhLcyPCheoch9pSIwqtqeTcuwY809osKD7kMIRdhQDSoaYrpD1pjtcpOgpWUxQR6RpOCPGkK7KN3sbUZZ6oDyIPszuSHmKE5c0QmwqG7a4tcE2pPzMJqXBkykBd4ujmgHZXOj4ZCVxd6K%2Bxod5fW1KyQFABcNe27MG6IwwdQeYcwIZrmEux04AwcgudNtg1M%2Bw57Znfp9xpt4VMWj3JaSoMIFjDTahlfIdpzyUXZQJ7oaBD3VTktTMCYkdPR1krnbZWUStKmi07mzcy1E8oBe2D4riJMzV%2BjivNeRNa1q3RfGTzkyG6bmkDMcNyfZ1FbbOhN%2BY1DZ5njoklwaCHTdJ0xXk1M0F7sLAYLjlR0914xJF2D%2FA2fWgYwnh9zoSKlN%2FMtdfMHI%2BqF49tPLe9Rh8040UYeVw6jFKuM8Q7ibqJ%2By14AUZ1Bo%2FaNbU2XLZ8vtkSI543l%2BpETa0QxCdrHoD7%2FKTwdwoulBlUpNeGTcGPwBSSZKOp57cDKYIhC01EmYuh1ZBpFB365sAKByKZIpY3QijecX0K9Dmp6efgiw5rmS70mXQyD4T5pNskSCFlQV8SxWFtEQpNqZA8lu%2BvGgxKY8tJR5EZCAcnOXyPB7JKLJx1MZvDiyEkdabr0FO8ethkcWmjdkcDdMmmzdirqROUmdgUNUqJmsvY3KAzdsKIt4vA0ZSTFpQwwwRdwQ1e89W2rE4yUB%2F7fJ81MsicMGGzxs%2FSca%2Fwijv9uN1e%2BjITSSO%2F3kKK2Ruh2Zo1LZLe1GJRQ8e%2Bk3BQoSltyaGxpkfh9QZa6BHQdfPfdW4omw1BSCk6JgJBlTAMS%2FVcq9ie4kwSr93z7dFMJzttmkdqDLUOhgmU23kwL2ZG63wUS4XXORbiJkNNZ6iXpWjc9TYtq8NP3eLmS2MQIxoh3kAMoHgiSoFMOGW3V0jSn3ZXjWpwuOvB4UxFIxA8TbGtiPb3Eu19GOYtLAM8F8QEluV5Vjy74tk3hVLyrqAUPBfdBZZEd1U8u%2BLZFc%2BueHbFs3%2FB4HAuShH8gXW0vskYbrS0B4ofh4kjIPqKeV8tKarQXWeMpaozW%2BXp%2FrRu%2BzkMB9%2FfcW%2FTL89FbIFVqdkqU%2Fehrb8qfvRbc3UZNVW90Pqm9NyKHt9neu5HEOqu8nPBc9FF0CUmPSpru%2BQ6i8cmc9slPwq9dcZYSuZBKjFWibG77rafpKP3VTmm0Ftn%2BmXJdEslxiox9jjWXxVO%2Bq1ibFc46WUBECpNY0dbpN%2B06mJFmO9Wnv3Q8knQucgj6DS3r7K2%2B5Jn5E3V2T6Du9RW4NNEoUqdVers3nvt5%2FjpHjPvhZ%2FucaS8X5ZlaVXqrFJnD2P9%2B2zaSp39UnVG5RewNFk1Vb9LlVU8%2BT5V2Qew6r5U2bngF%2FgH%2BgC2FlO2EihRLBEKvm6HTtvvUI0R%2B3KYO1NBS1KGrjjunavKA1dzZZUa%2B2ljwyf5KHJnfPRcwANczZVVauyhrR%2Bv1NgvVWM9Uw993wyM7UzZN0mxihzfmwR7P0DdlwQ7F%2FICn%2BYf%2FAQrKyJIy6zpLesj71%2BBgSABH5nKbXPHoHMFPeDPFEatJFglwX4gCSXui4TC54IakJKJ6kqCVRLscawfrCTYL5VgL%2BGJ9dyoo%2B%2BSYBU5vi8F9n58uisFBp8La0GgH2hk6A9UVLmkuqGigs9V40BOfTuVoqoU1WNySvj9Hfc2%2FfJcQAJSMtlcKapKUT2O9VfVOH69omLNqRM43zizVTHe68qkD4DOfcmkc%2FEmyA8s5%2FJEEtuR6fnlTnXSaezfjWXSuToZyGWKFna2Mkkwp%2FZcwFecyunovJBApGgJ8djh63ACrY02FIY%2BpsNaYhPJsiimSNM8OZuvDFakIdYoChf7k6Qo5tqc2pzYNkgVX3WAfhPhAycJBmbHeK5eTIoK0OiOpiIYLXG%2FXigj2YaM1mZGDhhjRA2702BhynEXbM%2B6UZxYlNwyiluWazPKQhJxgG16taGxMMEVOAizCVYzAK5RXECYgH4w9Zk21FpEYgf0wiVtbdqddXFdWiySViL3rCGvq1240dNqw2w1zNjmbCJl9ppNBlDYCfOnmc1pdNEXmXqrqMwszQbcepEu%2Bp2UZFtDqmtxkaRbQ3llcRs%2BnptuvYcj09UsgGYEU6yQCY0VA1gg2dLuRUbf7CFFaV6%2BEkpfoop3VisAPhc2gDxw2UJWGhXrO1J%2BjTe8IBx5sQ1O2vPmsDsO2xafcVRd8iJ%2FYGUZ2%2FB6FC9bqzqeMBRVyaVH6wNVvYzfKpdEbZaf%2FEU0DQsL%2BH7lVJHgK0unqxW%2FIMGnfSHga2gn5FygCHrKo8%2BbTclAXbamyHWthsAPx6MPm0yp6d9g0ok8WXwJ2x%2Fj0BZQ6LUh7OnW16zgXF0LtISz%2FUtNvdMUXmmugfE8NTWa2m6iTOhFCkJBRgUuE9lNr58MaT%2FNSRo9NXIe5kLKeDaEza4WECK04tIZPDNXMqdu4E2MRXMMJYoVTJga02povVmQrpCAsnS2kDxNaB5MwbCV35rNQhEsWas1ZXswJDa0IuS4Pcg%2F8FqhIM0JqM5RrWIV9FQZS%2Fok10MBzrEyTzfFUTPD2BG2rvetMOkRJNildHTgB52ZDc4EjG26utEkUAwbj1MPrs0afTALm2NjpmbjcIzNwbYhLbQ2tA6Mtse2AlGrtclJ02vCk5Bd94bztSRyaQddcUCxQlU38Ps4vYIaLA9pHMrTvvss%2F4LFOBnvllCX%2B%2Fiy0RrVay4adymo%2BLZQM1r53cmgA%2BpacfcW5CxXlzVYlGdIG2HZzuqAgT4iq%2FyUR%2BQFGz%2FIKq%2FXS%2FewUrHK38YqGTU1rbCwl2%2FhjxUReBcRuCCh%2FAD27D6Fn8BjQgk%2F7ddiPkQnBHsC0BKAAp9w9BIYdS58BTsNPL5%2FM%2FrGAeubqChGEEdmRJDYLZnouTALrKSSU8VEKyb6wzr2J5go%2FO5efJteWoWD%2FFYmuqs49U1EtGIQP4nDvh%2B17ovDYhW6XQbdwCeILIE3KnZU7xjcnv99AdxyZPw3mkXP4NU38w66B7Z4S1zehWBf%2BtLXwfQPfu0deieXh%2BoDZ0Ex2WQaltnfffoygaTGKRXH4epvmxkY%2BxautzHjcBAKapDtt%2B5vbymLPm%2B5e0e%2BQrZD%2B7ksmL%2BJhgfI9xFEfgWi5tpJx8U49ATDCAAhudqCMBTFgO0S7sWnk%2BJaipEbhgmSgAEUIBAcKZaMff6cXe%2BGse2b7OBN14ydHP2K8zy3BTkSPp8M3b%2BdHH7291Dbd9nhu9ODvak0k3AR6zujQHdonj9Ly0yP2woLOTsmxKanFmUtDzYqB%2Fbdrt1i4P07dPwHnqykHE6nSZEi8nckyE1PzQ622A3drw%2F5Io2Ro9EJh3L6hh0e8dUuOIZsgz%2FP7lVEjWwv5e%2F49HIf3jlkVUWHrjtkfSN6azmAeKbxF7qB0rHrebPrIjtaIfuHkR08wPEceAEQIxEyl%2BYoAsE4%2FHkQB%2FMhAQJwBCMInMQwAjjG9CfsaLCA8McC%2BR28IsSlMR4ECnVxnAFK7mrqvAXypfvg8BOKXBjliQrlH1WYOLrJB9PwqvCNfAm%2Bxb8b%2F2T0PpwzeC%2BE51CLQhgMojhBIjiMkUeYDmEAhMMkvn%2F9PKZvef7RmYht0tMBrJed7CqwjkOvYX1HW68O6%2F%2BdxrZ9BNeP%2FDwfRdgqcPdBEVb31CRxpjloFGf4G08B%2FMGZLaUGcgzOb2BWEmpxeSSGy5HYUBP7BY6KN121uAEFKIHQU%2FE9AewJACrMfh9mv6bHL5iNwDhEECCMoiQMQQD8BSJ%2B4k0Bb0q09wUYr47IIIlcmmrnYIk87ZNOT6INLsaZUaBC9MdE9LwPbLMr%2Fu9%2FV4Vq6EZQ%2FSjekU9g9Vus9wWtgbyFzD%2Fev34FrMn84ODB6Y7pNUlgMADmDH%2F3ejUwh0vA%2FCWN5Gpofms%2BvefxFfo%2BGvouncTRPPO43uJ1vc9ghcTXR2LybU9H4Z048j1AX5qDLDvTC4k%2BPdP1%2FBylQLyvGHntScqTcJWbwXKVSfKw04VhbJhxz5wv8pMYJcWbrovRQDlGV8j7Hn%2FFGR8zCMEQgWP4%2FvXzwPvin9hPSB5x6xdv840IL%2FROnN25DIAnCN0vsHRLDvzGvB%2BMHweEoCR5eLzXOyDI8Q4YAHxsBwT94A4QTlzYoVKtNvywY4dhTtWF9%2BxWueYwgZBfGiZ%2Br1d7j%2B5vY%2Ffng0neZuM3HCVeRoTb%2BkVevNzfxMeRClMfFVPVG1NwpArS%2B7Tz4zTm%2BsARXLx%2BHl9P5whv5954cWV8jnd%2F0b8BYt8EqFWC4uMD6vVdzsgbLucKS%2F%2BNpeDhbB4IoHv0vAK2lp7qt7mSv427VtmSDwu18X5Ba9PgU9O%2FJtTC%2BCeh1lcD4xc7BJ6gk8CJw8gJ8BRmka%2FAbBFFh5A4CaEwCELAEcq%2BmaF4JVKLvEbaWyUWfoHSlnsdiH05jX2CIIju89vfcvP%2Be5cLOHqrnMLHB3b16v4IuEoH%2F0IwBoEXwA2RCAagxGEq4cVTwok9e34eT07DMUrGkZsFOb%2FA%2FcNy6Cqx72GhVtULg2TVVL0qyr4RplzNqP0DZLc4epQogpDEAc7mwHgMs18A2buZZSsHWeDKIHtzVCXfvBnvL0kFFVUnj0I2MODtb%2FzuGlP7g1SI%2F3iInyy0XRKhc916HBBRUevPoX6BxDACIRiKo8%2BvR5CPAySCHvx8GPLfhcL73L0jFN6D1l2h8Bv5exCE7GtcvDgi4KOaF%2B%2FaB0PJJ4I8gc8vOi%2F2oF3h65Xw9dsST24VowZVDulPOqSPHQnEIZu%2B8MRf6am%2BwWmxZ3OHSI49uM8CgyqEvQjCEk%2FI7WpAf6Re6FDNMb44x0sWyXXZ7GcdxXnTryazx0HBR4nS%2Bevn8fVf7oqyM10FXomyEDbwRjHB5DfBa5Vm8bAOgh2%2Btp3AvSaiwsg7APXEGXAArIdbH2DoX0RFHxZR%2F5GMd7m8i633Gcs1MYBhMAkACJgf7xhlwedKoX%2BrFV0NZvfZyN9RyPPbWGyVefGwMKtfv5IbDHySs%2F5uJ8Ft8fXY0Yuf1EkmQODw54XjXj46GH4Nr7cr3%2FZN8FrlYTw8vFJJkn973wyuuqwI9LWU4V%2FsHvhHJczDGvEgSLzMhH3GIXuMrCiCkwgKAbvXqwFrWTTDHmyvDazwF9wDb1RwgEj0ae9c3c%2BqEdDZWbV37HOBKTXsjPPuc767Eol53CtLJaZKqlONuKdeWboixEF1QwIGcRIicZTEAQRCj5eEIDEQhQlk%2F%2FtrNbUgpCgBAuI4gpDgqcOu7EzXic8vm9l%2BdKpThcs%2FLNV5tuPXS19eXE5%2BNnf%2Fd8vJ48T98oTPq%2FnnEPB4SZ%2Brgep3uufAyxf%2FPqErOTl9Oq79XcK1wCccvshexNOOIF6OHVUh%2FA8L%2Fy8VB4TQML1r4v97aPQh2lfTNTuGfVTSu0iEPabY%2BNGyOciXKDYJ4zmRh2EMIEmUOPEmAiejAXS9WfGyagMPP11Trc%2FzuCi7VJ0cExwv3%2BLaQIu8Z96mAtqbVsgiAIgEEBRDchSH0b9lWnac%2FiTZ9WqwioDfAKvfHMuJV9lIDxot7wTL%2FAaEcdYz9TA2rgmpyDsgtcpAfYf34oIlW47Y6Rt4fTMU3dcseVgUrXKOHpac7q9f2zfkVk0dENa2uTS95GgpMq0ESS8OulUG6HVCkA7mrbevnwfhd6zpW3ay26Hyg8%2FL7dcxrlD58VBZP0iz3y3kGwbFgW6Sf%2F%2FWKgbVgmQ3C17aLt176ha4WqgomfNm4u%2FPbSOabhcqCnxT0W68Snl6WKQOo2sXGkSrANF79OqerntwszqCJdH2%2BzT9u6qt8iXErLKXHtRv%2B4yX2yIn1wTN575d5dx%2FAjNx%2FKj4yBWrnJSdqSpychuArfKXHpaSRqplCmaqDlTrqhD72TpSv56X%2FkP7Ey8pSwgCYPgXCp28w0WLYiCGwAS8e70iby2R%2Fti1l5C5gIv2jbhhgISf9kFb2b4N%2Bscatu%2FY6esBu3i1bs3jQnvs6FcP1sU%2FuzjYb0%2FWIAkUwXEQz0EWhmBsn%2FC287Eer2jwJeIMnAYFv8D2PvX1GzNU9%2FNSj%2BOMqBLgHhtQ%2BWAaXpMp429kv31yPu3YSVEF8J5lun9Z9V%2BfBbBblO061QNLTnQV7N3zvJti755Q79ehvTkWV9loj43FdBi614Ti90ymVfkRr7jtEZRerowVeAydN1snhihx%2Be7x9HF4a5VT9rhYubXv7g0Qk3hPRlmV%2FlDi5b0SZn5j8kMZbBLXjj3YU04EurQTFwJh%2BImEjv2x%2BwLVby70UrYTQIBP56s1gCSBPxH4P3b7uvd3%2Fzgq0H9A0C%2FgfqBq3jXXh3n2JVYM%2BeOlGkqdsgflCF%2F7ZD9dquFocRjyxPtbVhTiOsNByWLlt%2FNAHK9e%2BN9%2BKd1bs2yiSo57bMC9Nr%2BuSqPdMbsur7l2MzS9GbkGQfjS7HrLeMkTxgvvMvUux3ehCn4fM1J4uV%2Bl69rxDsT7fMKH%2FoyK8z5j5T6KYe%2BIOMbKL1X8BfOujebHABEQwAkCPo0OvlXZnLI1um5WNucLCWvloIzuR5QXdwcIP5HoWdfFO%2Fa5AI5XOXIPiuMv69rmFxBcs8gw%2BVlP9e9m0sATfhw2cUitLwzquW4joJwXoihIYDh0FItcYfp1%2FRRVSt3D%2BinyQ4e%2Bn4OVeu1kZPKzscG%2FPunjdTIykIPO8c9XoPXbJgX39RuO1sTYe2Ov7biAkItT5Bzo0CO%2BC6Po0245nLcoMkHiT8S%2F9roASa6y9h4Ww5%2B7D3P9pR3JyuH8Kfw%2BQO8rhsAVRA07%2FLkabu9jGG5ai%2BcCac9voDYEg0%2F76ODdWVAQPIva5ftgTwh%2BYdiuMvIeFrbDRWrlVmXtgfvaa5%2BT71tJo1r7%2FIbliE8gHMaJwx%2FksRB8P2O4X4hyj%2BgXnz%2BE4N0CSC%2FQTBBPyHlXdbE65BMOXmY37Gl30y83EFTZK487EES3mKskiXfBfxWdd7tS9CCJAySKwGjB1hH8xdHy4uY5dmrj12P0ZaXhru7WvhzgY%2BAxFcdB9OkfDP7fu1wAtMkz3bFKJzu%2FRvBxmNaBYt6%2Bfr7bvaOoLYJhEHjwcz0PaNmCZberavt53vWV6SSyyjN40Pn63ISf19Q5WvTh0kQGBOB3QGc1k%2FTxFR4uGAt7DKg3y84lSyobXH2Nne%2FG0yqN4EHxNA7Da0Y9geB7OGg1n%2FNtKPoOqloEuEIHP9ejqiD4nT7D49KH%2F0GXdhmCBIid5uYWqXbnJGT5PvDJ6utfl5H7U1QA%2F2gA76tJcXOvCPFQFdl6BYg%2Fjo8C9q6KTzkBESRXxAReHAsiEQx4mfT5DZGtJ9T5ZUbo4pP8OIyeTtPk9Ae5MFBXmQgPCtTL5xSEa07Pg9BnA2R%2F%2B8IT%2F%2BLjf7nz9vUrYI0iYE7pcRwlYRgDnn34vxyrsYtP3%2BPE6zI5EHDhgFiySmp4ZKwuDl7P8SO6LmRDFWRfA7KPyt3kr1%2BB7JelMhASJ4uJ7l8E2S8xswB%2BaZAmUORViYb8G10YpNEzne%2BTqxuWTJ4f97qfPHn%2Bpin%2BgCAOCDgRaBh2Zn2T9%2B%2F%2BcgHP3XG327mYvn8e6bkTvzrSv008f7t16h9sHquR%2FRz7BXP%2FHw%3D%3D) ## Why did I make these ERDs When I started working with Salesforce B2C Commerce Cloud, it took work to wrap my head around the object model. Sure, you generally know what objects exist - but how do you translate that when writing code? By making this Catalog ERD publicly available, I hope to help junior and senior developers by making a ‘cheat sheet’ of the landscape readily available. And honestly, it was good practice to build it. One caveat, though: these diagrams can get out of date - and I will do my best to spend some time on these every once and a while to keep them up-to-date. But you do not need to rely on me for that! **_If you didn’t notice the link below the image, click on it now!_** ## Some additional explanation ### Complexity It is no secret that Salesforce B2C Commerce Cloud offers a [very flexible product model](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/products/b2c_product_types.html), supporting things like: - Standard products - Base products - Variation Groups - Variations - Product Sets - Product Bundles - Product Links - Product Options - Recommendations ([Explicit / Manual](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/recommendations/b2c_explicit_recommendations.html), this is not related to [Einstein](/ai-einstein-in-salesforce-b2c-commerce-cloud/)) But having all these options available to configure … means that there are also a lot of APIs available for developers. I tried my best to visualise all of these options on the Product and Catalog ERD, and you probably noticed I had to create a “big” Product block to make it happen 😅. Luckily for us developers (and architects), Salesforce has provided some “helper model classes” to make life much easier. They tie all the complicated knots so we can focus on other things. Some examples: - [ProductVariationModel](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_catalog_ProductVariationModel.html) - [ProductPriceModel](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_catalog_ProductPriceModel.html) ### Helper functions I have taken the liberty to include the provided “helper” functions in the model that help you during development, and I made it clear which ones they were by making them broken lines in the diagram. These functions quickly fetch another entity further away in the tree. An excellent example of this is the “primaryCategory.” If you look at the ERD, you would typically have to fetch the Category Assignments and traverse them to look for the primary one. Thankfully, we do not have to do this! ### Some “functions” missing I have tried to include as many functions as possible within this diagram. But with the complexity of the product model, it takes work to balance layout and readability. I have decided only to include the most “important” ones (but not to worry, 95% of what exists is in this diagram). ### Pricebook and Inventory are also included Yes, the model of these entities is quite simple. Compared to the product entity, these are peanuts! So I decided to include them in the product and catalog ERD. You will find references to them in other ERDs on the blog. ## More to follow There are still quite a few entities within Salesforce B2C Commerce Cloud, each in charge of an essential role within the entire flow. Next up is content, [so keep an eye out](/category/erd/) for this blog! ### Mistakes Don’t you love being human? We get to make mistakes and call it part of the experience. Please don’t be shy if you spot something that needs fixing in this Product and Catalog ERD. Let me know! --- ## Salesforce B2C Commerce Cloud Customer ERD Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-customer-erd/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-customer-erd/index.md Content type: article Published: 2023-02-06T08:52:39Z Updated: 2023-02-26T18:09:36Z Summary: Are you wondering what entities make up a customer in SFCC and how they are connected? Then look no more! Here is a small ERD. Categories: ERD, Salesforce Commerce Cloud Tags: erd, sfcc, technical ## Key Takeaways - Provides a visual ERD for the SFCC customer, account, profile, and session domain - Explains how customer groups, sessions, CDP data, and related commerce entities fit into the customer model - Acts as a practical cheat sheet for developers who need a faster way to understand the customer object landscape Have you gone on [a wild goose chase searching for entity model diagrams of Salesforce B2C Commerce Cloud](https://architect.salesforce.com/diagrams#template-gallery) and come up with nothing? Fear not, as your luck has just changed. While finding diagrams for the entity model of [force.com](https://salesforce.stackexchange.com/questions/22720/standard-objects-in-salesforce) is as easy as pie, finding the same for [SFCC](/the-salesforce-b2c-commerce-cloud-environment/) is a different story. So I’ve taken it upon myself to create and share my own with the world! The first one on the list: the Account/Profile! ![Customer entity relationship diagram for Salesforce B2C Commerce Cloud](/salesforce-b2c-commerce-cloud-customer-erd/salesforce-b2c-commerce-cloud-diagram-customer-erd-0511da2fc0_hu_ec928dca4b40796b.webp) [View this diagram on draw.io!](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1#R7V1Zd6Jat%2F01Z4zvPpwa9M0jINggAiIqvNGD0kkn%2BusvJFrpLE%2BSiokxVJ1T6gZBYa2559yr8R%2BYiep%2BZqS%2BkNhO%2BA8E2PU%2FcO8fCAJBAGoe2pHd%2FQiKgfcDXhbYh50eBpRg7xwGgcNoGdhO%2FmTHIknCIkifDlpJHDtW8WTMyLJk%2B3Q3NwmfnjU1POfFgGIZ4cvRRWAX%2Fv0ogQIP4wMn8Pzi9xc%2BbImM486Hgdw37GT7aAhm%2F4GZLEmK%2B2dRzThhe%2FGO1%2BX%2Bfdwftv7%2BYJkTF695w%2BFG5MXu%2BN2q3K6HveY5%2BA9Mu0EYMkmYZM3rOImbXWgvM%2BygOfqz4bzIkrVzcvB4iYB2JDWsIPZmSdoM%2FAs%2FjNBJUSTRs8Gx4xbPhqaHy3o3liZBXNzdS5Ru%2Fmu%2BKgP8Qtt%2F%2F0Gb78I0Y%2BCJsfvX4Ikx4DjW%2FAfToWE6IW1Yay9Lyth%2B9uXuxhz7cKX8IgoPT7d%2BUDhK83HbK7ptPKAZe3lfDreqcrLCqR8NHe5T30kip8h2zS6HrTBxeMvu6AzHge2DDYIAchj0HxkgjBEH4z8Yvvf76A%2B20Tw5mMdpU4H%2FbCrQM1P5B4Lduz9n7MU30vYweeHEVhD%2Br5pLYy4ZeqwEGGGcqEA8s5E9gfjWZlT3JgpkEwNVy5DFeGPWKITCfba%2FVicmoGn%2BYKzy6BAi%2F4Fobj4P6O20znZlf8CEY3UqNq95xtiyzVYjqMCoeUzkaZaN0%2BZZJENuNgxFOsFdUBn74yrp7%2Bs5j2DMjMgHrJbWmihN8XhSjHor0W4MhJOWFVVk9cRj0o3I7walyvr6kIuCJKEZcLBxTW4hiqzW7GrXXuGI6952TJJrgdSGSiyFPBAH%2BYhLtL2sG66IED1dmrsEiy8BYMeuBHu2bj5Z7U2bD8iNmv9xSwFyiHXFKiZhXZt5psE1u3AcBAg2qG%2BHzk4v47gZGcfLIbySUVemmmv7fy%2F8srkxONL%2BfeGc0K06J%2FAe54Re7Zyf43vIn30Pful7wN2fP%2Fteu7vY3rFid4TlZ96o7ufQOEeHY9afT2bDZBzE%2FB5Aij2wTXdzCrRDFhTyTNgBXrELtnQeKpPlfDGJbWkXgONZ0FrumACHXvNkOGLXbCLzzSwOcb3%2BlKFVxS11jB6qwWytsuFU6MkLgVDHItVXdWwWac4anoyUPTpiSKXZcW0gkwWD%2BeAMNESEFvzmltEzohJ2an8hy0SY0NTaH4I2JbdX4G2Wf7PT0k1YPnr4PEZYHiz%2FHwgLmzPQdlA9cQlsU7asiXaTuPg3v%2BOMVLMDmNYP25pn3uHx7hjpySMYYeDFzbut5qo4zaWlIyPzgvjf8O6%2BU8DDSHb%2FbR8PFa0NUUBz1t9D5sGIDqPNhS3%2BDZqbFB%2FfWh3PGAW23X6Y5stlDXENknYwLLL7j%2FyHL9F%2B4f%2B8EiD0C787%2B92ga0RB2Dg%2FxTRnNrOgGbfuzYh6jB8vP0XoFM0l%2Bfdg9b%2B%2FUhjEzr%2FHe081fPcX8PhPYxxos1dyxBwK%2FPO3MY8DUpbYpVWMg7w4bmuMxXy%2BfzN2fwFeDKcnxu6M5jj6DFLb%2B9LejI4AX4AAt4ASNAqKurf03m9LP5h%2B79656KdH%2Bht8OmzF4V8A%2FIQ4Q8QvgHjBnEkU%2FXUErMcoBmK%2FUPDvcQz78wyOdHZ2VUILREjiicGgyEtzwXD4pa1g5AfMePifLQX9AJ2lSzTb6qyh4fobcSKPJkgRJ9Io7OvKaDffFQ3XpANuPCVFv4BcWIchsmYt2AhWFrM2PTDhm28Q8MuGFy5T1hcCjA2YyWpKkUM9mffXciNZ6BBv5UhRb1N4Np3NSMsncDcggQmbNeME4xCNPKKVmbjMK19LKpmcLyo%2FxBx8AEYqP6W37QXDxyVvm4wk%2B36ZYhgTiSM5yNfoNFl6ejjZxKwAJCvLddNIJpH1Su%2BVQvM20Ms9bIny25SXRxym7SktV9vjDepQT%2FWyPTOS0JGUwo62FS1MbbbVBIh5ykKvLIii9%2FYImES0vqwtszcoFgq%2FJKIEzwAcAvhmCuJmpCT3O331XpaJvYdlXs7liD%2B7HPY95VWi9R1fCYchytEjdcYuW7%2BQGWbv0WHfXaPRIJ3gipo3o8yKHYN1aiDgYrLvYfFGtYGezlBEjBr6GhFyr0YFmeGGLF3ilPfWhYWbnYxuwfDJTl39XHXV4JTzNcqqY7xXqKxeD01%2FVlb4L%2BIlVUYJ%2FBd8OWV1DAqemr3xztCuSlo9j2GdUlanFxPRY8T0r0wF%2FLOpEB%2BirSZ32kpwWm0lepuFk9lYj5%2FLERs5YZ5Z0tADpyKcmav2Q0P0rlUlOsQqERZlmoAY%2FmzY6qt8pzRbN9NSoQRRn%2Bw1KjMVbjfl5WRkUjw6htDFuNVZ0yjKI3incXBqcuiaH4yh3CeENoIkT8X5uvKzkbQFLd2vxvauLy1YSPASQcf3SOWS0oYi8S0vB0FSRkAoqnwjxricS43efDRRyf6itC2xblfbq16fsqK9IACLxaY9OiJsY8iB4tFkwBs93SOWVYy5DD7RU2CaTgRDNGf9ZZF7olDVNo2bzVwXQ0ayBPcGDMuQJoVtxIrMkME8G%2FkmDWOlSW5J2XfIuwgYpb2RanYa64lzAh%2B3lP8x3ncm2YD8njLraRSLVvakfCqKpZBzis7ETS0ObRY1gpKaDWWpDeGO90JIh2tWGmKUPBrsJkuZ7QTWTVk93GmsH6qxmDJvrlpz%2Fb9EZHXc9wpF1hvg6ZzKwj49fgWeSUEBge9nar9I8s6yyOem1eamMseHR%2BPtcls7jpwyxV%2FAc2s8HIbET%2Bz%2BL%2FB8%2F3srx5BLme8HSLff2a0HK8Rx7KV0I4GXBnhcvPwr60PPWN%2FzOP37lJtpJcJ9VGxdwJ6kNvNNjA3WO2aXKryHabUJErmhbIw0dCewORy4bSSLixuhQpcGt6gYw%2B1hE8iU0moF0SNiqO%2FMrFg6K4YNSsZBNii8XC2dGPdXUqUnePOV6JXtWlt4NuiLe1%2B0liU%2Fmlu99bzZooGToGhX57l5O20oCL0jV1W1tfkdFwrwMuP5LN5vVo2VrEY9tICSaSliad%2BYm7C8KMZjYxNoaW%2FhNAehgYUxbqNWYhQ1fNVnZRxYuVMjotAgVymjHqr0ijRnhZRw0ZjZ4vMtZqWWJACULzq4NiqHVZv32EYL1lVKzVCK9yh%2BrlO0I6dAX%2B95K2CMbtu5zBd7A8tc1BM%2FhRZzAp%2FwSlDCg%2FabvCM3q1N0T3wWeRe3vZhTnslpAE%2BkBH8HQRfpmC4eBN1coK096Q3H4rARdO0ayJ2kK1pJJ%2B9IXce4u6iZeJeYiN0lJjLOo7TEqE1LDLq0xBs0fbwTdZ2o%2B4qcxI5qXznV%2Fk%2Bl%2BNt9%2F1Mrvh7zjlsbb3ouFY%2Fi7zEsYuivE8tdH6UUz2TTgM%2BrFd5jvhc01svPY2%2BWXQT55I7CJ1JXQew4Hz2%2BncgH5IeA5Jl7%2BbYo%2Fgl2d3d3n41dFokA4jRUkM8h5M2ocNJU324exHtoDnpq8foYz%2F%2Bb2w%2BdCa2D70hGfaUNvCgNnI3tVpzflQaO2vzUIQ1GVU1VCD0LliO%2B1kQgd2EsiQRTMCJcT2wYz%2FfhfkUFru8b4KJidzRDOKS6VBFrQSguG4mhgavQcEQoUtBOw%2BK%2BrPpl88Qp%2FZJ0poq2ErBRtuPZWVQPwiWKT8KtIWgsllEeLzefwmlzWEf5vA5UKbGwtWfpuLSj4mFuG2tiLfXXnuQuazGhxBW%2F00UjIHhtY7NCtLRp2hGx0VGum%2Fx%2BrgJKP0ANcldqWUTGM9PZDQM1QqdwWoJaMlopoFBAhLKpZSK04UE56e%2FWU4fldnzl9IfWSrQYr9TFcVoARhtWbv6HbYDY88Fko%2BckHhb6Wua49RKDx1rB55tmD9oO3XgZaGE9W4CgNxZxTDRRC5MruocIdvV%2Ft6pC3rdoRl6Xex5nkytSIdhLFfJo6F6FQFenQrBfJHxChlBZYIRPRYhBGq5J%2FIUIaVsBvF11KEbo5G6SNfYJAXRj%2FRDAJFEjQ%2B4GmDAp7ebx3%2Fb51%2BqTjhT8JSn4QP3werQ6bIV%2BochT%2FfALeSkfULgRCiciTRD4CyU%2FANXOpImAbwtqXoN5feH89umc9Gg1LyNDKAKdEJwfoDbPtaUA35HT93cUlZO2dxSVN1OxcSqISziY2qgqVjgjChqFpEuO0oUiQiVkDYTl0ECt9ZIQxvoGGAZTYFbhad52pSADOJghXg3grtGfkouAJqYSussBBNoPYGDSxnRYbqQI4yQqk8QUDdaZO0uinlOAtk33wwEVZC7uuLnIA4RKuxqjGdxiRMfs0NnrqWP2OUsgRXQhDzidqpQVa%2Ff1DSGqGysSInPiOAsJD8RSNRp6Wo1HsxTdDPs5afTqUjOj5pstoyUyS41kyy%2BxGk7yYB14glKnXLJQKnFLDtdoFrOVRIq0MhOScKaFIWs5ON6YEw2316ahsPF6gezdZvLCMWlGjesBlesSvgDkZVznPb%2FZaQWA2pgS%2BAQqsV6p4zvM6g2UHtJ3eyvurnHOYVn9Vp347RX80PtI6qUc9LiK1ZHUvyOp5C%2BCuCaOOvOTqDEMCJj5Thk78T%2FtagHwD87cP2n%2BQp%2FANztC8G346BuA6U98tGGY%2BAk%2Biv%2BCTkhs7C7w8PeJT%2BcYRgsbju05ymHj74VrIyuottPcw5gT289G7vY6dLdD7%2Fd49OpFoPi3W3%2Bsff7xBj%2B6mW8xMqcOimXrSY2wAmEYIDACx0AUhTDisFW720pCMIBjv%2F89vrVXH7zw7sXu0QvJyYLm9rW2dj8WN7dyeTgWBGMoSRAkQCIQftz45xO1Wx%2FOdPdq9%2FjV83P9mRbnSZlZzlPF1dxXz3mmwlorOWvzmRMaRVA93um05R7eKrW48uAr%2Fz57R%2BK6eZv882DpjfUZu0d7HIDpuS%2F8%2Fkivm97PZWY9z%2Br%2FDsHK01HDl8HHK0zRAzH4aeOKT83RO9fiBHoetu5y9LocvWtnTO%2Frn4a%2B2ms%2FxSnPdJOBTiTOdjl6XY7erZj%2Bcd3yihYeuhy9229u0bHeL8mWewP6XFO2HHQmwwr6iGy5r7Ck76aTUPJEUt2l5iX4TFIV9Dx83umkTifdJll8VyrV5ZzyTGcY6ESmY6eTOp10K6Z%2FDMt0Oumn6SQmc9pLFBhh%2FjVaqWO4l9VEb84AvApNBJ%2F7qaGPCfh%2FtQ0dS9%2BuueMD%2BDv0fbAF8pQlXGxaOtNwBDqR2Pf3jKwTTp1wun72eATHa2GPZ%2BL%2F0Imufobb%2Fn39akYnkzpDvw5DP%2FZH7mTSj5NJh5Iqpif1jML4IqnUEd9PVk9vAKCrUk9nUj7g7jfNrktjocAXZuzBZzp1wNBL7tZFojpBddU%2B%2Bz6eib%2FaaT%2FFKc8kBMDPl0u7SFQnsW7H9JFjc%2BROYv1UiUVZbQnM16msjiBfqRZ7PVJdkxY7ds84OZk%2FTyv5Bqb2spXjN9BUn5rddyyjP3nHT%2FyYaKepOk111TD%2FLmKJvN5pP8UpzyQUwM%2FXVTtN1WmqGzL9K2y%2F0mmqT9VU%2Fcai0y%2BSUx3HvagsegPYXJUsOpM0An%2FH8rkXLeivUBa9SOf7XF10pjsE0nWH6HTRzyCH11Uij5xJFUC67hCdLrph0%2B%2B6Q%2FxUXcTWzZliI%2FzSLhEdzb2wMvqe7SCQM9kfyHctljvVWKRtC%2Fzyx7zuZy%2BQODFIQE%2BPcDcIIScG2xS6J%2Be6Gzj1w2HwvTmTV6zanv%2FsLggei%2Fo%2BY5Y8nvykOSKdautU24%2BgrtdVsH%2BcZ046ZderolNtN2z6UKfafqhqa9SaXVrFOMiLr1FsHf3%2BbvT7A9Xk92ykgZ7Je0HeVk94HeZ8Z3Cv6VP52PSe7P8dJB4MfGIRGHqmzwbyjh%2FQ6iReJ%2FG%2BH89Fr6vZAHomQQI50VWjk3idxLsV0%2B%2F6bHQSrxgWTvRFMq%2Fjxdelvd6AT1elvc7k1qDfsMrw5VLCd5BSKAh%2FopQ6008DhU5JKQdGoE5KdVLqpvjkdTUVQM9kVKBdP41OSt2u6WNdP40fLqW%2BRkJ19PbCiuh7NsPAzuStoN%2BwUPCLZqZPqhZDyKddND43KoVBZ2zlZBuNTkp1UuqKvfZdfBJ7vdt%2BilOeSSdAuzYanZS6YdPv2mj8cCklpu0HEBLbCb9IVXUU%2BSrV2BuQ6qrU2JkUE%2FQ7Fice2rYA2KVM5gNU1fPWhJ8sqs704MC6HhydqPpuOP8%2BZnldjQiwM3kCWNeDoxNVN2z6XQ%2BOHy6qjql%2BUplZvpF%2FUS%2BOju5eWCF9z14c2JnMEez7FQPez0rPSvbuB%2FFvpZk%2BtQMGfqYDBoZ0mqnTTD%2BCOF5XGwD8TCYB1nXA6DTTDZs%2B1GmmTjNNHa%2F5NzPiL8rw6%2Bjvp2uo79mBAj%2BTMoI9z%2BO6fiM601Cl7Yl5qtIOejZ%2BhQoLxOCnEos8ZScXm9HONKDATmQVdQqrU1i3RzPx66rCx89kB2AnusJ0CqtTWLdi%2Bl0Dip%2BqsCjbzpw8p5Nk%2FUW6qqPEV6W63gBNV6W6zuSU4M8Tvb6Did2Z0ikbu7OlExvu5rpnjSzvBx8aWX4HJfbJwa4zDSzwE7lInRTrpNgN8tHrquLHz6Qh4FAnxTopdrOmT3QNLH6qFDv%2BePFBkn2NHOu48jeQaN%2BzGQZxJoXlbpr6bmb3HdoDgiQMPrnzOP6J5VcEdOaWn8ha6tRVp65uj2ISr%2FfaT3HKMwkK%2BIlGM5266tTVrZh%2B19Pip6qrhRGGzhflDnbs9rKC6A0oc1WC6EzGCf484%2BS7mMy1J%2F6REPTkxqPHpn%2BPbjsE4Beaf860o8BP%2FMjNm%2FXQXBrbrR6SACPMcT%2BRzYXhJm5MGXN1lzjpMG7lC8DXwTww8WI7ab483RNjPRpDg0GO8pRcGxOYDEGbtEM4GAOeEi9d3rDJnKbw4VLPM04s8uYoHCmawKA%2FE1fkgq0IzUpBh9Nkly0qy6MDaQVVvL7GbJQBBXjEudQONUvX81N%2BHdb7mQexetxqG4YT%2FNEeWOzjLC0caB%2BN%2BuVcXVK8n6yg3RZYpqrBRdgOF%2FDEXXOcINIBBW9mStlMNYa%2F3fbnfd9pL32aCb1oS4lRf4bEwtjfLfXNtl%2FwEzkwVC3ZI6t1Wk1Kxk2hPsswThyWIBJKdoHraBVxVCzuOdRvDhTSouiXqmaudwq%2B4gmwH9aj5vbTe4Du1NDfUsJ3VeRfziXPJA4QJzrEfBM15LOP1VDtBYinT2NU1H1s5gDhWAJHU6Z30EKTBYMFXKOFKIQR%2FN5jLZS0WmjdaaEbNPyuFcVP1ULHSJNk7KLmUg3jxm3L9tkXyaOO615UHV2sFwUB%2FYLQy8mjM1kgxPMskO9gMt%2BxXd%2Bn1kUdj3vyjj%2Bvv%2BzCRV246DZ54nWV35NnwvbE84XN7yOQunBRZ%2Fr%2FafpQJ5F%2BqEQSM9vJBkGjk1qT%2BQpV1FHcC8ui79legjyTvUF811q6aw8agcgXiqIzzSKIk80iut%2BF6kTRrTFD8roq5skzoXuiaxbRiaIbNv2uWcSPFkVfpIY6antJMfQGjLkqMXQmeYP8iEq2bhJ6r2aCjyZ1zLM7%2FjT7I%2BNATqQ2HMf%2ByizONHUgT%2F3ADAzZ2Bl2dm8b5%2FmZr4%2BnvWS47bGL5uPpm4YzrQsmk%2BiKbV4HQyofBkKvIWPknh75DabTvAOVetvrglYir%2BSh2aiwhmPFnifNG4ixKZbcQJ4G42Fp7SA8n%2FIq09C%2B1BXxeQzZlt2eYR5FWQpn%2BmC7r3yZhmho0PK7fFWE5qJRSgJCTpaz4XDDsAAh7P2JVg1oQxaJgYwgfk%2BU%2BcqbbuGGrPUodEwDzNIwDU0SOG7RY2Y8RoN0mrNLz1swHDxeqtrSUJrzsu6WxodmQdQ5SWx7aiN%2FaH1DsoKOSZsRM%2FeXLiKSizofNh%2BmjAcsDVQjevuICXaOdUTed9WfX8xzzsTcyecLkq%2BJwL7Cc1J9POndLUAorl8WfTtcAqYI4tEwmIPDlMatlmpwREqr5ERDIkAjE2mk%2B95cA%2FPJOmKB2Vp3UVWaq0SV1DQ9h4HNarTJtVDb8VO%2FQIVlVhow4fArNwVZ2IXlQtpjqpUX02l%2FDBFrmJJ3loU6GD1rziWnQ5YZtYmxrDdVpW1f8zjU9fZaoMp6PXSjsG4vaKOcaFlYU0yw5tU%2BtS%2BnRa4O6ZVuFotxqhkiti9spLk6DdNZQBW6DyWU9jofuHYfAIEzaQjke9IQ3uME6%2BUGsjNYoNlsM130SLH52EXz2em5rKGJgUSQBmukMMnFJKqKSPV2e2ge7lW5NbcyxadrZbDJ53Yj0QkN1HabfeiDRalBRcWSkwW73%2FAl6jeGTDtrK5%2BKlMrnoA0wXl910XpGUxo59qgAEdVmF5kKZHdL5Ym9HZnslOllfrsqtqW1ETXnmwmFVZRwMJM1aFgByXTFb6tNsoRrFHJ8P1jp7t5uZkWa5GaFRE7zzgGu3AHOhPzJEyH%2FiziAvwSPs0D4aBbY%2BPVKButJvhNb49XNoT6duMsJT68jANpP5jNUbX3FEWZePe2ZzaWItVmCplNwus7GpJbLdeVozVtF2802enkP5X7fDAiPHpK%2Btc54QW5uEq1ajSkwmSYD6%2B1ksqIGw9YJ%2FGHrhRI1K6d5yQ%2FF7cKZaosRPR8y7FKSFhIpJu275wFlQBy87BVI3wZWieqMYXdS6KPEAdVqy3ZOcOVOAJ1xgvf0LniHE7Qrqa2cyJ1RNAwbWtGiewaSw2WZCAtAIGamgK%2BtKII4bb8E9n3L2DvuoDRSDFouN%2F0RYaCDZbXCp0N1i6Y%2BOAurcYHbNWo6ai3ACb5Bp80h9%2F50vvNl3h8STj1ZBSm1hoVIG%2FdW%2FdyTKHzI1lJj0hTA9%2FYaQYsjgaN3iUjRwW423KhM6TGOVSzVVvmAlIRspr3%2BTurnCuyjgE1vstrJ8MI0mYQA2wIbiupo0PU7wJlIM3miT8BHOQCT3ztAXeaKDcGUhbZierpjIiUChLrCSNdUnf56lK4njcWbaLjQ9KnQ7FOUDQ3KxKUP39GgGU3AyY7uTTYjFR4qaX9sTCKLw%2BzKLJspA5WWahLZyyU8Efu6qA0ofs5plTnqDUbt8mTMCf2MXi8pmtuWMkn1KtWlmOUwtnp9JWYdPM%2FHyNAJfDWh5TmzhMcyUOEDeQUmaqvvS3NacQWyYPK9Mm8DLRvS7GOw5fQztzP8azb8MxF38j0%2Fz%2FBm5C%2F7nhdY2RKQWLyvqCuuXUdpAy%2B0SiFgQ8F9ODXbsJzlrwXEg3bkasL4fcLpWxW24XBpN8Kmw1lizKdiW7ZI%2BVAwNnoTI81xEd60OF2VWiWKHFxILr6djWpPHXND1q15JVh43F0VZEgxq7ReUqMZg7I7ysT9DBlXjivQ3hqWnS3VaAd2s7YQhoE8ceehFg2l461aqzQErmhC3PuJBvIc2J7O3XtaSuoQZHbLQN%2FABc7Et8kT8e2Pd4Gqn1fj1VEC83Ijgcs%2FSOC1uI0THZoP5QXQWrs9nYHAZEuwK2SqmLIbktOtutV0D56V1b6hP%2BbIdbQ6b%2BkP5tzRn2jm%2BYnBT5NczUR9S4etA8StAzTUKUG4XknVXo%2BQXW%2FAKmCPDIa1qDimHKk6shzRmkx5s%2FVgfxTAM2NbRWsZ3uIQlPoq4swJ2A691ERXxFbrjP%2FKjf9MlT75nir9Nxt%2F3l%2BImXQw%2FvHd%2Bs%2Bd8fN3xi%2FXG3Nl2mE0JIUw4rSZoekTfUJEGYRjQ7vQCWm74xXAIwfOPq%2FYvK9rtoVnOezAiQbHuRyLAgfbkrnfriZbn0YRTqlGyzkvU%2FPlTlW3U0zEtjQ127v01uP6MDpPk6gNS6zalC9uOLYaWk9N5ZSl10kiFEN3PRwUSo%2FcyLKpZAreiN6FjbuFhlRzEipSLkjaRCjaAzrjv3LjPxNSBYETBfEfRvsTYdta%2F6iwQnxtZDpUufK%2Bt1D7%2BdpoO0U41TrsbRRfU6M2IWm%2F3I9zardy%2Byt%2BuRqvt9AKmNrofDIzhJVXT20NAIxM4VWLTTJ8MdUxMc6qcVXFUzHFcAxdaYQ0tFJNHCYoSzQnYJVoDSyLHbFmsnIVUUPJRNnF2CAGomcyzjZWPCVu2yly1L4%2FmA2nLONZosxVFLHJWsXgt94xzxZbecSzFF%2BuFo0A0AzYAFMbaZU7mWdTGK1Dqaa6QMA38IUzceR2kbTLL%2FiwO%2F%2F2nGwUepqU%2FZkJBiBwJk7arhy%2BQEnbxo07i%2Fm7FAP7LsVguHD11MqTVg%2FGSz9jyR3FyGt5S9Uzd7mhe3QiNTO5uytmQOpDnKyTbKYpvc00NCR0JA1mlrnder2dsC7WcCXPtyjtrzltV1rlZryYYBXG0wM%2BjckpEtmTWTwE7BijxvXIUuctkE14kofm%2FiSPJGDdBnaAVarRGT3DKG9khwxP6SOqD8jjNKyLmV%2BZY8vqZbgswW6qz7EVGWaeZZGmU7ACsjU41IegveNPFE%2FyeputhQ%2FSxVbi%2FFW6T0jcWMrEgDAXtDHVJaMERu4eDHkC4z1eQnpA7Wa4pCro1OwNOm15yreOOHYlsAqeia%2B2q44XohirkeoXdI9tP2CdO0m6mTsrLGrTcyhrPhswnCaklFw1Bk5HsY%2BtIaNm2kqF%2FjRNm4fMBOMpSDqDCHPJfW4tQ1Sq20ZYuIQ4OIhYtmsD%2FiBFHHLj9vh9S9ixvj5YNu%2FFpOYIHCQ135wbFJiDt9VHnFTwvdZ92rXKrHkctFUPW7fQ93SibY1ysCXxreIw7RGW7YoMNI89QuqpPOj19FnOmvkIZkjcnTlyvt%2FI060wa9d22rX6yNxGVOzHjjVndkgllMCUZrcK2QdqbggojhpmzKyH1mtNp8FcWwwlb4sxGMQKAzTE%2BsOtbC1aPuPlddgHjS3TQ%2FN8AOw0boyDHoeLQmX2AogYDVVNhOGZBpdsNZq2aRPL3pTEAmfsALDKQnkv3SyoUBvoswlKjNGBxqwrWF21UbctyOTeiK4ZltadQjAhc5UNDX%2BsWdWOiQZmAhApureVsD9VNuEAzxx3Ym8SbuFac7i348GN4cig2g%2BdKWnqAIXMVAgdelBvvrJypM9WMuvdX996gYXCUhSLEVvMPMwf9vSRzjHY0LXB3XaXVlwbXxT7Ag2VyljrNV9TmhX%2BZuboAyNayOhI2aEDStjE5lKdMmUtLGCfxuNcXTXA6ZvGEu33QSAvwXxmh3kwnxLxgrOocM3tNDYfy6uFOYn7sj8C98A8XOU64xtMZMaslGIoZVFTszaAQhmFHsWI%2FHgpBi3nnfj4gusjE4rKA2g9GHnZWCkp2wH7w4obFru9Ol7kQLs%2BDtYz3neyPsyb2VzeEmzGDrwNM9YHwli1uWHOSuVOqOWNtNlFy0pb6gGTE1aKUpzRnKiPQZ5vZtpeJSLeUpDhwECMvGAAbb6OgwJbtb8PR8OEjtaRn5LTGc8ZRV9o11umKbxBdmi9yMpYXhXcdJz5SOFsF1ApAvNMIAoH6ze%2BnqDceNB3LKQ%2FC5F6ZidRjNpjR58bOxURx2apxHN92dugPD%2Bg5dHCWk3H0iLinXQRt9eiFlm4MRraHQtoNtN2Q3Naz5WKYuLc3E%2FHgFtM7Z032oA7fxlHSD53a1EC0cFW366d2TbhEXO19jMCTRJzYrHeklog3r4wLMvNajVrfLfsKcPIlhIHDWAIkGRkjYHqJsoW3AyWA6ySDUPcl%2FKmmPL5ellMjL1t7%2FqLGQ9aMih46ymPbWcTtoZKbSzuSLSQsRCjlCGwl6DZYLBPsmoHWnt%2BzcZgLwmNIJTXWd0DJqhUYBLpOVVf5uIKhVeAEgzqdDWKh21qXToJVL6Iec2SPVWpURzYUFLZbMhzZ7XkFyhNU6Ja8gouBi1glUhuVYPGJyWJnFZKq50GNeHuUyyG7sPdI5NrF9LsCpKm%2BxnRTZnXPmWeycho4xWdEvk6JfI807kRB8jnKRHwTJpCu4z%2FgkzBJIYi%2BF8rkVPJzjVg9NolkLovT2V5JwuuK%2B52U1Mbl5sFWNoAWfKBXwbYbESzY3PjbhbSYmlwGi9SIbeYGvpa36X0CODq5abKN2V7YCULq3XIovPKxQQX8xyFYPsDS6ZLDIZHqO7c5UEHwMSVZCjgJ6t6KgoE5ZQcsB1hEuTven3WaytJqcgTBIbu89t8ClBLw9S1ashyBBeMQpuC63XOxp7fZ3oG1LZFBVvaNQcJW2uhUnb2XLYabyqYaPnEdjK7q2IdT%2BvZnnDmO3y8bu%2Fa3lozMaHt5ZUUyc2MQXXQ%2Bty%2FwNd72Kc40Jk0hzYUcBk1Ml%2BZVpHfNeqt9vyWAXwM52cjF5KNVimwwGomigDePodBNdS4dVls2oivmsqkJenbBW0WhIivUJcjq61EWjPEdpvtbWryAMXF8b4iSk9AqjGczxBrLznw1k1seE%2B4bY5zVbWSRoqhQtq3UmTlD%2FbrdhF0hbdXjFWQsbnqtfEGf92Srrb%2BeVdHVejDZDXwTaoNRvcnlFEvEnLNbNn1ZE31LRUSBgjjcBBlty603xaK7oEMBnh6n11PQ8JDN5nd99Saz2twO%2FXmKUi6olFSe%2BOeqHOj7aAf2BKbNrdVqHReZfXMHTnqWN%2FkqzCcinM6R4n2O3D9ybhs9hwrjAuwA2A%2F1Bm1INRxlCK0uMqH%2B41Kt5kYlpokESvyzqhauIN1b02O7KjusdoIWa2orC%2BxjgEinqXNaWg3mLBqT5cEeQGqnlLFApCiaKAImYdY2EzYUdMWFlaRBvWJVmyxdjhx7z%2B70jf7DHFXLTswCCSNo4LlqpkbL9JE3ZVK%2B1lARRoMrZGxZEcCOyanNsKmFTvnzFAkWmY2aDi8XoorbrlrLmm%2FDwzzacJas11mKF5%2F0abdQtrO0%2FDFYhUvDKQeiYkMynQKRHLfXg4NBFlMtRCSRoEVzRZ1tWGtgoAnqh8z0FoZRbWJg4bJUHOerRmNo405AYzd3mjDCaU8Td0SwCCfZrmGKicgwfSxjLSyKhzE4kzqD9l0M6u09aBRA5zAbrPAlGoL5ucytlx5E5uNy3EhQDpV9FHToaK9FmMoj3qynTJIsAJ8a5tuBEiAmYnEzFAoYlBIUiOLjtScnZYskjEQo8S8bEblQCYUKld914bYcGnWkRfGuKZYjCWYLSLnraXy6zxkoT4nL%2FqbTbBs5HC4x0JR55VqHPZ2PWivrDOmzBfMStnrS1BXSHvSL2oY2nGl5tt8BS7jdLh3GAwHmEK0bUkoNouSCqllNTX5CSS3DFzLFA%2Fz1lt3j4B43iguP0ar1sBTbih6uB%2F7Pb4Kdb1Nvh7vchofTdp7vfG4Sb3XvemcIEsstMkV5K%2FmEa20VT8JvqulEIu2mwUB6aoHzZaL7b4AGDHUIDFI1WAe1HDrFrBBG1nKMqv91uYHA2fZrlm4G8xxyb2DzWqzQJzBZOywypSu2LFTeGEUW3Ob1PUJMolJYmW6KSr6Oqw6hTXYDCY61EATRFd7f94DawXd2rTVLnEYbZBuxkOmVa6KjS8TmldJ0Urlx0xiTmeJuISXzgojqgBza4OfYGoLDjQ2We72FlBJxLib7K56sjuT2tSG%2Froa2wsIBAIFnggEBHj5kwMXK9cHwTOpPK3MfcFvUMRC0HP3vWsg0zWQ%2BYZIjLwHiS%2Fol2eyjNr4YtdDpushc8PWf8z06LrI%2FLQuMoqT5%2B2pv6SPTEdyL9tI5i1Ac02dZECw%2BzmUDwIk8BdEnkAkKguM8Cke3f%2F5CzxqK%2FX%2FE4CStmvVJPl4bHkAFai9to7tOcph68EJbSP3f%2Ftg%2B0Iy2q%2FVehT0q%2F3wwN1DiyhGVlBZlmwf3uzE9nGEnUZGbIsH8Gl2Ve6udQ%2B93%2B3wijxFj35f44%2BFqD8ixiN0%2BANAPV5Cf4pSL9DGqYNieYDY9nlbOtGgIYARCAmDh0fosLFXP9qzt3v0QnKyoEGE9pD3Y3GDDsv7Yx1ftoduILZhNyQOYYdH%2FLj14dh3r3aPXz0%2F%2Bh9XDPKkzKyD7WAHVd7cTM85Zr8eiFVrSGeBM3NCowgq58nRT6Hf4a1SO5884Ou%2F4HPETFw3b8XuA142lmfsHu1xmJJeHvMA4lBDDZBncVD4MPAAwfdHfQDk39%2FplRhNdhh9UYy%2BDGt8FUqnjW%2F4Ru7kv%2Flidpeqcr%2F1f4bnZY5nFI79f5cEcpB8M5CDByTHXonkeydLZolgxLufCua%2FgAa7cYJEcLgB8LbYEHmE7%2BDfwDn5%2BKgQBj9G97Yt%2FeN5A%2FyN%2FR%2BO7gj5Et2PiH95dH8%2Ftj9hy28EZwjowPlWwdkL3IJpQcJtYKJwhoUTXRSFidMo%2FEps%2FcE8%2BRf%2BgH13GPsYWH8BIIyRBAYfHo%2Bo%2By6kPXWi30j7qcCKXpo2fxxLJo%2FNs48UGUKRX4cQMff%2B9%2Fw9s%2F4d1OzA%2B%2BbA20qmjhc0gGc8%2BYHXj0dt%2FBWo%2FRSjH4H3450f4fQDaqM3i9oNMD%2FgaEtfH6N2g7QojEAIhh4esb9A7ad0%2BNSBL7PYcQK1j0h%2BVaj9V%2FwX6iD0ViE0%2BxwAxTra%2By4A%2FRd4jqAEclwVvoc6CIYIHMPB4%2BP7MfQ0WD%2BA6qkzfd4aw6VBtf7iNQa4w9hbxdjcD9K0OQhl25mT5xcFWrQD2vcyVfAJ%2BuFPUJaAQBLECeDw%2BH6Q%2FSOgP%2BDsiXN9Gszi%2BI3DLNLB7K3CbJrkBVs1V0H5RLxFOry9xMrAByZCPAXXUwfu0PWj0BXt0PVW0dUqs%2ByTsRXusPUSXPYRt7x7vCiZPXWyDm8%2FCm%2B7H6y9WbxNM8d1Gsi1PwNpoc9HWoiArG%2BPtMAv%2FM9rs6dzbt%2BdlXAGZlscfpoA8Ts97MNx9lgj9ak4%2B5De%2B0VA29V03SzQGvf4SidtH8ALYiz4Coztcgg%2Br0LiNEt%2BYK4YAhMwioGHx3etFNzdLy5ogeXvEPZYe3ZpJos87TxNQO%2FH29MnABEMf15OQRLE40O%2B6j0EBP9CPjpV7FxTdPAPhVA%2Fqb7pZAHmAxdC%2F7yi97Fc6NSJvoIL%2FS4J%2FVRX%2FXTy09Um3XL96CWVJfGHoqOulOjLWM9TkvNp4RDixPLcxatCPxsp4a5Q6GZl4h1WDoK8SFpTuxxiviaB5zGp7ETin%2Bsjf%2BMngCI4iaDQ8fFvyCfwbCHuGaI%2BJp7t46ci6mfJxH%2BPzR8PauxZA8dPw9uutudm8TY1dlFzDYZxA1hl%2B%2ByiPPU1i3MdTz0JvOgjpP2D%2BH6%2FzocQEEVQgoRxkCSeIO0ndjQhwJdIS9x4zTvc1fzcLLRujTB0Llnvg7%2BmXvLG10rfk7fzhLN%2B%2FxRI6EQnqCOWXpyhEl%2BEm10dz83i5iFS7FySieKvSXp8xju7JYB7ugg9a9xxQWZ68lRfQE2PmTdPsnE%2Br9neF2FsV8Rz6xh74Wwc7L1xqZ9NUJ%2BK%2FQ%2BO6T9G0M8M4p9iqZ8HoV%2BEoF2hzs0i6It2o5fAz9ckjHcs9Qdo%2FFPdnq%2Bybd1fwWVXZ3O7cJkldmkVYtqeQEhsJ7wgbqLEO3lnV9J44%2BXi6Imkb%2Byz1kq%2FioV2VTW3DquXxFLknVj64zX8T0vTP4Wt6KeVLGJfBK7drz7dOri2zeovqfLR95Y8dVlRvyD4aYTo2DLugLIf2K7%2B5Jm6fvUfA6Jd6dPNgmhjtdI9jo6DvMj%2FV%2BxS55K%2FwIT8XQ%2FkH42mP46yniosvbm%2B8khXLnWz6NpcBieLjbCBWDcILxqMQrpg1LuBFYDAZw3cHkHr6WKmC%2F2AHQICJEqQx8fL8dYTAavPK5v6mrUApKuTulmgtcq8uSxO1m98Pr0kzMKviV11MPuH4tQn2aJHvX8A2Qfu2j7%2B1WLAfxSnPqPKlytOPSLOV6LsF%2BdYIV0F1c2CrmG19tkzCuOSgIu8CnC7VgC3nWEFn0jx%2Fzwohb8IPLsU%2FxvtOZXeLwhcEDeh16wHdElWPzDJ6tSqKnTpQv6v1v5dqv%2FN0lArc9pr0CD5JYU%2F9JrAVcdDf0ax1Imo%2F8UR9NMhs0v3v1nIZHrSpWX732VN%2FVz6%2BR89%2FB5Hh5rHv4FP4MkSaXOqZ63fPy0YdYqQwpdOovrKZdLmZZa0Dvmwe2ak%2Fn3dDcz%2BPw%3D%3D) ## Some additional explanation ### Session I’ve highlighted the [session](https://documentation.b2c.commercecloud.salesforce.com/DOC1/index.jsp?topic=%2Fcom.demandware.dochelp%2FDWAPI%2Fscriptapi%2Fhtml%2Fapi%2Fclass_dw_system_Session.html) as the “starting point” of the diagram with green, but keep in mind that a session depends on a customer, not vice versa. For instance, you can [retrieve profiles](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_customer_CustomerMgr.html) outside a storefront session, e.g. in a standalone job. ### Customer Groups For those familiar with [Customer Groups](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_customer_CustomerGroup.html), you’ll know that the system already has pre-defined groups (Everyone, Registered, Unregistered). But why is the relationship marked as “0..n”? It’s because, technically, that list could be empty if the default groups aren’t present. ### Order, Product, and ProductOptionModel I marked complex entities in yellow to keep the diagram easy to understand, indicating they have multiple links to other entities not depicted in the chart. [_The diagrams for those sections will follow in the coming weeks._](/category/erd/) ### CDP The CustomerCDPData object only applies to your project if you have purchased [CDP](https://www.salesforce.com/products/marketing-cloud/customer-data-platform/) (Customer Data Platform). If you haven’t, it will contain empty properties. ## More to follow Stay tuned! The next ERD on deck is catalog/product, [so keep an eye out](/category/erd/) for this blog. ### Mistakes Don’t you love being human? We get to make mistakes and call it part of the experience. If you spot something that needs fixing, please don’t be shy. Let me know! --- ## What Composable Storefront Means for SFCC Developers Canonical URL: https://rhino-inquisitor.com/what-does-the-composable-storefront-mean-for-sfcc-developers/ Markdown URL: https://rhino-inquisitor.com/what-does-the-composable-storefront-mean-for-sfcc-developers/index.md Content type: article Published: 2023-01-30T07:59:37Z Updated: 2023-01-30T18:11:48Z Summary: Many SFCC developers look at the Composable Storefront as the next step of Salesforce moving SFCC to the CRM core. But is it so? Categories: Salesforce Commerce Cloud, Technical Tags: ohana, sfcc, technical ## Key Takeaways - Frames the composable storefront as a major architectural evolution for SFCC developers rather than an immediate replacement of existing monolithic projects - Explains why React and headless patterns broaden the technology stack while leaving plenty of value in existing backend Commerce Cloud knowledge - Encourages developers to adapt early, especially through phased or hybrid migration paths that preserve existing project stability Over the past year, I have seen increasing gossip (which I am partly to blame for) and discussions about what the Composable Storefront release means for development in Salesforce B2C Commerce Cloud. A comparison can be made to what has happened to [pipelines](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/LegacyDevDoc/WorkingwithPipelines.html) and [SiteGenesis](https://production-sitegenesis-dw.demandware.net/on/demandware.store/Sites-SiteGenesis-Site), and we found out [in September last year that many things are afoot](/what-is-commerce-on-core/)! ## Technology changes ![Graphic illustrating the long-term acceleration of computing progress.](/what-does-the-composable-storefront-mean-for-sfcc-developers/e094f768-3336-403f-8c75-9013cb07df2f-b7c7a5e8f2_hu_7563b35fbf7e8129.webp) Let us get one thing out of the way first. This article is my opinion and my opinion alone. As commerce and web developers, we are constantly reminded that technology never stands still. The world is rapidly evolving, and it’s up to us to adapt and evolve with it. The rise of “Headless, API First, Composable Commerce, MACH Alliance, etc.” has brought new opportunities to the eCommerce world. Salesforce has introduced a solution to meet this demand: the [Composable Storefront](/sitegenesis-vs-sfra-vs-pwa/). This is an entirely different type of implementation built on React, a more modern library than we are used to in SiteGenesis and SFRA. It’s an exciting new development that will support businesses’ requirements now and ones they will have in the future. I understand that there may be some concerns in the community about SFRA being phased out in favour of the “Core” with this move to Headless. However, [I don’t see that happening within the next five years](/what-is-commerce-on-core/). But we need to adapt. Is it really so bad that the platform is evolving to a more modern “composable” architecture? We don’t want to be left behind, and we don’t want the words of our competitors to come true - that Salesforce B2C Commerce Cloud is a dinosaur. We are so much more than that, and it’s up to us to prove it. Let’s embrace this change, take on the challenge, and make sure that Salesforce B2C Commerce Cloud is at the forefront of eCommerce technology. We are the ones shaping the future of commerce. Let’s make it a bright one. That felt like an inspirational speech, didn’t it? ## Advantages of a monolith ![Illustration representing the strengths of a monolithic commerce architecture.](/what-does-the-composable-storefront-mean-for-sfcc-developers/salesforce-commerce-cloud-monolith-e3f50eb05b_hu_f16938a64d161144.webp) I’ll make sure to make one thing clear. Monolithic architecture has its advantages! First and foremost, it’s easier to develop, test and deploy. All the codebase is in one place, meaning there’s less need for inter-service communication and less complexity. This makes it easier for developers (and businesses) to understand the flow of the application and more straightforward to debug and fix issues. With a monolithic approach, you can quickly scale up the entire application by adding more resources rather than scaling each microservice individually. A monolithic architecture may not be as trendy as microservices, but it has its perks! And sometimes, simplicity is the key to success. ## The Composable Storefront uses “boring” technology React.JS is something you can refer to as “boring” technology. This is because it has been around for several years and has proven to be a reliable and stable option as a platform for developers. Unlike newer and more experimental technologies, React.JS has a [large and active community of developers](https://reactjs.org/community/support.html) who have created a wide range of tools and resources for working with the library. Newer, more experimental libraries can be dangerous as they are often untested and unproven, leading to possible bugs and compatibility issues. They may also have a smaller community of developers, which can result in a lack of support and resources. If you attended the training or participated in the Slack conversations with the team, you will have noticed the emphasis on stability, broad developer base, and community support as critical factors in selecting the technologies used. ### More competition and less niche Unsurprisingly, experienced Salesforce B2C Commerce Cloud developers are in high demand. But with the addition of the PWA Kit, a new source of developers with Node.js and React experience opens up - removing a bit of the “niche” flavour. This is good news for customers, but that also means we have more competition as developers. But not to worry, this “new source” still needs to catch up on how eCommerce and Salesforce works. But honestly, as it stands, there is room for both of us in the Commerce Crew! ### Other platforms Other platforms, such as Shopify ([Hydrogen](https://hydrogen.shopify.dev/) and Oxygen) and SAP ([Composable Storefront](https://help.sap.com/docs/SAP_COMMERCE_COMPOSABLE_STOREFRONT/6c7b98dbe68f4a508cac17a207182f4c/c9dcbd1ca0ec4219ac3c51b29c44625e.html?version=5) 🙄), have adopted headless solutions, meaning that we as developers need to recognise the fierce competition in this space. As more platforms enter the market offering similar solutions, Salesforce must continue differentiating itself and stay ahead in innovation and customer satisfaction. This competition serves as a reminder that complacency is not an option and drives the need for continued investment and improvements in the Commerce Cloud platform. ## Willingness to learn and evolve ![A women holding a laptop displaying the text “never stop learning”.](/what-does-the-composable-storefront-mean-for-sfcc-developers/never-stop-learning-g3bc2c211b-1920-3142164f98_hu_1f31e28f675af22c.webp) As developers and architects working in eCommerce, we must stay ahead of the constantly evolving technology landscape. This is especially true when working in a SaaS environment, where platforms continually update and change to meet the market’s demands (and these updates are out of our control). Luckily, we can provide input to make some corrections here and there. But Salesforce is the captain of this boat! And that captain is giving developers and architects some really nice new options. And now is the time to start learning how these new options work. Customers will be looking into them to migrate to now or in the next few years. Salesforce has provided us with a lot of options to learn how to work with React and the PWA Kit, offering courses on the [Partner Learning Camp](http://partnerlearningcamp.salesforce.com) and allowing us to ask questions to the team on the [Unofficial Slack](https://github.com/sfcc-unofficial/docs). Not all platforms (and the teams building them) provide this service. However, it’s important to note that while the platform is evolving, it doesn’t mean that SFRA projects will disappear in the near future. There will still be a need for developers and architects who can maintain and support them. There will still be a fair share of projects starting today on SFRA! ## What about back-end development That knowledge is transferrable! The Rhino Engine and ISML are still crucial for creating custom Business Manager modules and API hooks, and we will need a lot of this type of development in the coming years. And who knows, we might even be able to build custom SCAPI endpoints using the same system as controllers soon! This knowledge is critical to the success of projects, as customisations to SCAPI, OCAPI, and Business Manager will be in high demand. To make things easier, do we need a BFRA (Back-End Reference Architecture) to assist us along the way? _I need to stop coming up with new ideas…but hey, who needs sleep?_ ### Hybrid deployments A potential path for existing Salesforce B2C Commerce Cloud customers is [the “hybrid” or “phased rollouts” solution](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/phased-headless-rollouts.html?q=phased). With this approach, you gradually migrate away from SiteGenesis or SFRA one page type at a time. For example, you can start with content pages, move on to lister and product detail pages, and finish with the checkout. This has several benefits: - No big-bang release - Risk is spread over time - More current-budget-friendly - One big development team, separate development teams, or something in between -> flexibility! Additionally, this also provides an opportunity for experienced SFCC developers: - The perfect chance to transition into the Composable Storefront, one page-type at a time - Keeps the know-how of both setups fresh ## Career Aspirations As developers and architects, it is crucial that we not only stay up-to-date with the latest technologies but also constantly question our own aspirations and career goals. As the landscape evolves, it is essential to consider whether remaining in a specific environment aligns with our long-term plans. The question we must ask ourselves is not just whether we are capable of adapting to the changing landscape, but whether we are willing to do so. Are we content with simply maintaining the status quo, or do we strive to be at the forefront of innovation and progress? The future is uncertain, and it’s hard to predict when certain technologies or skills will become obsolete. But as true professionals, we should be ready to embrace change and uncertainty, and always look for new opportunities and challenges to learn and grow. So, let’s ask ourselves, are we content with being a mere spectator of the eCommerce landscape or do we want to be a driving force shaping its future? ### _The choice is ours._ --- ## How to get Salesforce certification vouchers Canonical URL: https://rhino-inquisitor.com/how-to-get-salesforce-certification-vouchers/ Markdown URL: https://rhino-inquisitor.com/how-to-get-salesforce-certification-vouchers/index.md Content type: article Published: 2023-01-23T10:55:12Z Updated: 2023-01-24T15:14:57Z Summary: Getting certified with Salesforce is one of the people's many goals within the ecosystem. But they come at a price! Where can I score a deal? Categories: Certification Tags: certification, sfcc ## Key Takeaways - Lists practical ways to reduce certification costs through partners, events, quests, and webinars - Explains the difference between certifications and partner-only accreditations when looking for vouchers - Helps readers target the channels most likely to offer discounts or free exam attempts Earning a certification in Salesforce B2C Commerce Cloud [can be a valuable goal](/is-salesforce-certification-worth-it/) for those in the industry. However, it’s worth noting that certifications do come with a cost. If you’re interested in exploring options for discounts or free certifications, this article will provide an overview of what’s available. ## Certifications vs Accreditations [![Comparison graphic for accreditations versus certifications.](/how-to-get-salesforce-certification-vouchers/accreditations-vs-certifications-7c6224e505_hu_4c9ce79b6a01bc3b.webp)](accreditations-vs-certifications-7c6224e505.png) Accreditations and certifications open different doors, so the distinction matters before you chase vouchers. Before we start, we need to [distinguish between the types of certifications](https://partners-salesforce.relayto.com/e/partner-guide-to-credentials-vfgkh7myki6y2/fUtftxtv3). In 2021 a new type of “accreditation” made its way to partners and Salesforce employees: “[Accredited Professional](https://www.salesforceben.com/credentials-exclusively-for-salesforce-partners-show-off-your-expertise/).” These certification types have a different flow and require different vouchers and discount codes. Most of the items discussed below are only for regular certifications, not accreditations. We will be sure to mention this for each option if it applies or not. ## Partner Vouchers [![Partner benefits graphic used in the voucher overview.](/how-to-get-salesforce-certification-vouchers/partner-benefits-0de8d66c3b_hu_6e545d3873eb0024.webp)](partner-benefits-0de8d66c3b.png) Partner benefits are the main reason some Salesforce exam discounts are easier to unlock. Depending on what “level” you are as a partner with Salesforce, you get vouchers that cover the total cost of the certification exam. So if you are working for a partner company, ask if some are available for your certification! From what I gathered, getting vouchers for the Accredited Professional exams is also possible (at the very least with a discount). - Certifications - Accreditations ## Community Events Participating in community events can potentially be a great way to earn certification vouchers. These events often offer prizes, including vouchers or discounts for certifications. Since these events are for everyone, chances are low to non-existing that the vouchers are for Accredited Professional certifications. - Certifications - Accreditations ## Trailhead Certification Events Keep an eye out in the [Trailhead Community groups](https://trailhead.salesforce.com/trailblazer-community/groups?tab=featured) for one-time events that offer discounts and vouchers. _An example:_ [https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000H3HLp](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000H3HLp) - Certifications - Accreditations ## Partner Community Certification Events In the [Partner Community](https://partners.salesforce.com/_ui/core/chatter/ui/ChatterPage) there are also some groups to keep an eye out for! ### Some examples - [400 free certification vouchers](https://partners.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F93A000000HZ5o&fId=0D54V000068aOr9&s1oid=00D300000000iTz&OpenCommentForEdit=1&s1nid=0DB3000000007Uh&emkind=chatterPostNotification&s1uid=0053A00000EITbU&emtm=1653576584272&fromEmail=1&s1ext=0) - [Free Slack vouchers](https://partners.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F94V0000002Bv7&fId=0D54V00005vVcoA&s1oid=00D300000000iTz&OpenCommentForEdit=1&s1nid=0DB3000000007Uh&emkind=chatterPostNotification&s1uid=0053A00000EITbU&emtm=1645544651873&fromEmail=1&s1ext=0) - Certifications - Accreditations ## Certification Days Every year there is something called “[Certification Days](https://www.salesforceben.com/salesforce-certification-days-free-preparation-webinars-with-trailhead/),” a series of webinars organised by [Salesforce](https://trailhead.salesforce.com/en/credentials/cert-days/) to inform you about the different types of certification and some helpful tips to get you started. After participating, you can get a 40$ discount, which doesn’t cover the entire thing. But every discount helps, right? - Certifications - Accreditations ## Trailhead Quests [Trailhead Quests](https://trailhead.salesforce.com/quests) is an official Salesforce Trailhead event, offering unique (or sometimes repeating) rewards for completing a Trailmix. The rewards range from SWAG to Certification Vouchers, and there are new quests every month. So keep an eye out! - Certifications - Accreditations ## Salesforce Webinars Attending webinars can be a great way to learn about the latest updates and developments of Salesforce B2C Commerce Cloud. One thing to keep an eye out for is a slide presented near the end of the webinars. Especially when a new accreditation or certificate is being introduced, this slide may offer valuable discounts or even a form to enter for a chance to win a free attempt at the exam. - Certifications - Accreditations ## Bringing it all together [![Looking to save some money while getting certified in Salesforce? No problem! Here's a helpful overview of where you can find discounts and even free exam attempts to make your certification journey a little more budget-friendly. Partner Vouchers Community Events Trailhead Certification Events Partner Community Events Certification Days Trailhead Quests Salesforce Webinars](/how-to-get-salesforce-certification-vouchers/salesforce-credentials-vouchers-personv2-bf4ee67f38_hu_3aabfe38099e47cc.webp)](salesforce-credentials-vouchers-personv2-bf4ee67f38.jpeg) Discounts and free exam attempts usually come from partner perks, events, quests, and Salesforce programs. ## Any more Know about other methods to get our hands on these tasty vouchers? Please let me know via [X](https://x.com/theunenth) or [LinkedIn](https://www.linkedin.com/in/thomas-theunen-10905680/)! --- ## Salesforce B2C Commerce Cloud 23.2 Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-23-2/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-23-2/index.md Content type: article Published: 2023-01-18T19:00:06Z Updated: 2023-01-20T15:36:31Z Summary: Review the Salesforce B2C Commerce Cloud 23.2 release, including Page Designer and SCAPI changes developers should notice. Categories: Release Notes, Salesforce Commerce Cloud Tags: Business Manager, pagedesigner, scapi, sfcc, technical ## Key Takeaways - Highlights the major 23.2 improvements to Page Designer usability, locale controls, and guest basket behavior - Explains why the new Shopper Experience API is a significant shift for headless access to Page Designer content - Calls out the broader release impact across SCAPI, SLAS, tax handling, reporting, and PWA Kit updates February is almost here, and so is the [February 2023](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_23_2_release.htm&type=5) (23.2) release! If you are an avid user of Page Designer, this is the update you have been waiting for - and Salesforce, keep ’em comin'! Are you interested in last month’s release notes? [Read the 23.1 release notes](/salesforce-b2c-commerce-cloud-23-1/)! ## Page Designer Improvements ### Improved Page Designer Structure and Usability ![Old Page Designer structure before the 23.2 redesign.](/salesforce-b2c-commerce-cloud-23-2/page-designer-structure-oldv2-56ca8ab276_hu_869b4203c083d1b7.webp) Old Page Designer Structure ![New Page Designer Structure](/salesforce-b2c-commerce-cloud-23-2/page-designer-structure-new-q0uu07mbk2b779dng608ohzvqnewndt9ajezjc0u0w-f987195ba3_hu_100997d8cb4a01e.webp) > The Page Designer page structure in the canvas editor has been redesigned. The asset hierarchy outlines all the assets on your page. The visual connection between what is selected in the canvas and its location in the page structure is also improved. The redesign of the Salesforce Page Designer will be a good improvement. The new asset hierarchy and visual connection between what is selected in the canvas and its location in the page structure will make it much easier to navigate and edit pages. Overall, this will be a great step forward in enhancing the user experience. ### Move Components in Page Designer More Easily [Old drag-and-drop component movement in Page Designer.](/salesforce-b2c-commerce-cloud-23-2/page-designer-move-e9d6ec4100.mp4) Old Moving Component ![New Moving Component](/salesforce-b2c-commerce-cloud-23-2/page-designer-move-new-q0uu0xxsvfb2aqadmf5zcgd32825ysuaruhlziuh34-537198b2f6_hu_4ceebe9433bedbee.webp) > Dragging components in Page Designer is now more intuitive. Know exactly where you can place a component. And after you drop a component and refresh the page, the component remains in focus and highlighted until another selection is made in the canvas. **How:** Improvements to the drag functionality improve the Page Designer workflow. > > - Minimal changes in page structure during the drag function. When you initiate the drag process, you don’t lose the orientation to your starting location and desired drop location. > - Clearly identifiable drop zones identify where you can drop a component. After you drop a component and refresh the page, the component remains in focus and highlighted. > - After you drop a component and refresh the page, the component remains in focus and highlighted. This update will make Page Designer more user-friendly. The ability to place components with minimal changes to the page structure, clear drop zones, and the component remaining in focus after refreshing the page are all features that will enhance the user’s experience with the designer. UX seems to be “the” recurring theme in this release, which I believe is a welcome focus. ### Save and Return to the Same Canvas Location in Page Designer > When you save a canvas action in Page Designer, you’re now returned to the same canvas location after the page reloads. Previously, you were returned to the top of the canvas. This feature will likely be met with great relief, particularly for those who have experienced frustration while building large pages with many components. ## Platform ### Guest Basket Lifetime Limit Is Increased > The lifetime limit for a guest customer basket is now the lesser of 30 days, and the registered customer basket lifetime. Previously, it was the lesser of 7 days and the registered customer basket lifetime. This limit applies to input validation in the BM Basket Preferences UI and Basket Preferences Import. It also affects resolving the guest basket lifetime if it isn’t set, for example, for the baskets cleanup job. This update increases the lifetime limit from 7 days to 30 days, meaning that guest customers can now have access to their baskets for much longer. This is a huge advantage as it allows anonymous shoppers more time to review their items, make changes, and complete their purchases. Overall, this update brings many benefits and will significantly enhance the user experience. ### Reports and Dashboards for PWA Kit [Reports and Dashboards demo recording](/salesforce-b2c-commerce-cloud-23-2/rd-overview.mp4) Starting now, Commerce Cloud Reports and Dashboards work for the Composable Storefront! Not all reports work yet Please be aware that a patch is coming in early February to ensure order data makes it to these reports. At the time of writing, 8 out of the 11 dashboards work. ## Business Manager ### Do More When Calculating VAT > You can now calculate tax and use rounding based on tax groups, which is a legal requirement for Japanese taxation. The calculation method uses a new Tax Rounding Level site preference called Group. The tax groups are exposed via OCAPI and Script API to support customisation. How: To enable rounding per grouped tax rate, in Business Manager Site Preferences, set the Order Item Price Rounding Policy to GROUP. As I am not familiar with Japanese tax law, so it is not something I can go into. But for anyone who has a project active in Japan, I am sure it is a needed improvement. ### Fine-Tune Your Site’s Regional Settings > You now have full control in Business Manager over all parameters used for converting numbers and dates into strings. Use the new Format Symbols tab and regional parameters to add Locale details. **Where:** In Business Manager, select Administration | Locales | local ID > > - The Format Symbols tab is added for Locale details. > - The Numeral System settings are removed on the Locale details General Tab. > - New Regional setting parameters are added to Export and Import of locales. A nice improvement for locale management because it gives users complete control over all parameters used for converting numbers and dates into strings with configuration. This is beneficial because it provides more flexibility and precision in formatting numbers and dates according to regional and language-specific standards. ## OCAPI & SCAPI ### Access Page Designer with SCAPI > You can now use the Shopper Experience SCAPI API to add content created in Page Designer to your B2C Commerce headless implementation. Use the SCAPI Shopper Experience API to look up page information for pages created in Page Designer. The Shopper Experience API responses include: > > - The entire component hierarchy of the page at design time. > - All merchant data provided at design time. > - Server-side scripting data provided at run time. The new “[Shopper Experience API](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-experience?meta=Summary)” is a significant improvement for both Headless and Composable Storefront projects. In the past, solutions required complex workarounds to enable personalisation with [session bridging](/what-is-the-ocapi-session-bridge/). But this update eliminates the need for those workarounds. This change is highly anticipated, and I am sure it will be warmly welcomed by many. It brings more efficiency and ease of use to projects in need of the API. ### Other SCAPI Updates - Rate limit increase for `GET /customers/*(Shopper-Customers)`, see [Rate Limits](https://developer.salesforce.com/docs/commerce/commerce-api/guide/throttle-rates.html). - Security update for SCAPI platform environment. - Maintenance and stability updates for SCAPI platform environment. - Update TrustedAgentOnBehalf support for Shopper Token policy. - Prepare SCAPI platform for future feature enablement. ### SLAS Updates #### Support Forgerock IDP [ForgeRock Identity Platform](https://www.forgerock.com/) is an open-source identity management platform that provides authentication, authorisation, and identity management solutions for organisations. It is also a popular choice among financial institutions, healthcare providers, and government agencies to help them comply with industry regulations and standards. This is also the system behind [Account Manager](https://account.demandware.com/). #### Enhanced BOT mitigation strategy within SLAS The release log does not provide much more information on what specific actions have been taken to improve security. However, any improvement in security measures is generally welcome in order to better protect against malicious bots. #### /jwks endpoint now returns 3 key IDs Verify Impact Check if this change impacts any of your projects that use SLAS! JWKS (JSON Web Key Set) provides a set of keys that includes the current, past, and future public keys. This set of keys allows clients to check the authenticity of a token, called JWT, SLAS issues that for the shopper. #### Other SLAS updates - Trusted Agent On Behalf (TAOB) now supports Private ClientID flow, and TAOB JWT token expiry changed from 30 to 15 minutes for PCI compliance. - Reduced the Passwordless OTP - token length from 20 to 8 characters. - Fixed inconsistencies related to failed tokens. - Session Bridge: Improved error messaging & guest support. - SLAS no longer calls ecom, when a shopper account is locked. - User cache refinements & Fixed cache inconsistencies after tenant key rotation. - Addressed login ID inconsistencies for passwordless login. - Fixed AppleIDP issue related to middle name. - Security library updates. ## Development ### Set Up Payments for Immediate or Future Payment Capture > You can use the SalesforcePaymentRequest script API to set immediate or future payment captures. Use this method to override the site-level payment settings and gain greater flexibility over how payments are captured. New functions have been exposed on the SalesforcePaymentRequest: ```text salesforcePaymentRequest.getCardCaptureAutomatic(); salesforcePaymentRequest.setCardCaptureAutomatic(Boolean); ``` ### Do More When Calculating VAT (Development) New functions are now exposed to work with the new rounding options per group (see the item about Japanese Taxation): ```text lineItemCtnr.getTaxTotalsPerTaxRate(); lineItemCtnr.isTaxRoundedAtGroup(); basket.isTaxRoundedAtGroup(); order.isTaxRoundedAtGroup() ``` ## PWA Kit v2.5.0 A new preview release of the commerce-sdk-react library is now available on [npm](https://www.npmjs.com/package/commerce-sdk-react-preview) and includes ready-made React hooks for fetching data from B2C Commerce. The release also includes updates to pwa-kit-create-app, pwa-kit-dev, pwa-kit-react-sdk, pwa-kit-runtime, and template-retail-react-app. Some of the changes include adding instanceType to Einstein activity body, logging cid from res header instead of req in local development, and handling variants with Einstein. [View the full changelog](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v2.5.0). ## Bugfixes The developers of the current release have been unable to catch a bug, much like trying to catch a fly with chopsticks, resulting in no bug fixes included in this version. But we trust they will keep trying to improve the product. ## Updated Cartridges & Tools ### Composable Storefront Toolkit - [https://github.com/SalesforceCommerceCloud/composable-storefront-pocs](https://github.com/SalesforceCommerceCloud/composable-storefront-pocs) > This repo is a composable storefront implementation with various proof of concepts baked in. It otherwise closely tracks pwa-kit. A new cartridge has appeared, containing some goodies for the Composable Storefront! As all of these are POCs (Proof of Concept), understand that they still need some polishing. ### b2c-tools (v0.15.0) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances and administrative APIs (SCAPI, ODS, etc). It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. - adds custom preference support to instance info by [@clavery](https://github.com/clavery) in [#95](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/95) - intellij sfcc 2022.3 compatibility by [@clavery](https://github.com/clavery) in [#97](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/97) ### Salesforce B2C Commerce / Customer 360 Platform Integration (v2.0.0) - [https://github.com/SalesforceCommerceCloud/b2c-crm-sync](https://github.com/SalesforceCommerceCloud/b2c-crm-sync) > Salesforce B2C Commerce / CRM Sync is an enablement solution designed by Salesforce Architects to teach Salesforce’s B2C Customer Data Strategy for multi-cloud use-cases. The solution demonstrates a contemporary approach to the integration between Salesforce B2C Commerce and the Cloud products running on the Salesforce Customer 360 Platform. - Upsert Map instead of List for Account update by [@filipecarvalho15](https://github.com/filipecarvalho15) in [#165](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/165) - Bump async from 3.2.0 to 3.2.2 by [@dependabot](https://github.com/dependabot) in [#162](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/162) - Bump npm from 7.20.3 to 8.11.0 by [@dependabot](https://github.com/dependabot) in [#172](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/172) - Bump moment from 2.29.1 to 2.29.4 by [@dependabot](https://github.com/dependabot) in [#183](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/183) - Bump snyk from 1.672.0 to 1.1024.0 by [@dependabot](https://github.com/dependabot) in [#200](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/200) - Bump snyk-go-plugin and snyk by [@dependabot](https://github.com/dependabot) in [#201](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/201) - Fix unit tests by [@jbachelet](https://github.com/jbachelet) in [#213](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/213) - Fix issue with platform event failing due to “System.CalloutException” exception by [@jbachelet](https://github.com/jbachelet) in [#212](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/212) - Bump qs from 6.5.2 to 6.5.3 by [@dependabot](https://github.com/dependabot) in [#211](https://github.com/SalesforceCommerceCloud/b2c-crm-sync/pull/211) --- ## How to set up SLAS for the Composable Storefront Canonical URL: https://rhino-inquisitor.com/how-to-set-up-slas-for-the-composable-storefront/ Markdown URL: https://rhino-inquisitor.com/how-to-set-up-slas-for-the-composable-storefront/index.md Content type: article Published: 2023-01-16T08:12:41Z Updated: 2023-01-16T08:12:55Z Summary: Setting up SLAS for the first time can be quite a headache. Or maybe not? Is there an easy way to set up SLAS for the PWA Kit? Categories: Salesforce Commerce Cloud, Technical Tags: composable storefront, sfcc, slas, technical ## Key Takeaways - Walks through a practical SLAS setup flow for connecting a Composable Storefront to an SFCC sandbox - Explains where to find the short code, organization ID, and SLAS Admin UI configuration flow - Covers client creation, OCAPI access updates, and the PWA Kit install inputs required to go live Are you setting up your Composable Storefront and wondering what the SLAS Client ID is all about? You’re not alone! The [Shopper Login and API Access Service](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas.html), or SLAS, has been gaining popularity, but it can be challenging to set up. But don’t worry. We’ve got you covered. Instead of diving into a sea of Administrative APIs, we’re here to break it down and show you a simple way to set up your SLAS. Keep reading to find out how! ## Official Guide Salesforce has a guide for this installation publicly available. Some steps are more fine-grained here, whilst others are more detailed in the official guide. [https://developer.salesforce.com/docs/commerce/commerce-api/guide/authorization-for-shopper-apis.html](https://developer.salesforce.com/docs/commerce/commerce-api/guide/authorization-for-shopper-apis.html) This official guide also shows you how to use the APIs, which I will not cover here. ## Step 1: Get a sandbox If you want to connect the Composable Storefront to your own APIs (including SLAS), you need your own Sandbox. We will not be digging into this topic here, but the information to get one [is described in a previous article](/how-to-get-a-salesforce-b2c-commerce-cloud-sandbox/) and [the official documentation](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/creating-an-on-demand-sandbox.html). ## Step 2: Go to the Salesforce Commerce API Settings After you have logged into the Business Manager of your environment, go to the following: “Administration > Site Development > Salesforce Commerce API Settings” ![Salesforce Commerce API Settings page with the SLAS Admin UI link.](/how-to-set-up-slas-for-the-composable-storefront/slas-admin-ui-button-business-manager-7bdbd7a798_hu_d69dbc9492e3e29b.webp) This is the Business Manager starting point for finding your SLAS setup details. The link is not there. If you do not see the link (the link is inserted by [DWithEase](https://dwithease.com/)), manually go to the URL: `https://{{Short_Code}}.api.commercecloud.salesforce.com/shopper/auth-admin/v1/sso/login`. On this screen, some necessary information to install the PWA Kit can be found. But besides the Short Code and the Organization ID, there is an interesting link present: “SLAS Admin UI”. Let’s click that now, shall we? ![Sign-in page that links to the SLAS Admin UI.](/how-to-set-up-slas-for-the-composable-storefront/slas-admin-ui-login-ff882d0848_hu_61f72a108171c5aa.webp) If the shortcut is missing, this login page still gets you into SLAS Admin. When we click this link, the above screen should become visible. It shows a blue button with the text “SLAS Admin UI Login”. We are logged in with our Account Manager user when this link is clicked. To manage SLAS, we need the necessary permission (given to us by an Account Manager “Account Manager”: Scopes Do not forget to assign the correct scopes to this role! ![Account Manager role scopes required for SLAS administration.](/how-to-set-up-slas-for-the-composable-storefront/slas-rights-account-manager-dfaa6aa6b8_hu_63612243c3e1f76d.webp) These Account Manager scopes are the real prerequisite for managing SLAS clients. ## Step 3: Add a new SLAS Client If the used account has the correct permissions, we should be greeted by a friendly “Welcome screen”. ![SLAS Admin UI welcome page after a successful sign-in.](/how-to-set-up-slas-for-the-composable-storefront/slas-admin-welcome-ui-bbc3ad8da9_hu_e76ee6c412c20b4e.webp) A successful sign-in lands you on the SLAS Admin UI home screen. On this page, click the “Clients” tab to go to the list of active clients we are permitted to manage (see scopes in the previous step). ![Client list in the SLAS Admin UI.](/how-to-set-up-slas-for-the-composable-storefront/slas-admin-add-client-c488a4b6e3_hu_fa72dd5788d18788.webp) The Clients tab is where you manage existing entries and create a new one. Click the “Add Client” button on this page to go to the next step. ![New client form for a PWA Kit SLAS application.](/how-to-set-up-slas-for-the-composable-storefront/slas-admin-ui-new-client-pwa-kit-c70f8d1fd1_hu_a97c6632fa4d23ff.webp) This form creates the public client the Composable Storefront will authenticate with. And with that, we are almost there! Fill in the following information: - **What tenant will be used?:** Fill in the Tenant ID, part of the Organization ID, from step two. (format: xxxx\_sxx) - **What site will be used?:** Here, we fill in the site IDs used - separated by a space. - **Which App Type will be used?:** Well… the article is for the Composable Storefront, so let us select “_PWA Kit or SFRA or Mobile_.” Selecting this option will make a [Public Client](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-public-client.html). - **Client Id:** The Client ID to use during the installation of the PWA Kit. This can be left as-is. _Note: This Client ID does not need to exist as an API Client in the Account Manager. They are not related._ - **Secret:** Public Clients do not need a secret - **Do you want the default shopper scopes?:** Since we will be using the PWA Kit, leave this checked. - **Enter custom shopper scopes:** This step can be left empty. As the final step: “Click Submit”. Otherwise, not a lot is going to be happening. ### Typo in the scopes Currently (January 16th, 2023), there is an error in the default scopes that needs to be fixed manually. Specifically, there is a missing space between “sfcc.shopper-myaccount.orders” and “sfcc.shopper-myaccount.paymentinstruments”. ![Scope list showing the missing space in the default shopper scopes.](/how-to-set-up-slas-for-the-composable-storefront/typo-in-scopes-3b0626d7b7_hu_23612417215d799f.webp) Check these default scopes before saving because the bundled list contains a typo. ## Step 4: Enable OCAPI endpoints Follow step “Update Open Commerce API Settings” on the following page using the SLAS Client ID generated in the previous step: [https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/setting-up-api-access.html](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/setting-up-api-access.html) ## Step 5: Use the new SLAS Client Now that we have our SLAS Client, Short Code, and Organization ID, we can start installing the PWA Kit! Open up your favorite terminal and enter: ```text npx pwa-kit-create-app ``` During the execution you will be prompted to enter certain information. ### What is the name of your Project You can choose whatever name makes the most sense for you. Keep in mind that this is also the name of the folder it will create. ### What is the URL for your Commerce Cloud instance Fill in the URL of your sandbox, and this looks something like: ```text https://xxxx-0xx.dx.commercecloud.salesforce.com/ ``` ### What is your SLAS Client ID Enter the Client Id generated in step 3. ### What is your Site ID in Business Manager Enter the Site ID of the site you will use (e.g. RefArch). ### What is your Commerce API organization ID in Business Manager This information can be found in the “Salesforce Commerce API Settings” in the Business Manager of your environment. This was covered in step 2. ### What is your Commerce API short code in Business Manager This information can be found in the “Salesforce Commerce API Settings” in the Business Manager of your environment. This was covered in step 2. ## Step 6: Run the PWA Kit Now that we have SLAS up and running and our PWA Kit installed locally, all that is left is to run our application by going into the new folder the command has created, and doing: ```bash npm start ``` A browser screen will automatically open. And if all goes well, a homepage will appear after a short wait! ![Composable Storefront homepage after the starter app launches.](/how-to-set-up-slas-for-the-composable-storefront/pwa-kit-03394b0f92_hu_e56aa2bf1eb8f1c0.webp) If the setup worked, the starter storefront should boot with the new SLAS client. In conclusion, setting up the SLAS Client ID for your Composable Storefront may seem like a daunting task, but with the help of this guide, you’ll be a pro in no time. And if you’re still feeling a bit overwhelmed, remember that we’ve all been there. But hey, at least now you have a fancy new configured SLAS to show off to your friends and family, who are sure to be impressed by your technical prowess. So go forth and conquer the world of online business, one SLAS at a time. --- ## Simplifying the Salesforce Order of Execution Canonical URL: https://rhino-inquisitor.com/simplifying-the-salesforce-order-of-execution/ Markdown URL: https://rhino-inquisitor.com/simplifying-the-salesforce-order-of-execution/index.md Content type: article Published: 2023-01-09T05:48:13Z Updated: 2023-02-26T17:38:41Z Summary: How can we simplify the Order of Execution in Salesforce? Find out in this article where we only use modern and KISS solutions! Categories: Salesforce Platform Tags: apex, platform, salesforce, triggers ## Key Takeaways - Presents a simplified view of Salesforce's order of execution for teams favoring modern automation patterns - Explains how retiring Workflow Rules and Process Builder reduces complexity, recursion, and debugging overhead - Frames the simplified model as a practical planning aid rather than a universal replacement for the official diagram When it comes to understanding how Salesforce operates, there are many factors to consider. One key aspect is the “Order of Execution”, or the sequence in which Salesforce automation runs. Knowing the order of execution can help you better understand how your code, triggers, flows, and other automation tools operate within the platform. Whether you’re a seasoned Salesforce developer or new to the platform, understanding the [Order of Execution](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm) is essential to maximising the system’s potential. But there are so many different automation types available, and do I need to consider all of them in all use cases? This article might spark some heated debate, I am well aware! It delves into the topic of automation and how to choose the right tools for your organization while filtering out unnecessary automation and simplifying processes to reduce complexity. But don’t worry, and we’re not trying to stir the pot too much… just a little 😜. As software developers and architects, it’s essential to consider ways to streamline and improve our workflows constantly. Let’s dive in and start the conversation. ## tl;dr - show me the diagram For the impatient amongst us, here is the diagram showing the simplified representation of the “Order of Execution” based on [the original diagram posted on the Salesforce Architects blog](https://medium.com/salesforce-architects/salesforce-order-of-execution-visualized-76ac45721eba). ![Simplified Salesforce order-of-execution diagram](/simplifying-the-salesforce-order-of-execution/order-of-execution-simplified-apex-api-v56-0-23130ad657_hu_6a8797d32df92c6c.webp) Figure 1: Simplified Salesforce Order of Execution [View on Lucid](https://lucid.app/lucidchart/17edf202-1994-4772-8a0b-4d2835a9799e/edit?viewport_loc=3530%2C810%2C1844%2C838%2C0_0&invitationId=inv_f7af9e9a-9783-47ca-ab06-1142226cad87) Not for everyone. This diagram is meant to assist those starting a new project or has already migrated all of their automation to Flow. Remember that it may not work for every organization, as many have Workflow Rules and Process Builder automation that cannot be migrated overnight. If you are working on Sales or Service Cloud, the original diagram still applies to you if you use these types of automation. The goal is to help you make informed decisions about your automation strategy.​ ## The complexity and nuances ### Continuously changing Small (or significant) changes happen to the “Order of Execution” over time. And details on each step can change, so make sure to re-evaluate this process with each new release - it might impact you more than you might think (in a good or bad way). An excellent example between v55.0 and v56.0 is that the following warning has disappeared: Record-triggered flows If multiple active record-triggered flows are configured, the order in which those flows are executed isn’t guaranteed. This is a great improvement, but warrants more investigation: “[In what order are they executed then?](https://help.salesforce.com/s/articleView?id=release-notes.rn_automate_flow_builder_trigger_order.htm&type=5&release=236)” ### An overview When looking at all the different [automation tools](https://help.salesforce.com/s/articleView?id=sf.process_which_tool.htm&language=en_US) available within the Salesforce platform, it is easy to get overwhelmed. And that is not even considering the order they are executed in on the data. - [Workflow Rules](https://help.salesforce.com/s/articleView?id=customize_wf.htm) (retiring) - [Process Builder](https://help.salesforce.com/s/articleView?id=sf.process_overview.htm&type=5&language=en_US) (retiring) - [Flow Builder](https://help.salesforce.com/s/articleView?id=sf.flow.htm&type=5&language=en_US) - [Apex](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers.htm) - [Assignment Rules](https://help.salesforce.com/s/articleView?id=sf.customize_leadrules.htm&language=en_US) (Lead & Case) - [Escalation Rules](https://help.salesforce.com/s/articleView?id=sf.rules_escalation_best_practices.htm&type=5) (Case) - [Entitlement Rules](https://help.salesforce.com/s/articleView?id=sf.entitlements_overview.htm&type=5) (Case & Work Order) - [Sharing Rules](https://help.salesforce.com/apex/HTViewHelpDoc?id=sf.security_about_sharing_rules.htm&language=en_us) - [Restriction Rules](https://help.salesforce.com/s/articleView?id=sf.security_restriction_rule.htm&release=240.17.0&language=en_us&type=5) - [Validation Rules](https://help.salesforce.com/s/articleView?id=sf.fields_defining_field_validation_rules.htm&type=5) All in all, quite a list, correct? But behind a few of them, we notice that they are retiring or only apply to one or two object types. So what happens if we take those out of the equation? Does that make our “Order of Execution” easier? ### Retiring features Salesforce [announced in 2021](https://admin.salesforce.com/blog/2021/go-with-the-flow-whats-happening-with-workflow-rules-and-process-builder) that it is retiring the Workflow Rules and Process Builder features in favour of Flow. This change is part of Salesforce’s effort to streamline and modernize its platform. For those unfamiliar with Workflow and Process Builder, they are tools that allow users to automate various processes within Salesforce. Workflow Rules is a set of rules that can automatically trigger specific actions based on certain criteria, such as sending an email or updating a field. On the other hand, Process Builder is a visual tool for building automated processes and workflows, allowing users to create complex automation without needing code. It’s worth noting that Workflow Rules and Process Builder will not disappear overnight – Salesforce has stated that they will continue supporting these features for the foreseeable future. However, it is strongly recommended that users begin transitioning to Flow as soon as possible, as support for Workflow Rules and Process Builder will eventually be phased out. The first signs are already here, as [you can no longer create new Workflow Rules](https://help.salesforce.com/s/articleView?id=release-notes.rn_automate_flow_mgmt_block_workflow_rules.htm&release=240.17.0&language=en_us&type=5). And yes, not being able to create new automation with Process Builder is next! _So let us take these out of the equation, shall we? Why? Because they are known for some quirky behaviour_: - The order of execution takes a turn for the worse in complexity - Custom validation rules, flows, duplicate rules, processes, and escalation rules aren’t run again with Workflow field updates. - Workflow Rules executes before update triggers and after update triggers, regardless of the record operation (insert or update), one more time (and only one more time). - Recursion (up to 5 more times) in both Workflow Rules and Process Builder - Workflow Rules and Process Builder can run Flows - that’s a fun one to start debugging ### Object specific features Another consideration to simplify the chain is to look at processes that only run for a limited set of objects. It may have all started with Sales and Service Cloud. But in the meantime, many new products have joined the ecosystem that do not rely on these object types (and the automation that comes with them). Knowing that we can eliminate: - Assignment Rules (Lead & Case) - Escalation Rules (Case) - Entitlement Rules (Case & Work Order) ## Putting it all together Now that we have taken out all the above from consideration, we end up with the following updated visual: ![Simplified Salesforce order-of-execution diagram](/simplifying-the-salesforce-order-of-execution/order-of-execution-simplified-apex-api-v56-0-23130ad657_hu_6a8797d32df92c6c.webp) Figure 2: Simplified Salesforce Order of Execution (updated visual) [View on Lucid](https://lucid.app/lucidchart/17edf202-1994-4772-8a0b-4d2835a9799e/edit?viewport_loc=3530%2C810%2C1844%2C838%2C0_0&invitationId=inv_f7af9e9a-9783-47ca-ab06-1142226cad87) ## Why create this diagram I am well aware that there is [already a clear and documented visual](https://medium.com/salesforce-architects/salesforce-order-of-execution-visualized-76ac45721eba), and it is linked in the article! But this diagram considers all the items I mentioned before (retiring and object-specific), and I wanted a simplified version taking out all of these and seeing what remained. Not for everyone. This diagram is meant to assist those starting a new project or has already migrated all of their automation to Flow. Remember that it may not work for every organization, as many have Workflow Rules and Process Builder automation that cannot be migrated overnight. If you are working on Sales or Service Cloud, the original diagram still applies to you if you use these types of automation. The goal is to help you make informed decisions about your automation strategy.​ ### Modern When all of the retiring options are taken out, many of the known “quirks” fade into the distance - making our automation more future-proof and robust. ### Debugging becomes easier Another advantage is that debugging the automation becomes a lot easier! There are fewer areas to keep track of, and your logs are cleaner. You don’t have to catch them all; it is not a game of Pokémon! [Keep it simple, stupid!](https://en.wikipedia.org/wiki/KISS_principle) ### “Recursion” begone (almost) With the disappearance of recursion (up to 5x with Workflow Rules and Process Builder), we do not have to remember that some automation does not run inside that recursion. It is still possible to [create recursion](https://help.salesforce.com/HTViewSolution?id=000199485) with the remaining options, but it is much harder to do so - especially if you follow best practices in Apex and Flow. ### Getting rid of the Trigger warning After “cleaning up”, we are only left with a single warning: “The order in which our Apex Triggers are executed.” But luckily, the notice also includes the solution: [Using a framework](https://www.salesforceben.com/the-salesforce-trigger-handler-framework/). ## Conclusion We can lower the complexity of our automation “chain” when only modern features are used. And if we are not using Sales or Service Cloud, things become easier to keep track of. > Getting rid of a “chaotic” / fragmented automation landscape is key to predictability & stability of your automations. [Daniel Stange](https://www.linkedin.com/posts/danielstange_simplifying-the-salesforce-order-of-execution-activity-7018472428523642880-Ef-S?utm_source=share&utm_medium=member_desktop) Of course, cloud-specific automation will not disappear. But give it some time, and Workflow Rules and Process Builder will take their leave from the official diagram. And that will bring the above diagram closer to being obsolete! But until then, feel free to use the visual and make a copy to keep it up to date for yourself! Keeping the diagram up to date As it stands, I have yet to decide if I will spend the time to update this diagram with each new release. So always check the “last updated” date and API version at the top of the visual! For that reason, I have shared the link to the original Lucid file (look at the image) - so others can take charge and make updates where necessary. To err is human Did you spot a typo or mistake? Let me know! You can find links to my socials in the footer. --- ## Submitting a file to a third party service in SFCC Canonical URL: https://rhino-inquisitor.com/submitting-a-file-to-a-third-party-service-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/submitting-a-file-to-a-third-party-service-in-sfcc/index.md Content type: article Published: 2023-01-02T08:00:00Z Updated: 2023-01-02T08:00:00Z Summary: Learn how to submit files to a third-party service from SFCC with the Service Framework, including setup concerns and pitfalls. Categories: Salesforce Commerce Cloud, Technical Tags: file, services, sfcc, technical ## Key Takeaways - Shows how to send a file to a third-party service from SFCC using the LocalServiceRegistry and HTTP service framework - Explains both the simple file-return pattern and the execute-override pattern for more control over the request - Covers the related Business Manager service configuration and logging behavior developers should understand Salesforce B2C Commerce Cloud provides developers and architects with a [framework to integrate third-party services](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/web_services/b2c_webservices.html), making it much more streamlined to get up and running. With the [LocalServiceRegistry,](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/web_services/b2c_coding_your_web_service.html) you get some neat features like configuration management from the business manager, logging, and service monitoring! There are examples available on how to use this system, but how do you send a file to a service using it? There isn’t an example available for this (except for an FTP service that, by definition, works with files). ## TLDR; solution ### Multipart/Form-Data A [separate article is available](/submit-multipart-form-data-to-a-third-party-service-in-sfcc/) if your service uses the Multipart format. ### Single File For those who want a code snippet to copy and paste, here you go! ```js LocalServiceRegistry.createService('test.http.post', { createRequest: function (svc, args) { var File = require('dw/io/File'); // In case you have a variable endpoint svc.setURL(args.uploadUrl); return new File(args.filePath); }, parseResponse: function(svc, client) { return client.text; } }) ``` Or if you want more control over your request: ```js LocalServiceRegistry.createService('test.http.post', { createRequest: function (svc, args) { // In case you have a variable endpoint svc.setURL(args.uploadUrl); return args; }, executeOverride: true, execute: function(svc, args) { var File = require('dw/io/File'); var client = svc.client; client.send(new File(args.filePath)); }, parseResponse: function(svc, client) { return client.text; } }); ``` ## Configuration in the Business Manager In the Business Manager go to: “Administration > Operations > Services” [![Administration and Operations menu path to Services.](/submitting-a-file-to-a-third-party-service-in-sfcc/administration-operations-services-ecba1de963_hu_1147a150cd74513a.webp)](/submitting-a-file-to-a-third-party-service-in-sfcc/administration-operations-services-ecba1de963.jpg) And click the “New” button on the bottom right. Here we can configure our service: [![Example HTTP POST service configuration in Business Manager.](/submitting-a-file-to-a-third-party-service-in-sfcc/test-http-post-service-be40e7ba49_hu_3068c97e3526029e.webp)](/submitting-a-file-to-a-third-party-service-in-sfcc/test-http-post-service-be40e7ba49.jpeg) This example service is configured with the following values: - **Name:** It can be any name as long as it matches the name (ID) used in the code. - **Type:** In this case, HTTP service is selected. This ensures the Service Framework behind the scenes uses the correct client (HTTP). - **Service Mode:** To call the service endpoint, the value needs to be “Live.” - **Log Name Prefix:** If you want to debug and have all request and response data in a dedicated file for this service, fill this in. - **Communication Log Enabled:** This must be enabled to debug the requests and responses through logging. - **Force PRD Behavior in Non-PRD Environments:** If you filter the logs and want to test as if it is a production environment, enable this. - **Profile:** Select the profile to be used (timeouts, rate limiting, circuit breaker.) - **Credentials:** Depending on the service, this needs to be configured. Now everything is configured in the Business Manager, and we can move on to writing some code. ## Returning the file in createRequest ```js LocalServiceRegistry.createService('test.http.post', { createRequest: function (svc, args) { ... return new File(args.filePath); } }) ``` No rocket science is happening here. The Service Framework automatically detects it is a file being returned and executes the appropriate logic on the [HTTPClient](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_net_HTTPClient.html) “beneath the surface”. ## In case we override the execute logic ```js LocalServiceRegistry.createService('test.http.post', { createRequest: function (svc, args) { ... }, executeOverride: true, execute: function(svc, args) { var File = require('dw/io/File'); var client = svc.client; client.send(new File(args.filePath)); }, parseResponse: function(svc, client) { ... } }); ``` Overriding the “execute” logic is quite simple. As explained in the [ServiceCallback](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_svc_ServiceCallback.html) documentation, we can use the “_executeOverride _” flag to write some custom code on how the external service is called. In this case, we get the original [HTTPClient](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_net_HTTPClient.html) from the [Service](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_svc_HTTPService.html) using “_ svc.client._” This client has a function for us to send a file over to an external endpoint: [send(File)](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_net_HTTPClient.html#dw_net_HTTPClient_send_File_DetailAnchor). ## Effects on logging When working with files, the function “[_filterLogMessage_](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_svc_ServiceCallback.html#dw_svc_ServiceCallback_filterLogMessage_String_DetailAnchor)” receives what you return in the “_createRequest_” call rather than the request’s body. This might be a good thing if you are sending large files. ```text INFO PipelineCallServlet|1954691750|Sites-RefArch-Site|Login-Post|PipelineCall|kxZB-_nwKL custom.service.test.http.post.COMM [] Request: [File path=/TEMP/my-file.zip] ``` --- ## What can I use ChatGPT for when working with Salesforce? Canonical URL: https://rhino-inquisitor.com/what-can-i-use-chatgpt-for-when-working-with-salesforce/ Markdown URL: https://rhino-inquisitor.com/what-can-i-use-chatgpt-for-when-working-with-salesforce/index.md Content type: article Published: 2022-12-26T06:44:32Z Updated: 2022-12-26T06:44:32Z Summary: A practical look at where ChatGPT can help in Salesforce work, from drafting and debugging to research and day-to-day delivery. Categories: Corporate Tags: ai, security, technical ## Key Takeaways - Explores practical ways ChatGPT can help with Salesforce work, including answering questions, drafting content, and generating starting-point code - Balances those use cases with concerns around copyright, accuracy, data handling, and unsafe or invalid code generation - Argues that AI output should be treated as a productivity aid and review input, not as something to trust without validation The year is coming to an end, but what a year it has been. As the news was announcing lockdowns to be over and [events were starting](/events-and-the-golden-hoodie/), the world was in turmoil again when Russia began to invade Ukraine - putting the world on its head again. Putting that aside (but not for too long), other big things have happened this year: Big strides in publically available AI tools. Although they have been around longer than this year, they have gotten quite a bit of attention as the ease of use has grown tremendously. People generate [images based on text descriptions](https://openai.com/dall-e-2/) and [write articles by asking questions](https://chat.openai.com/). …What? Other Services Besides OpenAI, many services are popping up in different areas. Too many to even mention. ## Some concerns In this article, I will mainly focus on ChatGPT. But other services might be mentioned for particular concerns. ### Copyright For AI to work, it needs to be fed large amounts of information. And luckily for them, the internet is a vast resource of publicly available data. But what about copyright? Someone wrote that “data”, and maybe not everyone has given their consent to that data being ingested and used in such a way. I am no lawyer or legislative specialist, and I will follow this news. But there are already lawsuits and concerns being outed everywhere. - [Lawsuit Takes Aim at the Way A.I. Is Built](https://www.nytimes.com/2022/11/23/technology/copilot-microsoft-ai-lawsuit.html) - [Is ChatGPT a ‘virus that has been released into the wild’?](https://techcrunch.com/2022/12/09/is-chatgpt-a-virus-that-has-been-released-into-the-wild/) - [Artists fed up with AI-image generators use Mickey Mouse to goad copyright lawsuits](https://www.dailydot.com/debug/ai-art-protest-disney-characters-mickey-mouse/) ### Incorrect Information We (hopefully) all know that the internet contains a lot of incorrect information. And that information has most likely also been fed to these AI. If you start asking questions to ChatGPT, heed the warnings it gives you! ![ChatGPT home page warning that answers may be inaccurate or harmful.](/what-can-i-use-chatgpt-for-when-working-with-salesforce/chatgpt-warnings-5212d4f2bc_hu_68ff27418952df04.webp) Fact Check and Quality Check With each generated piece of text, do some validation and verify it to be correct and not harmful. - [Stack Overflow temporarily bans answers from OpenAI’s ChatGPT chatbot](https://www.zdnet.com/article/stack-overflow-temporarily-bans-answers-from-openais-chatgpt-chatbot/) ### Free (for now) Going to keep this one short: “If something is free, you are the product.” Think about that one when entering information into these services. ![ChatGPT FAQ entry that explains how conversation data may be used.](/what-can-i-use-chatgpt-for-when-working-with-salesforce/chatgpt-faq-2022-40f4e275e1_hu_1815cdc016075000.webp) ## What can we use it for With those concerns out of the way, we can get to some of the good stuff. What can we use these services for? Making our lives a little bit easier, **_one step_** at a time. ### Answer questions you have One of the primary purposes these AI services are used for, is to answer questions. ChatGPT was trained on conversational content to explain things and respond in a “human tone”. Do you have questions about a Salesforce product, chances are pretty high it will give you a correct answer. But again, keep in mind the warnings above! ### Write Content One of the great things about ChatGPT is that it writes very detailed explanations in a very short amount of time. This can speed up writing documentation and guides needed for certain features. 2021! The Salesforce ecosystem and features change rapidly, meaning that the guides written by ChatGPT do not consider changes and new features added to the products in 2022. ### Write Code I am getting into dangerous territory now, aren’t I? Yes, [many articles have already been written about ChatGPT’s ability to write code](https://www.apexhours.com/chatgpt-to-salesforce-developers/). But as these articles point out, this new “option” is dangerous for Junior developers (and also senior devs). There have been many occasions of ChatGPT providing good answers. But it has also pushed out insecure, bad performing, and bad practice code. I also tried to get it to generate Salesforce B2C Commerce Cloud code, but since most of the code is not public, it tends to create Salesforce B2B examples or give generic answers. We use “Controllers” as the name for our server-side code, which is probably not helping our case with this AI. ![ChatGPT attempt to prepend an SFRA controller.](/what-can-i-use-chatgpt-for-when-working-with-salesforce/sfra-prepend-controller-chatgpt-67cd953d79_hu_da274d7d402965ed.webp) Ok… let’s try that again? ![Second ChatGPT attempt to prepend SFRA review logic.](/what-can-i-use-chatgpt-for-when-working-with-salesforce/sfra-prepend-reviews-chatgpt-attempt2-d8dd9d7540_hu_bc3d0cd3aa3158f6.webp) Ok, that is not nearly close to what I meant. Let’s see how many attempts I need for a Salesforce Apex trigger. ![ChatGPT Apex trigger attempt for downloading product reviews.](/what-can-i-use-chatgpt-for-when-working-with-salesforce/salesforce-apex-trigger-chatgpt-download-reviews-02315d688b_hu_35fca0d73a2da3ed.webp) That is more like it! There is much more public code available for the Salesforce platform than for B2C Commerce Cloud (Demandware). And that also explains why I need fewer attempts to get what I want. But some things could be improved in the code it generated - Notice the insert of the single review inside a loop? So again, _**USE WITH CARE**_! But you can ask the AI to correct itself: ![Revised Apex trigger attempt after asking ChatGPT to improve the code.](/what-can-i-use-chatgpt-for-when-working-with-salesforce/salesforce-apex-trigger-fixed-chatgpt-4f14ff15f9_hu_bae05ad6e574cf7c.webp) Maybe formulating the questions in a specific manner will generate higher-quality responses. Perhaps something like this: ```text Write a Salesforce apex trigger to download reviews from a third party when a product is saved, making use of best practices and avoiding governor limits ``` Invalid Code Even with the corrections in the Apex Trigger mentioned above, there is still a big issue with the code generated: [‘Callout from triggers are currently not supported’ error](https://help.salesforce.com/s/articleView?id=000386018&type=1) But it is a starting point. ## The future It is exciting and scary how quickly the world of AI is evolving. We have gotten quite a few new toys this year to play with. But what does 2023 have in store for us? How quickly will they evolve now that we have come to a point where data is so easily accessible and in large volumes? ## Conclusion These new AI tools make our lives easier, and the results it is pushing out are amazing to behold. Learning how to use this tool will also take some time: The better you can formulate your questions or descriptions, the better the AI’s responses will get. Speaking from personal experience, I have to rephrase my questions quite often to get a good result. Luckily, for now, the failed attempts are free. But for how long? And on a final note, make sure to fact-check and optimize what has been generated. In many cases, the text or code generated needs some “refactoring” to be useful. If there is **one takeaway** from the above article: “**Don’t trust the info it gives you just yet**. Use it as a starting point - but nothing more.” --- ## Salesforce B2C Commerce Cloud 23.1 Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-23-1/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-23-1/index.md Content type: article Published: 2022-12-19T08:35:50Z Updated: 2023-03-01T18:52:05Z Summary: A new year means releases for Salesforce B2C Commerce Cloud are back! Let us have a look if there are some presents for us! Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc ## Key Takeaways - Highlights the most relevant 23.1 updates around legacy-job migration, sandbox URLs, retention policy, and HSTS controls - Explains smaller but useful OCAPI improvements to property selection and basket flash behavior - Calls out the accompanying PWA Kit, b2c-tools, and sfcc-ci releases that matter for day-to-day development Summer has arrived, and so has the next Salesforce B2C Commerce Cloud release! This time we look at the [January 2023 (23.1) release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_22_7_release.htm&type=5)! Are you interested in last month’s release notes? [Read the 22.10 release notes](/salesforce-b2c-commerce-cloud-22-10/)! ## Migrate Deprecated Custom Jobs to Step-Based Jobs > Use the new migration tool to convert your deprecated custom jobs to step-based jobs. Previously, migrating deprecated custom jobs required long development times. To activate the migration tool, contact your support engineer. A tool is now available to migrate your deprecated custom jobs to the step-based system. Since this needs to be [activated by a support agent](https://documentation.b2c.commercecloud.salesforce.com/DOC3/index.jsp?topic=%2Fcom.demandware.dochelp%2Fcontent%2Fb2c_commerce%2Ftopics%2Fjobs%2Fb2c_migrate_legacy_jobs.html&cp=0_6_15_5_4), I am unable to test this tool out myself (and I have no projects that need it) Feel free to poke me on Slack with screenshots and feedback on this new tool! ## Platform ### Use a Unified URL for Your On-Demand Sandboxes > You can now access your on-demand sandboxes with a unified cluster-agnostic host name, so you no longer have to remember the cluster that your sandbox belongs to. The hostname matches the pattern -.dx.commercecloud.salesforce.com, for example, zzzz-001.dx.commercecloud.salesforce.com. It also matches the domain name of the B2C centralized admin API server, admin.dx.commercecloud.salesforce.com. A new set of URLs is introduced to make it easier to access sandboxes and not think about which cluster they are part of. For example: ```text xxxx-006.sandbox.us03.dx.commercecloud.salesforce.com ``` becomes ```text xxxx-006.dx.commercecloud.salesforce.com ``` There is already an automatic redirect in place to make this transition easier. ### Data Retention Has New Limits > To comply with Salesforce Commerce Cloud data management and regulation standards, B2C Commerce is implementing a strict 180 days data retention for code and data replications. Replications after 180 days aren’t visible in the Business Manager replications module. I don’t have much to say about this because it is a cleanup update. Making sure the platform works according to regulations, these updates are good for staying compliant. One hundred eighty days is more than enough to see what and when replication was done in the job history. ### Orders from Stored Information with Salesforce Payments > Each time an order is placed, you can reuse the payment details, payer’s stored payment credentials, or off-session tokens from a previous payment. To create an order from a previous order, use the _[SalesforcePaymentsMgr](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_extensions_payments_SalesforcePaymentsMgr.html).confirmPaymentIntent (order, paymentMethod, statementDescriptor)_ class and method from the B2C Commerce Script API. Data from the previous order is retrieved to create the order. No customer interaction is required. ## Business Manager ### Configure a Max-Age for HSTS > Add additional security to your B2C Commerce instance with the max-age for HSTS setting. Setting a max-age determines how long the HSTS settings will stay enabled.. A new option for us to configure the max-age ourselves for the [HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) setting. We could already do this in the eCDN, but now we can also do this in instances without it. ![HSTS max-age setting shown in the eCDN interface.](/salesforce-b2c-commerce-cloud-23-1/hsts-812238f9bc_hu_d819245b586c9730.webp) HSTS in the eCDN ![HSTS max-age setting shown in Business Manager.](/salesforce-b2c-commerce-cloud-23-1/hsts-business-manager-sfcc-95dbd0264e_hu_2841eeab11d519e1.webp) HSTS in the Business Manager Use with care When enabling HSTS to include subdomains, ensure that all subdomains support HSTS (also internal-only applications)! ## OCAPI & SCAPI ### Property Selector Key Error Identifier > Beginning with OCAPI Version 23.1 a MalformedSelectorException is thrown if the selector key is incorrect. Previously, the property selection didn’t work when the “select= key was incorrectly defined. For example, select%20=(price), resulted in the selector being skipped without any error message, and the normal response was returned. This a minor update that will make sure that you don’t waste hours looking in places nothing is wrong. Making a typo (in a URL) happens far too often, and a clear error message to point you in the right direction is vital. ### Basket Flash Validation Update > The property selection mechanism now works with all Shop API resources that return a basket or create an order. Previously, validation returned an error in most instances. With property selection, you can control what fields are returned by the endpoint. This saves resources and bandwidth. You can find out more about [property selection](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/PropertySelection.html) and [Basket Flash](https://documentation.b2c.commercecloud.salesforce.com/DOC3/topic/com.demandware.dochelp/OCAPI/current/usage/Flash.html) in the Info Center. ### Use Selectors with Expressions > Selectors with expressions now work correctly when objects contain a property with markup text. Previously, when an object contained a property with markup text, selectors with expressions didn’t work correctly. Also an update to the [Property Selection system](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/PropertySelection.html) to correctly handle markup in the values. ## New Ideas Some great new ideas were submitted! - [Early Hints support for B2C Commerce (Embedded CDN)](https://ideas.salesforce.com/s/idea/a0B8W00000LynV9UAJ) - [Visibility to reg price and markdown value in GMV and reports and dashboards](https://ideas.salesforce.com/s/idea/a0B8W00000LxQWAUA3) - [Audit History Business Manger](https://ideas.salesforce.com/s/idea/a0B8W00000LwUJJUA3) - [Enable Crawler Hints for embedded CDN](https://ideas.salesforce.com/s/idea/a0B8W00000LhrcuUAB) - [Adding more decimal digit on the priceBook Table and on Promo price](https://ideas.salesforce.com/s/idea/a0B8W00000LhGYsUAN) - [The Price Information Act (2004:347)](https://ideas.salesforce.com/s/idea/a0B8W00000Lh9tbUAB) ## PWA Kit v2.4.0 Another month, another update hits the PWA Kit with quite [an extensive changelog](https://github.com/SalesforceCommerceCloud/pwa-kit/compare/v2.3.0...v2.4.0). The “spotlight” change is that the new commerce-sdk-react library includes ready-made React hooks for fetching data from B2C Commerce. The full release notes are available [in the PWA Kit v2.4.0 release notes](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v2.4.0). ## Bugfixes In the update downtime for the past two months, some time was spent fixing reported issues! - [Stop word doesn’t work for ‘brand names’ when Auto-Correction Search Preference is enabled](https://trailblazer.salesforce.com/issues_view?id=a1p4V000001t2OvQAI&title=stop-word-doesn-t-work-for-brand-names-when-auto-correction-search-preference-is-enabled) - [Exporting and re-importing jobs is reseting the Failure Handling](https://trailblazer.salesforce.com/issues_view?id=a1p4V000000rUEEQA2&title=exporting-and-re-importing-jobs-is-reseting-the-failure-handling) - [Unable to import Page Designer Page for a certain locale using “ImportPageLocalization” job step](https://trailblazer.salesforce.com/issues_view?id=a1p4V000002veUvQAI&title=page-localization-should-retrieve-localeinfomation-by-id-and-avoid-indirection-via-java-locale) - [Bulk product lock gets cleaned up by orphan lock cleanup before expiration time](https://trailblazer.salesforce.com/issues_view?id=a1p4V000002as9uQAA&title=bulk-product-lock-gets-cleaned-up-by-orphan-lock-cleanup-before-expiration-time) ## Updated Cartridges & Tools ### b2c-tools (v0.14.1) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances and administrative APIs (SCAPI, ODS, etc). It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. - adding `code watch` subcommand to watch and upload cartridges by [@clavery](https://github.com/clavery) in [#93](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/93) - adds finish feature lifecycle method by [@clavery](https://github.com/clavery) in [#91](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/91) - adding oauth scopes support to environment for implicit and client\_credentials by [@clavery](https://github.com/clavery) in [#92](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/92) - adds custom preference support to instance info by [@clavery](https://github.com/clavery) in [#95](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/95) - adds `parseConfig` helper to get configuration in a headless/non-CLI environment (web, testing, other tools, etc) ### sfcc-ci (v2.10.0) - [https://github.com/SalesforceCommerceCloud/sfcc-ci](https://github.com/SalesforceCommerceCloud/sfcc-ci) > The Salesforce Commerce Cloud CLI is a command line interface (CLI) for Salesforce Commerce Cloud. It can be used to facilitate deployment and continuous integration practices using Salesforce B2C Commerce. - Various SLAS related adjustments, documentation improvement, added callbackURIs ([#318](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/318)) - Add support for limiting and expanding results of org:list ([#286](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/286)) - Expose more org level properties through org:list ([#287](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/287)) - Remove default roles assigned to newly created users ([#301](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/301)) - Add support for Sandbox API gateway ([#322](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/322)) - Fix/rewrite staging hostnames ([#324](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/324)) - Add support for resetting user ([#330](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/330)) - Enhancements for managing uses (last login date, filter users by org) ([#336](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/336)) - Various dependency updates ([#281](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/281), [#284](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/284), [#293](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/293), [#298](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/298), [#311](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/311), [#325](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/325), [#326](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/326), [#328](https://github.com/SalesforceCommerceCloud/sfcc-ci/pull/328)) --- ## The move from on-site to remote Canonical URL: https://rhino-inquisitor.com/the-move-from-on-site-to-remote/ Markdown URL: https://rhino-inquisitor.com/the-move-from-on-site-to-remote/index.md Content type: article Published: 2022-12-12T08:15:25Z Updated: 2023-01-15T08:46:26Z Summary: If anything positive came out of the whole COVID-19, then it is the move of working on-site to remote. I'm here to share my experience! Categories: Corporate Tags: ohana, personal ## Key Takeaways - Shares a personal account of the transition from office and client-site work to remote consulting - Covers the practical trade-offs around commute time, home setup, meetings, and family life during and after the COVID shift - Argues that remote work has become a durable model for productivity rather than a temporary exception Ah, yes, working remotely. The bane of many employers before 2020 and the new normal now. If anything can be said about the health crisis that has been taking the world hostage for the past years, it has drastically changed how we do things (at least in our branch of work). For me, a lot has changed during these past years too… ## Before ‘it’ all started Let’s go back a few years in time. The year is 2015, and the norm is working as a consultant at the main office or with a customer. Back then, most clients did ask for the implementation team to come sit at their main office to have close contact with the internal team and business. And to be honest, that all made sense because everyone was at the office and video conferencing only happened occasionally. My average commute was 30-40 minutes, depending on traffic; compared to others, this is peanuts. My wife has to endure 90 minutes and more to get to her client’s location on a good day. Depending on your role, that is a lot of “wasted” time. I have learned to use my commutes to have 1-1 talks with people (not much else to do except focus on the road), and yes, I use hands-free calling! Those “short” commutes did come at a price, sort of speak. I started my days at 7 AM (waking up at 6 AM), so traffic was practically non-existent on my route. This allowed me to end my workday at around 15:30, so traffic would be manageable. ### Thalia was born ![Thalia Theunen-Vanhoof](/the-move-from-on-site-to-remote/thalia-scaled-psv25226nd87xk5yw4jl2gxdwd1vdrhw7avqfqo45c-8d4884e1a0_hu_ecf2a9cb1756f1e6.webp) The arrival of Thalia marked the start of a chapter that made remote work not just a preference but a necessity. Your routine needs to change when you put a child into the world! I was mentally prepared for this, but oh boy. The first six months didn’t change much since my wife was on maternity leave, but daycare came into the picture after that. Getting to work at 7 AM wasn’t an option anymore as it only opened at 7. No problem! We’ll adapt. The impact on my commute, however, was drastic. My 30 to 40-minute drives became 60 to 70 minutes on certain days. That is a huge difference! I also got an electric car then, and by 8 AM, all chargers were usually taken. An annoyance, but not too much of an issue as I had plenty of miles left. ## Figuring it all out Then it happened, lockdown! Daycare, schools, shops, and workplaces started closing their doors by government order. In a world where remote would happen every once and a while, everyone had to work remotely. What a change in pace, and I was not prepared. My wife and I both work in IT consultancy, meaning we can work from anywhere. So, no problem. Right? It turns out that having a daughter that just learned to walk and can not be brought to daycare or grandparents can make it quite tricky. What did we do? My wife worked out a schedule where we could still work full-time while taking care of the house and our daughter, but that meant working from about 7 AM until 10 PM, alternating between who takes care of the ‘household.’ We did this for eight weeks; I still need to understand how we managed to pull this off. **NEVER AGAIN!!!!** After that, we decided to bend the rules and let the grandparents help (thank you!) Luckily [our company](https://www.forward.eu/) decided to embrace this new way of working entirely, and we got a complete set of working materials to do our thing at home: - Standing desk - Screen - Chair This made it a lot easier to organise our workspaces. ### Meetings Now, at home, my and my wife’s desks face each other. This posed no problem when I was a developer working on his code and tapping on his keyboard all day. But as a company, Forward [grew](https://www.forward.eu/career/) even during COVID-19 times. My role quickly changed from developer to technical lead to architect to Head of Commerce. And that is when something interesting happened. I went from just doing a daily standup to days full of meetings. My wife, who is in a more functional role, also had meetings all day long. Which wasn’t a problem when I didn’t have any, but now we were constantly having meetings simultaneously. To the point that people started to think that there was an extra person in the meeting. So that you know, [my wife is an SAP Consultant](https://www.linkedin.com/in/elsvanhoof/). I guess people in my sessions were learning SAP, and people in her meetings were learning about Salesforce. After a while, I moved my desk to a separate room to prevent us from disturbing each other’s meetings. It was a shame, but some of the things discussed shouldn’t be heard in other meetings (especially since we don’t work for the same company). ## The new normal: remote ![Remote-work illustration showing the shift from office life to long-term work from home.](/the-move-from-on-site-to-remote/remote-working-e716e903ff_hu_c9c47aa1ea598315.webp) What began as a temporary pandemic response became a permanent shift in how developers organise their working life. Two years later, here we are. Thoroughly accustomed to remote work. And productivity has not plummeted as some anti-remote doomsday-sayers were predicting. Even in my role, meetings are remote in 80% of the cases. And for many of them, it doesn’t even make sense to go to the office just to be locked up in a separate room all day. I can do that perfectly fine at home! I usually go to the office when I hardly have a meeting to be approachable for my team to ask questions or chat. ### Less stress in the mornings When I work from home, I get a lot more time to spend with my children (yes, during COVID, my son Thano was born) and to have breakfast at an average pace. (Though my daughter wants to break the record of slowest eater sometimes) Instead of cramming everything into an hour, I have two hours to prepare everything for school and work. Sure I have to work later than I used to, but I’m home. Woohoo! I don’t have to face rush-hour traffic! ![Portrait of Thano used in the family chapter about adapting to remote work.](/the-move-from-on-site-to-remote/thano-psv24pu9kldk5x8zu262vki7uludwrj46gur4x75jm-99e877453d_hu_159feb3ba6ebc535.webp) Skipping the commute freed up time and energy for family mornings — one of the unexpected wins of working remotely. Obligatory proud-parent photo required ## The future of remote work But now that COVID-19 lockdowns and regulations are being removed, companies appear to be pushing to go to the office again. Luckily for me, that isn’t the case, and we can decide for ourselves! But it is a consultancy firm; if a customer asks to work at the office, there is not much we can do against that except to put on the negotiation glasses. It’s hard to say where this will go, but remote work is here to stay. And that is a good thing! We have all the proof now that working from home does not negatively impact productivity; for many people, it has increased productivity a lot! **Side note:** [Events are back!](/community-salesforce-events-and-commerce-cloud/) Wooohooo! --- ## Podcasts about Salesforce B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/podcasts-for-salesforce-b2c-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/podcasts-for-salesforce-b2c-commerce-cloud/index.md Content type: article Published: 2022-12-05T16:08:12Z Updated: 2022-12-08T12:44:02Z Summary: There are many Salesforce-related podcasts available on the web, but which of those are interesting to follow as an SFCC enthusiast. Categories: Community Tags: ohana, podcast, sfcc ## Key Takeaways - Curates podcasts that are useful for staying connected to the SFCC and broader Salesforce ecosystem - Highlights which shows are directly commerce-focused versus generally useful for developers, community members, or leaders - Gives newcomers a practical listening list for both technical insight and ecosystem awareness Over the years, a lot of podcasts have popped up around Salesforce. And amongst these, they organise quite a few themselves. The [ecosystem has grown significantly over the years](/the-state-of-ohana-for-salesforce-commerce-cloud/), and some podcasts have chosen to target a specific portion of the community. But which ones are interesting to listen to as a Salesforce B2C Commerce Cloud enthusiast? ## Unofficial SFCC - [https://unofficialsfccpodcast.com/](https://unofficialsfccpodcast.com/) - [Oleg Sapishchuk](https://osapishchuk.medium.com/) - [Peter Schmalfeldt](https://peterschmalfeldt.com/) > Welcome to the Unofficial Salesforce Commerce Cloud Podcast. We created this Podcast to give everyone access to each other to share ideas and help one another. It also offers members a place to discuss, listen and watch Salesforce B2C Commerce Cloud in a free and open environment. We can only start the list of podcasts by putting the Unofficial SFCC podcast at the top! It is the only one primarily focused on Salesforce B2C Commerce Cloud. Various topics are discussed, going from development to recruitment within the ecosystem. **Note:** It has been a while since a new episode was released. Hopefully, new episodes are in the making! ## Salesforce Commerce Cloud Innovations - [https://podcasts.apple.com/ca/podcast/salesforce-commerce-cloud-innovations/id1654981816](https://podcasts.apple.com/ca/podcast/salesforce-commerce-cloud-innovations/id1654981816) - [Natalija Pavic](https://www.linkedin.com/in/natpavic/) > What if you could hang out with eCommerce experts at Salesforce, as well as our customers and partners, ask them about their experiences and be inspired by innovative ideas and live use cases; then take an insight or two to guide your own Commerce Cloud journey? Hosted by Natalija Pavic ––Innovation Leader on the Business Strategy & Growth team at Salesforce Commerce Cloud. –– every episode is a deep dive into topics that will impact your digital business from new trends like metaverse and NFTs to the evolution of the online customer experience and its impact. We hope to expand your mind with solutions available today and explore their impact on the future. Our goal is to give inspire you with ideas, solutions, and visions of the future in eCommerce. A new podcast on the block about innovations in and around Commerce! ## Developers Podcast - [https://developer.salesforce.com/podcast](https://developer.salesforce.com/podcast) - [Josh Birk](https://twitter.com/joshbirk) > Tune in to the Salesforce Developer Podcast to hear short and insightful stories for developers, from developers. Join Joshua Birk, Developer Evangelist and Godfather of Trailhead, as he hosts developer trailblazers from around the world as they share their stories of learning, building and integrating with Salesforce. This is the biggest podcast that targets all Salesforce Developers within the ecosystem (but still mainly the Salesforce CRM, as most of the products run on it). But every once and a while, a Salesforce B2C Commerce Cloud-related episode comes around: - [105: B2C Digital Trends with Natalija Pavic](https://podcasts.google.com/feed/aHR0cHM6Ly9zYWxlc2ZvcmNlZGV2cG9kY2FzdC5saWJzeW4uY29tL3Jzcw/episode/ZDE0NGE5ZGQtZjYzNi00MzM2LWJjMWQtNWRkMThhMjJkNzVl?sa=X&ved=0CAUQkfYCahcKEwjgu4SO-Mz3AhUAAAAAHQAAAAAQAQ) - [069: B2C Commerce Development with Andrew Lawrence](https://podcasts.google.com/feed/aHR0cHM6Ly9zYWxlc2ZvcmNlZGV2cG9kY2FzdC5saWJzeW4uY29tL3Jzcw/episode/MGI5OWUwYTQtMDkwOS00NjdhLWI3ZGEtMGMwZTU4NzVkYTVj?sa=X&ved=0CAUQkfYCahcKEwjgu4SO-Mz3AhUAAAAAHQAAAAAQAQ) In the future, we hope to see more than two episodes a year pop up here as well about B2C Commerce Cloud and its related products, such as [OCI](https://help.salesforce.com/s/articleView?id=release-notes.rn_inv_omnichannel_inventory.htm&language=en_US&r=https%3A%2F%2Fwww.google.com%2F&release=230&type=5) (Omnichannel Inventory) and Salesforce [OMS](https://help.salesforce.com/s/articleView?id=sf.om_order_management.htm&language=en_US&r=https%3A%2F%2Fwww.google.com%2F&type=5) (Order Management). ## Up Next In Commerce - [https://mission.org/up-next-in-commerce/](https://mission.org/up-next-in-commerce/) - [Stephanie Postles](https://www.linkedin.com/in/stephaniepostles/) > Join host Stephanie Postles as she sits down with eCommerce leaders on the front lines of digital innovation. With guests from established enterprise companies to D2C start-ups barely out of infancy to everyone in between - you’ll get the inside scoop on what’s Up Next in Commerce. New episodes release every Tuesday and Thursday. Don’t want to go too technical and get inspired by entrepreneurs in the Commerce space? Then this is the podcast for you! Listen to inspiring talks about the ever-changing world of doing business on- and offline. ## Syntax - [https://syntax.fm/](https://syntax.fm/) - [Wes Bos](https://twitter.com/wesbos) - [Scott Tolinski](https://twitter.com/stolinski) > Full Stack Developers Wes Bos and Scott Tolinski dive deep into web development topics, explaining how they work and talking about their own experiences. They cover from JavaScript frameworks like React, to the latest advancements in CSS to simplifying web tooling. Leaving the world of Salesforce-related podcasts, this one deserves mentioning. Especially with the addition of the Composable Storefront, I feel this web development podcast (that focuses on React.js) has become more relevant. It is a fun-to-listen-to development podcast that keeps you up to date with full-stack web development. ## Complete this list Do you feel like a vital podcast is missing from this list? Let me know via [Slack](http://sfcc-unofficial.slack.com), [X](https://x.com/theunenth), [Trailhead](https://trailblazer.me/id/thomas-theunen) or [LinkedIn](https://www.linkedin.com/in/thomas-theunen-10905680/)! ## Other Salesforce podcasts Some podcasts are also available in the ecosystem that are more “general.” These podcasts usually handle the broad ecosystem or trailblazing across the world. ### Life With Goldie - [https://lifewithgoldiepodcast.buzzsprout.com/](https://lifewithgoldiepodcast.buzzsprout.com/) - [Mia Pacey](https://twitter.com/PaceyMia) > Mia Pacey interviews the Trailblazer Golden Hoodie recipients to uncover their unique journey in the Salesforce ecosystem. How did they enter the ecosystem? What is it like to own the most sought after item of swag (the golden hoodie)? Let’s spotlight these amazing Trailblazers and see what nuggets of wisdom we get shining back. I was recently interviewed on this podcast as the “first” Salesforce B2C Commerce Cloud golden hoodie where I could tell my story. This podcast will tell you the unique stories of these Trailblazers, which can spark some ideas! ### Mums on Cloud Nine - [https://supermums.org/mums-on-cloud-nine-podcast/](https://supermums.org/mums-on-cloud-nine-podcast/) - [Heather Black](https://www.linkedin.com/in/heather-black-salesforce-women-in-tech-speaker/) > Mums on Cloud Nine aims to inspire mums to progress their careers in tech from starting to climbing the career ladder. We provide tips and insight on how to succeed in your career and overcome adversity many women can face in the workplace. Mums on Cloud Nine hopes to inspire mothers in the workplace by interviewing moms excelling in their careers to share their inspiring stories! ### Inside the Ohana - [https://www.qualified.com/plus-series/inside-the-ohana](https://www.qualified.com/plus-series/inside-the-ohana) - [Dan Darcy](https://www.linkedin.com/in/dandarcy/) > Salesforce legend and veteran, Dan Darcy, takes us to the tops of Salesforce Towers across the globe, chatting with Trailblazers, Salesforce execs, employees, partners, and more. The Trailblazer economy is booming, hear the best lessons learned from the greatest in the industry. This podcast also focuses more on the people and less on the product. You will hear the stories of people from the Trailblazing community (in and outside Salesforce) and the values they find essential in their careers and communities. --- ## Salesforce B2C Commerce Cloud November 2022 Updates Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-november-2022-updates/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-november-2022-updates/index.md Content type: article Published: 2022-11-28T18:36:33Z Updated: 2022-11-29T10:33:29Z Summary: A closer look at the November 2022 B2C Commerce Cloud updates, including cartridge releases, tooling changes, and SCAPI work. Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc ## Key Takeaways - Summarizes the notable November 2022 updates outside the normal holiday release cycle - Highlights the PWA Kit, Account Manager, and plugin_slas changes most relevant to active storefront teams - Calls out bug fixes, new ideas, and cartridge releases worth tracking during the slower release period It is a slow period in B2C Commerce Cloud update land as no significant [releases](/category/release-notes/) happen during the holiday period. But updates still occur in other places! In this article, I consolidate all the updates I have found across the different areas encompassing Salesforce B2C Commerce Cloud. ## SFRA v6.3.0 A [maintenance release](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/releases/tag/v6.3.0) has happened with no more than updated dependencies. So nothing too exciting to mention here! This usually means plugin cartridges (such as wishlist) have received updates, and the SFRA version has been “upped” to match. In this case, it was a major update to [plugin\_slas](https://github.com/SalesforceCommerceCloud/plugin_slas/releases/tag/v6.3.0). ## PWA Kit v2.3.0 As expected, another big update hit the PWA Kit with quite [an extensive changelog](https://github.com/SalesforceCommerceCloud/pwa-kit/compare/v2.2.0...v2.3.0). The “spotlight” change is the added [React Query](https://tanstack.com/query/v4/docs/overview) support for the server side. Some other noteworthy changes (besides bugfixes): - [New Einstein API activities](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/714) - [Updated the demo ODS instance URL](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/799) - [Performance improvement on the Managed Runtime](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/720) An [upgrade guide](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/upgrade-to-v2-3.html) is available if you are already working with the PWA Kit and need to update to this version. ## Bugfixes Even though there are no “big releases”, bugfix releases still happen in this period. - [basket.reserveInventory on Product Bundle fails with NPE when parent bundle item has null inventory record](https://trailblazer.salesforce.com/issues_view?id=a1p4V00000219j2QAA&title=basket-reserveinventory-on-product-bundle-fails-with-npe-when-parent-bundle-item-has-null-inventory-record) ## Account Manager The Account Manager got some love again at the end of October (after my [last release notes post](/salesforce-b2c-commerce-cloud-october-updates/)). - Security Fixes - Bug Fixes - Usability Improvements to the API Client List Page - **[Updated API Client List Page](https://help.salesforce.com/s/articleView?id=sf.b2c_rn_am_api_client_list_page_je.htm&type=5&language=en_US)** With the addition of two new columns and filters, the Account Manager API Client List page is now easier to use. ## New Ideas Some new ideas made their way to the IdeaExchange! - [The addCertificateForZone endpoint needs better error messaging.](https://ideas.salesforce.com/s/idea/a0B8W00000LfJTJUA3) - [Improved CMS where Content Library can be exported separately from code changes](https://ideas.salesforce.com/s/idea/a0B8W00000LgTXBUA3) - [Request for implementation of personalization features in PWA Kit](https://ideas.salesforce.com/s/idea/a0B8W00000LfMwKUAV) - [Salesforce Payments: Paypal : Supports only combined auth and capture](https://ideas.salesforce.com/s/idea/a0B8W00000LgsQDUAZ) ## Updated Cartridges & Tools ### Adyen (v22.2.1) - [https://github.com/SalesforceCommerceCloud/link\_adyen](https://github.com/SalesforceCommerceCloud/link_adyen) > Adyen provides a LINK cartridge to integrate with Salesforce Commerce Cloud (SFCC). This cartridge enables a SFCC storefront to use the Adyen payment service. This cartridge supports SFRA version 5.x.x & 6.x.x and SiteGenesis JS-Controllers version 103.1.11 and higher. ### New - Support for the new India live environment. Use this environment with the corresponding India location-based live endpoint. - A custom [Business Manager configuration page](https://docs.adyen.com/plugins/salesforce-commerce-cloud/set-up-the-cartridge#set-up-the-business-manager). - New supported payment method: [UPI](https://docs.adyen.com/payment-methods/upi). ### Improved - The cartridge now uses [Web Components v5.28.0](https://docs.adyen.com/online-payments/release-notes#releaseNote=2022-10-10-web-componentsdrop-in-5.28.0) and [Checkout API v69](https://docs.adyen.com/online-payments/release-notes?integration_type=api&version=69). - You can now persist gift card information in the payment form after the shopper has filled in the gift card information. ### Mollie (v22.3.0) - [https://github.com/SalesforceCommerceCloud/link\_mollie](https://github.com/SalesforceCommerceCloud/link_mollie) > This is the integration cartridge for Mollie - Fixed some ApplePaySession errors in non-safari browsers - Fixed order locking issue. Only update supported hook order status via hook, handle the rest of the statuses on redirect. ### plugin\_slas (v6.3.0) - [https://github.com/SalesforceCommerceCloud/plugin\_slas](https://github.com/SalesforceCommerceCloud/plugin_slas) > The plugin\_slas cartridge extends authentication for guest users and registered shoppers using the Shopper Login and API Access Service (SLAS). - fix cart merge error due to session bridge failing when client IP header name is not set by [@sandragolden](https://github.com/sandragolden) in [#53](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/53) - issue [#41](https://github.com/SalesforceCommerceCloud/plugin_slas/issues/41) : restore session custom attributes after session bridge by [@sandragolden](https://github.com/sandragolden) in [#54](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/54) - Add support for ECOM 18.10 by [@vcua-mobify](https://github.com/vcua-mobify) in [#59](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/59) - Document allow listing POD IP address by [@johnboxall](https://github.com/johnboxall) in [#63](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/63) - Fix SLAS Logout issue by [@shethj](https://github.com/shethj) in [#64](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/64) - Run login flows only if request method is ‘GET’ by [@shethj](https://github.com/shethj) in [#69](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/69) - Fix refresh\_token value undefined in browser cookies by [@shethj](https://github.com/shethj) in [#70](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/70) - Fix merge basket call returns 409 Conflict error if guest user has no basket by [@shethj](https://github.com/shethj) in [#66](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/66) - Release/v6.3.0 by [@shethj](https://github.com/shethj) in [#71](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/71) - Enforce `prettier` in CI by [@johnboxall](https://github.com/johnboxall) in [#67](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/67) ### b2c-tools (v0.13.3) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances. It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. The changelog is visible [in the b2c-tools v0.13.2 to v0.13.3 comparison](https://github.com/SalesforceCommerceCloud/b2c-tools/compare/v0.13.2...v0.13.3). --- ## Is Salesforce Certification worth it? Canonical URL: https://rhino-inquisitor.com/is-salesforce-certification-worth-it/ Markdown URL: https://rhino-inquisitor.com/is-salesforce-certification-worth-it/index.md Content type: article Published: 2022-11-21T10:17:21Z Updated: 2023-02-15T20:40:06Z Summary: You want to get certified but are still determining if this will benefit you or not within the Salesforce ecosystem. Let's dig into that! Categories: Certification Tags: ohana, trailhead ## Key Takeaways - Argues Salesforce certifications are worthwhile when used as a guide for learning and validation - Explains how certifications benefit individuals, partners, Salesforce, and customers differently - Warns that certifications do not replace project experience and can be undermined by easy exams or cheating A common question within Salesforce (and other ecosystems) is the value of being a [certified professional](/certifications-for-salesforce-b2c-commerce-cloud/). To get certified, you need to spend a substantial amount of time to prepare in some cases (I’m looking at you, the [Certified Technical Architects](https://www.salesforceben.com/become-a-salesforce-certified-technical-architect/) 😁.) And it isn’t exactly free. Each attempt will set you back a few hundred dollars. In some cases, even a few thousand. I’m looking at you again, the CTA’s. So it is understandable that new people to the ecosystem want to understand why they should make the investment (or the employer). ## Is it worth it Let’s get this question out of the way as soon as possible. Yes, it is. But why is it worth your effort and time? Let’s look at a few benefits! ### You can verify your expertise Certifications (and Accreditations) can verify that your knowledge is on par with the “standards.” Even though you might have already done a project or two, there might be a few areas you have not touched yet. Each certification has a preparation guide to show you the content you should master. It should be easy to pinpoint the areas you must work on to pass the exam. And filling those gaps in your knowledge will help you on your next project! ### Get to know the platform Let’s turn that previous topic upside down. Maybe you still need project experience, but you have one in a few weeks/months. You want to be prepared! But where to start? A certification could be a good guideline for getting to know the platform, features, and capabilities. And it is always nice that you can take the exam at the end of the road, which will verify if you understand the concepts you have been learning about in the past weeks and months. ## Does it benefit someone else ![Illustration emphasizing the wider benefits of certification.](/is-salesforce-certification-worth-it/benefit-a5b0552ef8_hu_fb10fa596feeafea.webp) Certification gains value not just for you, but for recruiters, clients, and teammates who rely on verified expertise. ### Partners If you work for an ISV (Independent Software Vendor) or SI (System Integrator), they benefit from getting you certified. Salesforce uses information such as Trailhead Badges, Partner Learning Camp Accreditations, and Certifications to weigh a partner’s capabilities. The more Certified Professionals a partner has, the more Salesforce will pitch the company to potential clients (co-selling). A second benefit is a part of the “[Consulting Partner Program](https://partners.salesforce.com/pdx/s/learn/article/salesforce-consulting-partner-program-overview-MCBZXIAMZFV5EOFLJNPZ4SZOJHNY).” You may know that there is a rewards/tiers program (Base, Ridge, Crest, and Summit), and you need to collect points to rise to the top of that mountain. One of the ways to earn points is the “Innovation” section, where you get points for, you guessed it, credentials (certifications). So for a partner to grow in tiers, a certain amount of certificates will help them get there! Some certifications will give more points than others: A good example is that Architect certificates give ten points, while an Administrator certificate only awards one. ### Salesforce It shouldn’t surprise you that Salesforce themselves benefit from providing certifications! They benefit most from this system, but let me tell you why. 1. **It is an excellent way to see and grow partner expertise:** The eco-system becomes more prominent every year, and more and more companies join the fray. Salesforce needs measurement tools to pick the best partner for each client to pitch. Certifications are an excellent way to be pointed in the right direction (but it is only some of it)! 2. **It benefits Salesforce customers:** Having Certified Professionals ensures they have the knowledge to help customers with their challenges and needs. You can’t just let anyone do an implementation, which might end in disaster if they do not have the required knowledge in-house! 3. **It is a steady income:** Salesforce invests in creating these certifications, but there is an ROI because so many people take them (and the trainings to prepare). ### Salesforce Customers Companies put their trust in you to do an exemplary implementation of Salesforce. One way for them to see that you have the required knowledge (and the easiest) is to look at your credentials. It is always nicer to know that your project is being implemented by a team of Certified Developers and Administrators than a team with no prior experience or certifications. But does that mean that they know what they are doing? Certifications will never match experience, but that is a topic I will touch upon later! ## You want to land your first job This one is a bit controversial since you have to spend money to get a job to earn money. And this is not possible for everyone! So do you need a certification to land a job in Salesforce? Absolutely not! ![Simon Sinek quote about hiring for attitude rather than only skills.](/is-salesforce-certification-worth-it/you-dont-hire-for-skills-you-hire-for-attitude-you-0d3739fc5c_hu_1aa872a422080bd1.webp) Attitude often matters more than raw credentials — certifications prove commitment, not just knowledge. Unfortunately, not everyone hires with the mindset of this quote by [Simon Sinek](https://simonsinek.com/). I hire for my team at [Forward](https://www.forward.eu) and have hired many people with no certifications or experience in the Salesforce ecosystem. If you are willing to invest, the certifications on your resume will put you higher up in the resume pile - above the people without them (on the same experience level). ## The harsh reality You just hired your first Certified Professional, with five certifications in all the areas you need expertise in! You feel great and have confidence that this person will resolve all your challenges in the coming months. Three months pass, and your challenges are looking more like forest fires. How is this happening? You hired a pro, right? ### Certifications ≠ experience No matter how well you understand the theory and exercises on Trailhead, they will never match the [complexity of a real-life project](/category/go-live/). Doing projects in a team and learning from your more experienced peers will give you more knowledge than preparing for a certification ever will. You will hit “walls” in projects that need inventive ways around (or demolish) that you will not experience in Trailhead modules or superbadges. On the [latest episode](https://developer.salesforce.com/podcast/2022/11/episode-150-b2c-and-b2b-solution-architecture-with-shoby-abdi) of the Salesforce Developer Podcast, I heard a few sentences that resonated: > An MQC is what’s called a **minimally-qualified** candidate. This is an individual who with at least some preparation, some experience, can they take this exam and pass it. The reason behind that minimally-qualified candidate, once again, it’s the words, “Minimally-qualified.” Do they have just enough to make it real? Shoby Abdi With just the certificate pass, you will have just enough (minimally qualified) knowledge to get projects up and running. Still, there is **a lot of room to grow** in experience - and this experience will consist of challenges you might run into and how to resolve them in the best possible way! If you are put on a complex project without prior experience, ensure you have someone who has your back when \*\*\*\* hits the fan! You might worsen things and wall yourself in if you are alone without expert help. ### Cheating ![Illustration introducing the harsher realities behind certifications.](/is-salesforce-certification-worth-it/reality-is-a-harsh-mistress-f67c988867_hu_3f44e851a6401d28.webp) Certifications have a darker side: exam dumps and brain dumps undermine their signal of real competence. Unfortunately, we live in a world where not everyone makes an effort to get certified correctly. There are many ways to cheat on certifications: - **Exam Dumps:** People buy actual exams with questions and answers and study that instead. You are not learning anything by doing this. - **Have someone else take the exam:** This is something relatively new I saw pop up on Twitter. People are getting messages from companies who offer to take the exam for you with a 100% promise of passing. You won’t learn anything at all by going this route. Plus, you will be paying for the exam and the service. ### Some certifications are just too easy I have accumulated five certifications and ten accreditations in the past five years. Some of these are relatively easy to pass. One (I won’t say which) took me about 4 hours of preparation to part with a score of 100%. But I was in a summer competition hosted by Salesforce, and whoever got the most certifications would win a prize. This caused me to look for easy wins (I never cheated!) to get up in the rankings. Does that mean I am a subject matter expert in that area? Most definitely not! What does this prove? That I can study well. But I did learn a lot from this competition. I learned about specific features in more detail and about platforms I had never touched before within the Salesforce ecosystem (Yup, I’m talking about you, [Net Zero Cloud](https://www.salesforce.com/products/net-zero-cloud/overview/)). ## Conclusion I mentioned this initially, but getting certified is worth it if you use it as intended. As long as you don’t think being certified puts you on an equal plane (or above) to those with project experience (but no certifications), you should be fine! --- ## Change Code Compatibility Mode in SFCC Canonical URL: https://rhino-inquisitor.com/how-to-change-the-code-compatibility-mode-in-salesforce-b2c-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/how-to-change-the-code-compatibility-mode-in-salesforce-b2c-commerce-cloud/index.md Content type: article Published: 2022-11-14T08:04:44Z Updated: 2022-11-19T09:06:30Z Summary: Understand how to change code compatibility mode in SFCC, when a rollback matters, and what to check before switching versions. Categories: Salesforce Commerce Cloud, Technical Tags: sfcc, technical ## Key Takeaways - Explains what SFCC code compatibility mode controls and why upgrades can break custom code - Shows the WebDAV .apiversion workaround for aligning sandbox compatibility versions - Warns that rolling compatibility backward should be rare and limited to valid supported modes “How do I update my Compatibility mode to vxx.xx?” This is a question that many have asked over the years, especially with the On-Demand Sandboxes taking the last compatibility mode by default - not providing a way to go back. So what now? How do you keep your sandboxes all on the same version if some are on an older one? ## What is this “Compatibility Mode”? The easiest way to explain this is by linking the Compatibility Mode to the engine that runs between us (the developers) and the Java engine that runs Salesforce B2C Commerce Cloud. Commerce Cloud uses an engine based on [Apache Rhino](https://en.wikipedia.org/wiki/Rhino_%5c%28JavaScript_engine%5c%29), which translates JavaScript to Java. And this engine has versioned releases, each providing new features to keep up with the JavaScript standards (or at least as much as possible). ### Forced upgrades are dangerous Updating the engine can cause some functions that worked in the previous release to break down. The engineering team can only force this new version on us if they give us the time to update the custom code to be compatible with the latest version. And that is where the choice of “Compatibility Mode” comes in. We can decide for ourselves when to make a move to this new engine ([and make use of the new toys that come with it](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_development/b2c_compatibility_mode_considerations.html)) ## The only way is up? As with all features baked into the Business Manager, Salesforce decides which modes you can use in the interface. And in most cases, the only way is up. ## Can we “downgrade”? If the interface only allows us to upgrade, it is time to find ways to work around that “security”! ![Hacker-style illustration introducing code compatibility mode workarounds.](/how-to-change-the-code-compatibility-mode-in-salesforce-b2c-commerce-cloud/hackerman-hr-6b82b63667_hu_cf045d754778e6cc.webp) If the UI only supports upgrades, you need a workaround rather than the normal path. ### Manipulate the form? The first weapon we have is our browser console! Can we manipulate the HTML form and add the version we want? ![Browser DevTools inspecting the compatibility mode form in Business Manager.](/how-to-change-the-code-compatibility-mode-in-salesforce-b2c-commerce-cloud/manipulate-form-code-compatibility-1d501b0279_hu_d3cbb6689981134b.webp) The browser console is the quickest way to test whether the form can be bent. As it turns out… no. There is server-side validation in place. So we need to find another way to hack the system! ### To the WebDAV Let us next see if we can do anything in the WebDAV to manipulate the Compatibility Mode. (**Spoiler**: We can) To retrieve the URL for the WebDAV go to: _“Administration > Site Development > Development Setup”_ ![Business Manager Development Setup screen showing the WebDAV URL.](/how-to-change-the-code-compatibility-mode-in-salesforce-b2c-commerce-cloud/cartridges-webdav-88a388e63c_hu_49d54f1ae8476d88.webp) The WebDAV URL in Development Setup is the doorway to the manual workaround. DWithEase I use the browser plugin [DWithEase](https://dwithease.com/) to make WebDAV browsing much more pleasant. If you open the URL (and have the browser plugin installed), you will get a view such as this: ![WebDAV directory listing for the cartridge folders in a code version.](/how-to-change-the-code-compatibility-mode-in-salesforce-b2c-commerce-cloud/webdav-overview-38949e23ef_hu_744bfb0c0a8cb076.webp) Once inside WebDAV, you can inspect the code version directly instead of using the UI. Click on the **active** Code Version (this is important)! Go into the folder, and a file called “.apiversion” will be there. ![WebDAV folder showing the .apiversion file in the active code version.](/how-to-change-the-code-compatibility-mode-in-salesforce-b2c-commerce-cloud/code-version-26171e5278_hu_4d3eddccbe4f37ad.webp) The hidden .apiversion file is the small detail that makes the workaround possible. Missing File If you do not see the file, don’t worry! You can upload it yourself to the folder. Inside that file is where the “magic” happens, and it looks something like this: ```properties #DO NOT EDIT! This is the api version with which *this* code version is compatible. It is managed by the system. #Tue Aug 01 09:55:45 GMT 2017 api.version=21.7 ``` This file has an interesting key, specifically “api.version”! You can change that to the version you want to use for your sandbox by downloading it, editing it, and re-uploading it to the same folder. In this case, we will update it to “18.10” ```properties #DO NOT EDIT! This is the api version with which *this* code version is compatible. It is managed by the system. #Tue Aug 01 09:55:45 GMT 2017 api.version=18.10 ``` Let us head back to the business manager and go to the “Manage Code Versions” screen: _“Administration > Site Development > Code Deployment”_ If all has gone well, the code versions have changed to the one in the file! ![Manage Code Versions screen reflecting the updated compatibility mode.](/how-to-change-the-code-compatibility-mode-in-salesforce-b2c-commerce-cloud/new-code-version-d4f4f68888_hu_62c2bebd70a2a39c.webp) If the edit worked, the new compatibility mode shows up back in Code Versions. Not visible If no changes are visible, try switching active code versions to trigger the system to re-read the WebDAV files. ## Dangerous? It depends. Only do this if you have to. In most cases, this is done on older projects already tested on that older Compatibility Mode, and you need to match it. Please do not go back too far; it is in everyone’s best interest to be on the latest and greatest version of the [Rhino Engine](https://github.com/mozilla/rhino)! But developers worldwide have done this many times without any drawbacks! **Just make sure you configure a Compatibility Mode that exists**! --- ## How to set up the eCDN for Staging in Salesforce B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/how-to-set-up-the-ecdn-in-sfcc-staging/ Markdown URL: https://rhino-inquisitor.com/how-to-set-up-the-ecdn-in-sfcc-staging/index.md Content type: article Published: 2022-11-07T10:29:05Z Updated: 2024-10-14T16:50:08Z Summary: New APIs have been made available to manage certificates on the staging eCDN ourselves. But how does it work? What do I need to keep in mind? Categories: Salesforce Commerce Cloud, Technical Tags: headless, scapi, sfcc, technical ## Key Takeaways - Documents the legacy API-first path for configuring staging eCDN zones, certificates, and DNS in SFCC - Explains the sequence from API client setup through zone creation, certificate upload, and hostname verification - Flags that the approach is now deprecated because staging vanity domains can be managed in Business Manager > **Deprecated article:** Since the writing of this article, the eCDN Business Manager module has been updated to allow configuration of vanity domains on staging. Therefore, there is no need to use API calls as described in this article unless you really, really want to. Read all about it [in the staging eCDN Business Manager release note](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_configure_ecdn_for_staging_in_bm.htm&type=5). Using the [Business Manager module](/lets-go-live-ecdn/), setting up custom vanity domains and uploading certificates on the production instance is easy. But how about staging? Until recently, we needed to contact support to set up custom vanity domains with a valid certificate on the staging instances. Luckily that has changed, and now we can fully control the domains and certificates for staging “just like production”. Yes, it has been put between quotes. Let us find out why! ## API First In an API-first manner, REST APIs are available to manage the eCDN (Cloudflare) for all our environments. But unlike production, there is yet to be a Business Manager module available to do this on staging. ## Step 1: Create an API Client To connect to the SCAPI, we need to create an API client with the correct scopes: - sfcc.cdn-zones - sfcc.cdn-zones.rw Salesforce [has written a guide](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=Summary#before-you-begin) on the developer support site to create an API Client for this use case. **tenantID:** The tenantID mentioned in the guide is the Realm ID (zzxx) combined with the Instance ID (001). This information is shown in the next step of this guide on the staging instance. e.g. **zzxx\_001**. Remember to assign the Salesforce Commerce API role to the API Client. [![Account Manager roles screen with the Salesforce Commerce API role enabled for staging.](/how-to-set-up-the-ecdn-in-sfcc-staging/commerce-cloud-api-client-roles-1a338d1f61_hu_fdf63aad898dc9eb.webp)](commerce-cloud-api-client-roles-1a338d1f61.jpg) API client roles for staging eCDN ## Step 2: Get the staging credentials Since the “CDN Zones” API is part of the SCAPI, we need to get our environment-specific credentials from the business manager. In this case, that is our Staging instance. We get these settings here: “Administration > Site Development > Salesforce Commerce API Settings” [![Salesforce Commerce API Settings screen with the short code and organization ID for staging.](/how-to-set-up-the-ecdn-in-sfcc-staging/salesforce-commerce-api-settings-be8d59fe5b_hu_b49bfe8236edb47c.webp)](salesforce-commerce-api-settings-be8d59fe5b.jpg) Staging Commerce API settings ## Step 3: Get an access token To communicate with the [Zones API](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=Summary), we need a bearer token. This is fetched using the following API call to the Account Manager **tenantID:** The tenantID combines the Realm ID and the Instance ID with an underscore (e.g. **zzxx\_001**). ```bash curl -i -k \ --data 'grant_type=client_credentials&scope=SALESFORCE_COMMERCE_API:<tenantID> sfcc.cdn-zones sfcc.cdn-zones.rw' \ --user '<client-id>:<client-secret>' \ -X POST 'https://account.demandware.com/dwsso/oauth2/access_token' ``` If all goes well, a response similar to the one below appears. ```json { "access_token": "<bearer-token-truncated-for-readability>", "scope": "SALESFORCE_COMMERCE_API:zzxx_001 sfcc.cdn-zones sfcc.cdn-zones.rw", "token_type": "Bearer", "expires_in": 1799 } ``` ## Step 4: Get all zones First, check that we can use our newly fetched “access\_token” to call the Zones API. This information can be obtained by making a GET call to the “[Get zones info](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=getZonesInfo)” endpoint. shortCode and organizationId The shortCode and organizationId in the URL below are obtained in step 2. ```text https://{shortCode}.api.commercecloud.salesforce.com/cdn/zones/v1/organizations/{organizationId}/zones/info ``` If all the steps have been adhered to above, a response like the one below will magically appear! ```json [{ "zoneId": "example1-zone-Id", "name": "example1.com", "status": "pending" }] ``` ## Step 5: Create a zone (register domain) Now that it is confirmed that API calls can be made, the first step in creating a custom domain for the Staging environment can be done: “Creating a zone in Cloudflare”. To achieve this, the following API call must be made to the “[Create storefront zone](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=createStorefrontZone)” endpoint: Top-level domain In this step, the top-level domain is used even if you plan to use a subdomain for Staging. e.g. To use “stg.cc-merchant.com”, “cc-merchant.com” is submitted in the request of this step. ```bash curl "https://{shortCode}.api.commercecloud.salesforce.com/cdn/zones/v1/organizations/{organizationId}/storefront-zones" \ -X POST \ -d "{\n \"domainName\": \"cc-merchant.com\"\n}" ``` If the zone did not exist already and is created successfully, the following response is given: ```json { "data": { "zoneId": "023e105f4ecef8ad9ca31a8372d0c353", "zoneName": "stg-zzzz-cc-merchant-com.cc-ecdn.net", "createdOn": "2022-01-01T05:20:00.12345Z", "status": "active" } } ``` Status The status could also be “pending”. Give Cloudflare a bit of time to process your request. It is always possible to do the GET call in step 3 to keep an eye on it. ## Step 6: Upload the certificate Certificate and Private Key Before starting this step, please ensure you have acquired the certificate and private key. These are TXT files that the person who purchased the certificate has. Finally, we get to the “goal”: Uploading the certificate. To do that, an API call is made to the “[Add certificate for zone](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=addCertificateForZone)” endpoint. ```text https://{shortCode}.api.commercecloud.salesforce.com/cdn/zones/v1/organizations/{organizationId}/zones/{zoneId}/certificates ``` This is a POST call with the following body: ```json { "hostname": "cc-merchant.com", "certificate": "<escaped-certificate-pem>", "privateKey": "<escaped-private-key-pem>" } ``` When the request succeeds, and the certificate is checked to be valid, the information needed for the next step is in the response. ```json { "certificateId": "3822ff90-ea29-44df-9e55-21300bb9419b", "status": "EXPIRED", "hosts": [ "example.com", "www.example.com" ], "expiresOn": "2021-01-01T05:20:00Z", "uploadedOn": "2016-01-01T05:20:00Z", "issuer": "DigiCert", "signature": "SHA256WithRSA", "customHostnameVerificationTXTName": "_example.com", "customHostnameVerificationTXTValue": "4c9c3f4f-2e91-4c5d-a902-f12f9c285b9e", "customHostnameId": "354a48f6-3d98-4c15-9312-211984ee8518", "customHostname": "cc-merchant.com", "customHostnameStatus": "PENDING" } ``` Status Notice that the customHostnameStatus is “PENDING”. ### Encoding the certificate and key Since JSON is used, the body of our request needs to be safe to use in that manner. Certificates and Private Keys tend to have several new line characters incompatible with JSON. These need to be “escaped”. Luckily, many online [tools](https://www.freeformatter.com/json-escape.html) can help you with this chore. > **Security:** Don’t trust just any tool online with this data. The private key is sensitive information. ## Step 7: Validate ownership of the domain For this step, we need the person who manages the DNS records of the domain in question. To prove we own this domain to Cloudflare, a txt record must be added to its configuration. The data of this TXT record was in the response of the previous step: ```text { ... "customHostnameVerificationTXTName": "_example.com", "customHostnameVerificationTXTValue": "4c9c3f4f-2e91-4c5d-a902-f12f9c285b9e", ... } ``` Once this record is added, the “[Get certificates](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=getCertificates)” endpoint is available to track the status. As soon as it changes to “ACTIVE”, you can go to the next step! ## Step 8: Update the DNS records The final step is to set the CNAME record in the DNS for the domain. This is the combination of “commcloud.`<zone\_name>`”. The “zone\_name” was retrieved in step 4 when the zone was created. It is always possible to do the “[Get zones info](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=getZonesInfo)” API call to get this information. An example: ```text commcloud.stg-zzzz-cc-merchant-com.cc-ecdn.net ``` ## Step 9: Business Manager (Optional) If you make use of vanity domains in the business manager, you will have to contact Support in order to manage this “zone” through the API. > Post-migration tasks validate your eCDN traffic flow and setup. To complete the post-migration process, coordinate with Commerce Cloud Engineering.Commerce Cloud Engineering creates and activates a staging Business Manager zone to handle your Business Manager traffic that goes through only your Business Manager host name, for example, staging-`<realm>`\-`<customer>`.demandware.net. Business Manager doesn’t have an eCDN management page for staging instances. Commerce Cloud Engineering services include the demandware.net lockdown protections that protect your production and development instances. _**Post-migration tasks:**_ 1. **Revert to the \*.demandware.net certificate at the origin:** This step applies to custom certificates installed to the POD for the staging instance. Commerce Cloud Engineering validates that traffic is flowing through eCDN for the configured host names. After validation, the certificate at the origin level is reverted back to the standard \*.demandware.net certificate. The Salesforce Commerce API (SCAPI) can then connect to your staging instance. 2. **Create and activate a staging Business Manager zone:** Commerce Cloud Engineering creates and activates the Business Manager zone for your implementation. If you use the self-service steps to create an eCDN zone and certificate, contact SFCC Support. They contact Commerce Cloud Engineering to create and activate a staging Business Manager zone. If you implement an existing custom certificate for your staging instance, Commerce Cloud Engineering creates and activates the staging Business Manager zone without a GUS request. You can request to opt out of this component. Infocenter (04/05/2023) ## All done After all of these steps are complete, the domain can be used to reach the staging environment with a valid certificate! --- ## Using OCAPI and SCAPI Hooks in SFCC Canonical URL: https://rhino-inquisitor.com/how-to-use-ocapi-scapi-hooks/ Markdown URL: https://rhino-inquisitor.com/how-to-use-ocapi-scapi-hooks/index.md Content type: article Published: 2022-10-31T13:03:53Z Updated: 2025-07-29T12:47:51Z Summary: Hooks are becoming more and more prominent because of the PWA Kit and the API first methodology. But how do you implement them? Categories: Salesforce Commerce Cloud, Technical Tags: headless, ocapi, scapi, sfcc, technical ## Key Takeaways - Explains how OCAPI and SCAPI hooks extend existing API lifecycles and when not to use them - Covers registration, implementation flow, and the practical differences between before, after, and modifyResponse hooks - Emphasizes security, validation, and architectural discipline as essential for safe hook customization > **Info:** This article was updated with the latest and most important feature information as of 26 July 2025. So, you need to add a custom attribute to the basket response, or maybe validate an order against a third-party fraud service before it’s created. Your first thought? A SCAPI hook. You’re not wrong, but you’re only seeing the tip of the iceberg. Salesforce Commerce API (SCAPI) and OCAPI (Open Commerce API) hooks are one of the most powerful tools in our arsenal for extending the platform’s [headless](/sitegenesis-vs-sfra-vs-pwa/) capabilities. They allow us to inject custom logic directly into the API lifecycle, tailoring the out-of-the-box behaviour to meet unique business requirements. But let’s be clear: with great power comes great responsibility. The official documentation provides the “what” and the “how,” but it’s in the wild, under a production load, where the real lessons are learned. These powerful tools, if used improperly, can be extremely hazardous, potentially introducing security vulnerabilities, performance bottlenecks, and maintenance issues. This isn’t just a rehash of the official docs. This is a field guide, a playbook forged from experience. We’re going to dive deep into the critical areas that documentation often glosses over: security hardening, performance tuning, bulletproof error handling, and avoiding the architectural traps that lead to what architects call a “Big Ball of Mud”. We’ll cover everything from the fundamental anatomy of a hook to advanced strategies like idempotency and circuit breakers. Our roadmap is clear: we’ll start with the fundamentals, then navigate the security gauntlet, tackle the need for speed, prepare for when things go wrong, and finally, tour the hall of shame of common anti-patterns. Let’s get started. ## The Anatomy of a “Hook” Before we can master SCAPI and OCAPI hooks, we need to understand them from the ground up. This means not only knowing what they are but also what they are not, and how they fit into the broader SFCC extensibility landscape. ### What Are Hooks, Really At their core, hooks are a mechanism for altering and extending the behaviour of _existing_ API resources using server-side B2C Commerce Script API logic. They are not standalone endpoints; rather, they are extension points that allow you to inject your custom code into the platform’s standard API request lifecycle. This brings us to a critical architectural crossroads. The platform provides two primary methods for adding custom server-side logic to SCAPI and OCAPI: hooks (SCAPI / OCAPI) and Custom APIs ([SCAPI only](/creating-custom-ocapi-endpoints/)). The choice you make here will define the maintainability and scalability of your solution. Hooks are fundamentally tethered to an existing Salesforce endpoint, like `/baskets` or `/orders`. They can only react to calls made to that endpoint. Their purpose is to _augment_ an existing process. For example: - Adding a custom attribute to the basket response. - Validating a shipping address against a third-party service. - Calculating a complex, custom surcharge on an order. Custom APIs, on the other hand, allow you to create and expose entirely new, net-new REST endpoints under the SCAPI framework. If your goal is to introduce a new capability that doesn’t logically fit within an existing API’s model, a Custom API is the correct strategic choice: - A `/loyalty-info` endpoint to fetch a customer’s points balance. - A `/pickup-point-locator` endpoint to find nearby physical stores. - An endpoint to handle a custom newsletter signup form. The introduction of Custom APIs, especially with the 23.9 release, was a game-changer, moving us beyond the old workarounds of trying to tweak existing endpoints to serve entirely new purposes. Choosing the wrong tool leads to technical debt. Trying to shoehorn new functionality into an existing hook results in convoluted, hard-to-maintain code that compromises the original intent of the endpoint. Make the right architectural choice _before_ you write a single line of code. ### The Three Musketeers: before, after, and modifyResponse [![Illustration representing the before, after, and modifyResponse hook flow.](/how-to-use-ocapi-scapi-hooks/26df11a8-62ec-44cd-bf3b-6ff9ab46bee8-5598d60cbd_hu_cc9605b80220d245.webp)](26df11a8-62ec-44cd-bf3b-6ff9ab46bee8-5598d60cbd.jpg) Before, after, and modifyResponse are the three hook phases you actually need to reason about. SCAPI and OCAPI hooks come in three main flavours, each with a distinct role in the request lifecycle. Understanding their specific purpose and limitations is crucial to using them correctly. - **`before<HTTP Method>`:** This hook executes _before_ the server performs its main processing. Its primary role is to validate input and preprocess the incoming request document. This is your first line of defence, where you can perform status checks, apply additional filtering logic, or validate data before it ever touches the core system objects. - **`after<HTTP Method>`:** This hook executes _after_ the server’s main logic has completed but _before_ the final response document is created. It operates on the modified Script API object (e.g., the `Basket` or `Order` object). This is the place for side effects and integrations, such as sending a newly created order to an external ERP, triggering a basket recalculation (`dw.order.calculate`), or performing change tracking. - **`modify<HTTP Method> Response`:** This is the final step in the chain. It executes _after_ the platform has already created the response document from the Script API object. Its sole purpose is to make final modifications to the response document, such as adding or removing custom attributes (c\_ fields) or cleaning up data before it’s sent to the client. A critical point: this hook is **not** transactional. Attempting to modify a persistent Script API object here will result in an `ORMTransactionException` and an [HTTP 500 fault](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/b2c-commerce-ocapi/customization.html) ## Not all APIs are made equal Before starting this journey together, the most important thing to understand is that not all endpoints support hooks. An overview for both types is available: - [OCAPI](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/b2c-commerce-ocapi/hooks-shop.html) - [SCAPI](https://developer.salesforce.com/docs/commerce/commerce-api/guide/hook_list.html) ### Feature switch for SCAPI As it stands, Salesforce B2C Commerce Cloud disables hooks by default for the SCAPI. To enable hook support, a feature switch needs to be enabled in the Business Manager: “Administration > Global Preferences > Feature Switches” ![Feature switch screen used to enable SCAPI hooks in Business Manager.](/how-to-use-ocapi-scapi-hooks/feature-switch-scapi-hooks-9a09bc135b_hu_f04a6fe1b3ccc5af.webp) SCAPI hooks do not exist until the feature switch is enabled in Business Manager. OCAPI Hooks are enabled by default for the OCAPI, and you don’t need to do any configuration. ## Step 1: Register your customizations The first step in writing hooks for our APIs is registering them with the server. To do this, you need to do the following steps. ### Create a “hooks.json” file We need to create a JSON file that describes which endpoints we want to customise called “hooks.json.” This file can be put anywhere in a cartridge. But in this case, we will put it in the root ( e.g. “my\_project/cartridges/my\_ cartridge/hooks.json ) as an example. ```json { "hooks": [ { "name": "dw.ocapi.shop.basket.beforePATCH", "script": "./cartridge/scripts/hooks/basketHooks.js" }, { "name": "dw.ocapi.shop.customers.password_reset.afterPOST", "script": "./cartridge/scripts/hooks/passwordHooks.js" } ] } ``` In this file, we “hook” the customisation script to the REST endpoint we want to extend. We can define as many as we want within the file! But make sure every “name” is unique. If it is not, there might be some unexpected behaviour. ### Update the “package.json” cartridge file The next step is to create or edit your cartridge’s “package.json” file. The file should be in the root folder of your cartridge. (e.g. “my\_project/cartridges/my\_ cartridge/package.json”) ```text { "hooks": "./hooks.json", ... } ``` Salesforce B2C Commerce Cloud parses this file to enable specific customisations, including hooks. ## Step 2: Build your customisations You probably noticed that we need to define a “script” file for each hook we register. But we have not created those files until now, so let us do that! ### Look up the endpoint documentation Before we start writing the code, we need to know what function to export in our script for the system to pick up our customisation. This information can be found in the [Infocenter](https://documentation.b2c.commercecloud.salesforce.com/DOC1/index.jsp). First, we locate the endpoint we want to override. The documentation will show us more information about the [function behind it](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/Baskets.html#id-1036385888__id1441479317). [![Hook documentation showing the exported function name and parameters.](/how-to-use-ocapi-scapi-hooks/screenshot-2022-06-01-at-20-31-35-e1654104790984-f648d18f90_hu_acd796f361ef8ae.webp)](screenshot-2022-06-01-at-20-31-35-e1654104790984-f648d18f90.png) The hook signature tells you exactly what the platform expects your script to export. In this case, we need to export the function “beforePATCH” with the parameters “basket” and “basketInput.” Case sensitivity The function name is case-sensitive, so match it to the documentation! If it does not match exactly, your customisations will not run. ### Put that documentation to work Now that we know what function to use, we can start writing some code. ```js /** * This can be used to update the basket server side, if for instance we need to call a tax service or sync the basket. * The client app can retrieve this updated basket by doing a PATCH request. */ exports.beforePATCH = function (basket, basketInput) { var productLineItems = basket.getProductLineItems(); /** pass on something to ensure hooks are executed */ for (var i = 0; i < productLineItems.length; i += 1) { productLineItems[i].setLineItemText('PRODUCT ' + productLineItems[i].getLineItemText()); } }; ``` ### Detecting OCAPI vs SCAPI We may have a scenario where the OCAPI and the SCAPI use the same endpoint and have their unique customisations. To detect SCAPI calls, the request object/class has recently received [a helper function:](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_system_Request.html?resultof=%22%69%73%73%63%61%70%69%22%20#dw_system_Request_isSCAPI_DetailAnchor) ```text request.isSCAPI() ``` ## Step 3: Test if it works That wasn’t so much work now, was it? All that is left is to test that our custom code is executed correctly! I recommend [Postman](https://gist.github.com/jorgehernandezSF/0fe8866996b5968f0daceb0c408be824) to do so. Maybe a list of things to keep in mind: - Don’t forget to upload your cartridge! - Don’t forget to add the cartridge to the correct cartridge path! - Call the correct endpoint! - Call the correct environment! Some of these might seem obvious, but it is easy to get mixed up when working with tools such as Postman. ## The Security Gauntlet: Fortifying Your Hooks We must build our customisations to be robust, as an exception can cause the entire API to fail! Be sure to catch exceptions and log them appropriately so we can monitor and fix any exceptions that might occur. Now that we know how to build a hook, let’s discuss how to create a _secure_ one. This is not optional. A poorly secured hook can expose your application to significant risk. Salesforce has provided a list of constraints and best practices [on the documentation site](https://developer.salesforce.com/docs/commerce/commerce-api/guide/extensibility_via_hooks.html#constraints-and-best-practices)! ### The Shared Responsibility Pact Let’s be crystal clear on the security context. Salesforce is responsible for securing the API endpoints, the underlying platform, and the infrastructure on which it runs. This includes authentication at the API gateway and authorisation based on scopes. However, under this shared responsibility model, **you** are responsible for the security of any custom code you write, and that absolutely includes hooks. When a SCAPI request arrives, it’s first authenticated and authorised by the gateway based on the client’s Shopper Login and API Access Service (SLAS) token, along with its associated scopes. Only then is the request passed on for processing, which is where your hook executes. The hook script runs with powerful server-side permissions, and this is where the danger lies. A developer, focused on a simple task like adding a custom field, might implicitly trust that the initial gateway authorisation is sufficient. This is a critical mistake. Your hook script has direct access to sensitive Script API objects, such as `Order`, `Customer`, and `Basket`. Without its own internal checks, it can be manipulated. For example, a `PATCH` request `/orders/{order_id}` might be authorised by the gateway for the `orders` scope, but the gateway doesn’t know if the authenticated user actually _owns_ that specific `order_id`. It’s the hook’s job to verify ownership. A hook that blindly trusts the data it receives creates a massive security hole. It can function as a “confused deputy,” where an unprivileged user can make privileged calls through your code. The mantra must be: **re-authenticate and re-authorise within the hook.** ### Never Trust, Always Verify: Authentication & Authorization in Hooks This principle must be applied rigorously. When your hook code deals with sensitive objects, you must always use the secure Script API methods that require a secondary token or secret that only the legitimate owner would possess. For instance, the `dw.order.OrderMgr` class provides two ways to retrieve an order. One is dangerously insecure in this context; the other is the correct choice. ```js var OrderMgr = require('dw/order/OrderMgr'); // INSECURE: AVOID in hooks where ownership is not yet verified. // An attacker could pass any valid order number. var order = OrderMgr.getOrder(orderNumber); // SECURE: PREFERRED in hooks. // The orderToken is a secret known only to the user who placed the order. // This token should be passed in the request from the client. var order = OrderMgr.getOrder(orderNumber, orderToken); ``` This pattern extends to other sensitive objects. Always perform additional checks to confirm the user’s authority to perform the requested action. For guest shoppers, where you don’t have an authenticated session, this is even more critical. You should consider prohibiting guest shoppers from changing existing orders or requiring them to provide a combination of secrets from the order (e.g., order number and the email address used) before allowing any modification. ### Sanitise Everything: The Gospel of Input Validation Your `before` hooks are the primary gatekeepers for all incoming data. They must be ruthless in their validation. Failing to validate and sanitise user-provided input opens the door to a host of attacks, including Cross-Site Scripting (XSS) and various injection attacks that could compromise your server or database. The best practice here is to adopt a **whitelisting** (or allowlisting) approach. Instead of trying to block known bad inputs (blacklisting), you should define exactly what is permitted and reject everything else. This is a far more secure posture, as attackers continually find new ways to circumvent blacklists. Your validation logic should check for type, length, format, and range on every single field you process. ```js // Example validation in a beforePUT hook for a customer address exports.beforePUT = function (customer, addressId, addressDoc) { var Status = require('dw/system/Status'); var status; // This will hold the Status.ERROR object if any validation fails. /** * A helper function to initialize the error Status object on the first validation failure. * This prevents creating the object unnecessarily and keeps the code clean. * @returns {dw.system.Status} The status object, initialized to ERROR if it wasn't already. */ function getErrorStatus() { if (!status) { // Create a single ERROR status with a custom code the client can use. status = new Status(Status.ERROR, 'AddressValidationError'); } return status; } // Example: Validate postal code format for a specific country if (addressDoc.country_code === 'US' && !/^\d{5}(-\d{4})?$/.test(addressDoc.postal_code)) { // Add a machine-readable key and a human-readable message for this specific error. getErrorStatus().addDetail('INVALID_POSTAL_CODE', 'Invalid US postal code format.'); } // Example: Prevent overly long city names if (addressDoc.city && addressDoc.city.length > 50) { getErrorStatus().addDetail('CITY_NAME_TOO_LONG', 'City name exceeds maximum length of 50 characters.'); } // Example: Ensure required fields are present if (!addressDoc.first_name || !addressDoc.last_name) { getErrorStatus().addDetail('MISSING_REQUIRED_FIELDS', 'First and last name are required.'); } // If 'status' was created, an error occurred, so return it. // Otherwise, all checks passed, so return an OK status. return status || new Status(Status.OK); }; ``` ### Implement the same hook in multiple cartridges > In a single hooks.json file, you can register multiple modules to call for an extension point. However, you can’t control the order in which the modules are called. If you call multiple modules, only the last hook returns a value. **_All modules are called, regardless of whether any of them return a value_**. At run time, B2C Commerce runs all hooks registered for an extension point in all cartridges in your cartridge path. Hooks are executed in the order their cartridges appear on the path. Each cartridge can register a module for the same hook. Modules are called in cartridge-path order for all cartridges in which they are registered. The text above has been taken from the [Salesforce B2C Commerce Cloud Infocenter](https://developer.salesforce.com/docs/commerce/sfra/guide/b2c-sfra-hooks.html) and turns out not to be correct (at least for SCAPI/OCAPI hooks. [![Hook response example where returning Status.OK short-circuits later hooks.](/how-to-use-ocapi-scapi-hooks/hooks-return-status-to-short-circuit-806c56df79_hu_52d94b4cf969b723.webp)](hooks-return-status-to-short-circuit-806c56df79.jpg) Returning Status.OK can stop later hooks, so one line can change the whole chain. This does have a slight nuance: It is not the case for all endpoints. Luckily this is documented for every hook! [![Documentation excerpt showing hook return behavior for a specific endpoint.](/how-to-use-ocapi-scapi-hooks/hook-return-behaviour-91893c6015_hu_7291212f82af43eb.webp)](hook-return-behaviour-91893c6015.jpg) The documentation is worth checking here because hook return behavior is not intuitive. Read the documentation carefully for each hook! So basically: never return the following code in your hooks when your custom code completes successfully (if the endpoint supports it): ```text return new Status(Status.OK); ``` Sometimes, your linter will complain about not returning a value in all branches. But you must ignore that warning to avoid breaking another cartridge hook. (Unless you want to break the chain!) An example where a linter will complain: ```js exports.beforePOST = function beforePOST(registration) { var Status = require('dw/system/Status'); var verificationResult = validate(registration.customer); if (!verificationResult) { return new Status(Status.ERROR, 'ERR-TS-02', Resource.msg('turnstile.errors.ERR-TS-02', 'turnstile', null)); } // Your linter will want a return statement here }; ``` ## The Need for Speed: Performance Tuning Your Hooks A functional hook is different from a performant hook. Every line of code added to a hook increases the ‘overhead tax’ on the API’s response time. ### The Overhead Tax: The Cost of Customization Let’s be blunt: hooks are inherently slower than the out-of-the-box APIs. This is because your custom script execution is layered on top of the platform’s own code. This is a trade-off you make for the sake of flexibility. The performance shared responsibility model is clear: Salesforce is responsible for the performance of its base API code. You, the developer, are responsible for the performance of your catalog structure, the parameters you send in requests, and every single line of your hook script. A slow hook can bring a snappy API to its knees. ### Your Best Friend, The Code Profiler You can’t optimise what you can’t measure. The B2C Commerce [Code Profiler](/server-side-performance-in-sfcc/) is the essential tool for diagnosing performance issues in your custom code. It allows you to see exactly how much time is being spent in different parts of the application flow. The profiler has several modes, each with a different level of detail and performance impact : - **Production Mode:** Measures a subset of requests with minimal performance impact. Good for getting an aggregated view on a live system. - **Development Mode:** Measures all requests with more detail. This is the default for sandboxes and has some runtime overhead. - **Extended Script Development Mode:** Provides deep insight into script execution, down to the line level. It has a **severe** performance impact and should be used with extreme caution, especially on production instances. To zero in on your hook’s performance, open the Code Profiler (`Administration > Operations > Code Profiler).` Select the appropriate mode, and look in the results for the `SCRIPT_HOOK` result type. This displays the execution times for your hooks, allowing you to quickly identify bottlenecks. ### Optimization Tactics for High-Performance Hooks Once you’ve identified a slow hook, here are the primary tactics for speeding it up: #### Minimize External Service Calls This is, without a doubt, the most common and most severe performance killer. A hook that makes a synchronous call to a slow third-party service will hold up the entire API response. If you absolutely must call an external service, you must use the B2C Commerce Service Framework. This framework is designed for this purpose and provides critical features, such as configurable timeouts and a circuit breaker, which can prevent a failing external service from cascading into a full-blown site outage. #### Strategic Caching Caching is a powerful tool, but with hooks, it’s a double-edged sword. A `modifyGETResponse` hook, for example, only runs when the cache for that API response is empty or stale. If your hook injects highly dynamic or user-specific data into a response (e.g., a personalised “Welcome back!” greeting), you have effectively made that response uncacheable for anyone else. What was once a fast, globally cached response from the eCDN now requires a full server-side execution for every single request. This can dramatically increase server load and latency. Therefore, you must be acutely aware of the “cacheability” of the data you inject. Use `modifyResponse` hooks on GET requests with extreme caution. If possible, load highly personalised data via a separate, non-cached API call from the client after the main, cacheable content has loaded. For expensive, repeatable operations _within_ a hook (like a complex data transformation), you can leverage B2C Commerce [Custom Caches](/caching-in-the-sfcc-composable-storefront/) to store the result, but be mindful of their size limits (20MB total, 128KB per entry) #### Efficient Data Handling Don’t process more data than necessary. Before your hook even runs, the initial API call from the client should use the `select` and `expand` parameters to request only the necessary data fields. If your `modifyResponse` hook on the product details page only needs to add a custom warranty field, the client shouldn’t be asking for all image groups, all variation attributes, and all set products. The less data the platform has to retrieve and your hook has to parse, the faster it will be. ## When Things Go Wrong: Error Handling & Idempotency A hook that works perfectly on a sunny day is easy to write. A truly robust hook is one that behaves predictably and safely when things go wrong. ### Building Resilient Hooks: Beyond the try-catch Any unhandled exception thrown from within your hook script will cause the entire database transaction to roll back, resulting in an HTTP 500 Internal Server Error being returned to the client. This is a jarring experience for the user and can mask the root cause of the problem. Therefore, every hook function you write should be wrapped in a comprehensive `try-catch` block. When an error is caught, you must log it with enough context to be useful for debugging. Use the standard B2C Commerce logging framework (`dw.system.Logger`) to write detailed messages to a custom log category in the Log Center. Include identifiers such as the basket UUID or customer ID to facilitate easier troubleshooting. ### The Circuit Breaker Pattern: The Platform’s Self-Defence Your error handling strategy isn’t just about logging, it’s about platform stability. B2C Commerce has a built-in self-defence mechanism called the [Hook Circuit Breaker](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/b2c-commerce-ocapi/hookcircuitbreaker.html). If a specific hook extension point fails more than 50 times in its last 100 calls, the circuit “opens.” For the next 60 seconds, all calls to that failing extension point will be immediately rejected with an HTTP 503 Service Unavailable and a `HookCircuitBreakerException`, without ever executing your code. Think about the implications. A buggy hook doesn’t just return an error for one user; it can render an entire API endpoint, such as adding a payment to the basket, completely unavailable for _all users_ for a full minute. A transient issue, like a third-party payment gateway being temporarily down, could cause a cascade of hook failures, tripping the breaker and turning a minor hiccup into a major outage. This elevates your `try-catch` block from a simple best practice to a mission-critical component. Gracefully catching external failures and returning a non-error status (if the failure is not critical to the core transaction) is essential to prevent your hook from taking down a piece of your storefront. ## The Hall of Shame: SCAPI Hook Anti-Patterns To wrap up, let’s tour the gallery of common mistakes and anti-patterns. Avoid these, and you’ll be well on your way to writing clean, maintainable, and robust hooks. - **The “God” Hook:** A single, monolithic script file (`hooks.js`) that contains the logic for dozens of different extension points. This violates the Single-Responsibility Principle, resulting in a tangled mess that is difficult to read, debug, or maintain. - **The “Chain Breaker”:** A hook that incorrectly returns `new Status(Status.OK)` when it should simply allow processing to continue to other hooks later in the cartridge path. Unless you explicitly intend to short-circuit the execution chain, a successful pass-through hook should often have no return statement at all. Returning a status can prematurely stop the chain and silently disable functionality from base cartridges or other customisations. - **The “Silent Failure”:** A hook that swallows exceptions in an empty `catch {}` block or logs a useless message like “error occurred.” This makes troubleshooting a nightmare and can conceal critical system failures until they result in major data corruption. - **The “Leaky” Hook:** A `modifyResponse` hook that adds internal-only data, debugging information, or sensitive PII to an API response, which is then exposed directly to the client browser. - **The “Chatty” Hook:** A hook that makes multiple, inefficient, synchronous calls to external systems within a single execution instead of designing a more efficient bulk or batch data-fetching strategy. - **The “Trusting Fool”:** The most dangerous of all. A hook that blindly accepts and uses input from the request document without performing its own rigorous validation and authorisation checks, as detailed in our security section. --- ## Salesforce B2C Commerce Cloud October Updates Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-october-updates/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-october-updates/index.md Content type: article Published: 2022-10-24T17:48:25Z Updated: 2022-10-24T17:52:28Z Summary: There are no official updates in October, but that doesn't mean that nothing is moving! Let us have a look at what has changed! Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc, technical ## Key Takeaways - Summarizes the platform-adjacent October updates that landed after the final yearly 22.10 release - Highlights the SLAS trusted-agent capability and the operational implications for customer-service login flows - Calls out smaller Account Manager, idea-exchange, and cartridge/tool updates worth monitoring between major releases We have just received the final release ([22.10](/salesforce-b2c-commerce-cloud-22-10/)) of the year. But that does not mean there are no updates to some APIs and cartridges. Let us have a look what has changed in the past month. ## OCAPI & SCAPI ### Trusted Agent ![Diagram showing SLAS trusted-agent authentication in the October updates article.](/salesforce-b2c-commerce-cloud-october-updates/slas-trusted-agent-099b4e2206_hu_220fab562a800632.webp) Figure 1: Diagram showing SLAS trusted-agent authentication in the October updates article - [https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-trusted-agent.html](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-trusted-agent.html) This month a new addition to the SLAS ([Shopper Login API](/slas-in-sfra-or-sitegenesis/)) appeared! The ability to authenticate as a Trusted Agent (Customer Service) to log in on behalf of a customer. This is not a new feature, as this was already possible using the OCAPI. But it is good to see that this has also made its way to SLAS, so we do not have to combine authentication methods for these use cases. Another added advantage is that this authentication works with the Account Manager, so we do not have to worry about security on that part (2FA is included this way!) Permissions This new API depends on an Account Manager account with a “user” in that specific environment. Permissions and roles define what these users are capable of: - `Login_On_Behalf` - `Create_Order_On_Behalf` ## Account Manager The account Manager [received some updates](https://help.salesforce.com/s/articleView?id=sf.account_manager_rn_1_31_102_release.htm&type=5&language=en_US) this month on the 5th of October: - Security Fixes - Bug Fixes - Updates to the email sent by the Account Manager. Updates include new messaging and a new format that improves the user email experience. ## New Ideas Whether or not you believe this works to get things prioritized, giving good ideas some points will at least point the roadmap team in a specific direction. For that reason, I created this new section that lists all new ideas posted in the past month! - [Reports & Dashboards - Promotion dashboard enhancements](https://ideas.salesforce.com/s/idea/a0B8W00000L7GuRUAV/reports-dashboards-promotion-dashboard-enhancements) - [Provision to upload custom robots.txt per domain similar to custom sitemap files](https://ideas.salesforce.com/s/idea/a0B8W00000L7BCbUAN/provision-to-upload-custom-robotstxt-per-domain-similar-to-custom-sitemap-files) - [Audit Log on Custom Object Values](https://ideas.salesforce.com/s/idea/a0B8W00000KuSVfUAN/audit-log-on-custom-object-values) ## Updated Cartridges & Tools ### `plugin_reorder_demo` - [https://github.com/SalesforceCommerceCloud/plugin\_reorder\_demo](https://github.com/SalesforceCommerceCloud/plugin_reorder_demo) > This is the repository for the `plugin_reorder_demo` plugin. This plugin enhances the `plugin_commercepayments` cartridge by providing re-order functionality, including the following capabilities: - Registered shoppers can re-order previously placed orders from their accounts A new cartridge popped up with re-ordering functionalities. Although it requires the Salesforce Payments cartridge, you can use the code as a cheat sheet when implementing your version that does not use it. ### b2c-tools (v0.11.1) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances. It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. Page Designer orphan cleanup example and support by [@clavery](https://github.com/clavery) in [#86](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/86) See [examples/page-designer-orphan-cleanup.js](https://github.com/SalesforceCommerceCloud/b2c-tools/blob/main/examples/page-designer-orphan-cleanup.js) --- ## Let’s GO-LIVE: Customer Migration Canonical URL: https://rhino-inquisitor.com/lets-go-live-customer-migration/ Markdown URL: https://rhino-inquisitor.com/lets-go-live-customer-migration/index.md Content type: article Published: 2022-10-17T17:49:09Z Updated: 2022-10-17T17:53:18Z Summary: Bringing your first site live on SFCC can be challenging. In this series, we will be looking at different parts. This time: Customer Migration Categories: GO-LIVE, Salesforce Commerce Cloud, Technical Tags: migration, sfcc, technical ## Key Takeaways - Explains why customer migration planning must start early even though it executes near go-live - Covers ownership, secure handling, password migration, and rollback considerations for customer data moves - Emphasizes testing, delta planning, and post-launch monitoring to avoid data loss and login issues We have already gotten [a few parts down](/category/go-live/) of our GO-LIVE story, but we are far from done. Going live with any Commerce project can be quite an endeavor. But hopefully, with this series, the most critical parts of the puzzle are covered! On to the next piece: Customer migration! ## [Start sooner rather than later](http://t) Although this series is about GO-LIVE, which happens at the end of a project - a lot of preparation goes into it, even weeks and months in advance. Data migration should be in your planning as soon as possible, as customers who existed on a previous platform (which usually applies) must be migrated. The main reason to start this sooner rather than later: **You are, in most cases, not in control!** What I mean by this is that the implementation partner of the previous platform needs to share the data with you, either in their format or in the one that Salesforce B2C Commerce Cloud uses. And since this is sensitive data, processes need to be put in place to ensure the transfer of information happens securely! ## Decide who is in charge Salesforce B2C Commerce Cloud only allows formats it defines, which means that with any migration, some transformation needs to happen from the format of the previous platform to that of SFCC. And there is only one option: [XML](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/xsd/Schemas.html) (Business Manager or Automated job). But what do you mean by “who is in charge?”. Well, who is going to be doing that transformation? Depending on the answer, this will affect your planning. There are a few options for who takes ownership of this: 1. The Consulting (Implementation) Partner 2. The Salesforce customer 3. The previous implementation partner Ultimately, it does not matter who does it as long as they have the required knowledge of both the old and new formats. There is enough [documentation](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/import_export/b2c_customer_object_import_export.html) available to get anyone started on the process, and guidance from the Implementation Partner is always a good thing. ## Handle with care ![Security illustration introducing the risks of mishandling customer data.](/lets-go-live-customer-migration/data-breach-7096540e7a_hu_fe56e20a731c844f.webp) I have mentioned this before, but we deal with people’s personal information in this process! Be sure that the data you work with is handled properly! Transfer the data securely, and only transfer it to people who need to work with this data. _😱 Don’t email the database unencrypted to everyone involved in the project. 😱_ And also important, once the people have done their task, they must delete the data from their systems. ## Make a deployment plan Work out a detailed plan on how you will do this migration. In many cases, the old platform will still be up and running a few hours before the scheduled go-live. So what about the registrations and account updates between the last export and when you go live? Think about, and discuss with the team how to handle the last delta import to make sure no data is lost. Make these steps part of your deployment plan, and decide who is in charge of each step. ## Compare and test After converting the data, run extensive testing on the source and target file to ensure no data has been mixed up. This might seem obvious. But we don’t want to link the address of person A to person B accidentally, do we? ## Password migration I will not elaborate on this one too much, but compared to the other data in a customer migration, this tends to be the most challenging. Why is that? Well… better hope you get this data encrypted or hashed! Otherwise, the previous platform had some severe security issues. And because of that encryption/hashing, you need to find ways to handle this. To dig deeper into this topic, I will redirect you to an [excellent article by Oleg Sapishchuk](https://osapishchuk.medium.com/legacy-customers-password-migration-3fa1596303cc). ## Monitoring ![Monitoring illustration for post-go-live customer migration checks.](/lets-go-live-customer-migration/robot-monitoring-a-screen-4af85584a4_hu_910daa635530c18a.webp) The final step, as with many things, is monitoring after go-live. Make sure people can log in - and make Customer Service aware to note down all the information to track potential bugs. It is vital to keep this part of your daily routine for the first few days (amongst other things) after the big release. ## Rollback With any big release, make sure you also have a contingency plan. Things can go wrong, and a rollback might be needed to make corrections. Like a deployment plan, ensure a rollback scenario is covered with tasks and who is responsible for each. We all wish everything goes as planned, but the reality is not always so kind. --- ## What is Salesforce B2C Commerce on Core? Canonical URL: https://rhino-inquisitor.com/what-is-commerce-on-core/ Markdown URL: https://rhino-inquisitor.com/what-is-commerce-on-core/index.md Content type: article Published: 2022-10-09T14:17:31Z Updated: 2023-02-08T18:02:55Z Summary: People who have been around "Demandware" for a while and continued after the acquisition by Salesforce know that this announcement was bound to happen at Categories: Salesforce Commerce Cloud Tags: security, sfcc, technical ## Key Takeaways - Explores the idea of Salesforce B2C Commerce moving onto the Salesforce core platform and explains why that direction seemed increasingly plausible - Connects that speculation to platform changes like SCAPI, OCI, and the composable storefront that point toward a more swappable architecture - Balances the potential advantages of commerce on core with the major blockers around features, performance, and the long migration horizon for existing customers People who have been around “[Demandware](/sitegenesis-vs-sfra-vs-pwa/)” for a while and continued after the acquisition by Salesforce know that this announcement was bound to happen at one point. It is a question that many have asked over the years looking at the core platform of Salesforce: “When will they migrate everything and move Salesforce B2C Commerce Cloud to the Salesforce core platform ([force.com](https://www.salesforce.com/products/platform/products/force/?sfdc-redirect=300))?” During Dreamforce, the first mention of this happening reared its face this year. During the keynote even! Although honestly, if you blinked, you probably missed this. A big announcement for Marketing Cloud is “hidden” in this slide too 😉. ![Dreamforce keynote slide hinting at Commerce on Core.](/what-is-commerce-on-core/commerce-on-core-fda7921efd_hu_90602d6bfef8ce76.webp) The Dreamforce '22 Main Keynote There was another slide and a short presentation they gave during the Keynote, but it seems it never made it to [Salesforce Plus](https://www.salesforce.com/plus/experience/Dreamforce_2022/series/Best_of_Dreamforce/episode/episode-s1e4). Unfortunately, I was not able to snap a pic of that one. However, I found another slide in one of the more recent presentations for onboarding new partners. ![Partner presentation slide showing multiple Commerce on Core shapes.](/what-is-commerce-on-core/commerce-on-core-subscriptions-6a0584ff6d_hu_81a98ed6389dbae8.webp) Commerce on Core can take many shapes and forms. Speculation Before you continue to read on, the article below is speculation and opinionated (my opinion only). So take everything with a grain of salt and contact Salesforce if you want to know more! **I do not work for Salesforce, and I do not know the internal roadmap!** ## Is it happening Yes, I have talked with multiple people within Salesforce. This change has been in the works for quite a while now. And this should have been clear if you look at some of the decisions made over the past two years and where Salesforce put focus. Though not much is known about this topic yet, I first saw mention of this “Commerce on Core” in September for research and UX testing. ## When is it happening As I have mentioned, a roadmap is not yet publicly available, nor is much information to be found. What can be speculated is that this will only be for new customers and likely only for small to medium businesses at first. The reasons why this will be the case should become more apparent as you continue reading. And more importantly, there is no reason to “**panic**.” This change will take many more years to complete, and innovations will keep happening to the current set-up (albeit in a different form - Composable microservices, anyone?). So please keep on reading! ## What will it look like ![Experience Cloud interface representing the likely foundation for Commerce on Core.](/what-is-commerce-on-core/experience-cloud-c8e89ddba1_hu_9bd98b4ff9dcfd07.webp) Hard to say, looking from the outside in. But chances are incredibly high that it will be the [B2B2C](https://trailhead.salesforce.com/content/learn/modules/b2b2c-commerce-basics) offering that will be used as a basis for this product. And I am sure the Composable Storefront will play a significant role in this transition. ## The preparations that Salesforce has done So what signs were there of the preparational work? Let’s dig into what has happened in the past few years, shall we? ### SCAPI An essential part of understanding how the SCAPI works is that [Mulesoft](https://www.mulesoft.com/) is involved. Using this orchestration layer allows for a lot more flexibility for future choices, and one of these options is … drumroll please … swapping out systems! ### OCI The [Omnichannel Inventory](/what-is-oci-omnichannel-inventory/) (part of the B2C Commerce Cloud license) was another sign that Salesforce pointed products more to a “composable architecture.” It is a separate product that can be used for B2C, B2B, B2B2C, or other applications. Many other products that followed, like Order Management and Commerce Marketplaces, were separated from the B2C Offering, and most noteworthy are on the [force.com](https://www.salesforce.com/products/platform/products/force/) (core) platform. ### Composable Storefront ![Composable Storefront architecture sitting on top of SCAPI services.](/what-is-commerce-on-core/composable-storefront-6b029b5901_hu_a2a8227369907673.webp) Another separate product on its own “stack” is the [PWA Kit](/sitegenesis-vs-sfra-vs-pwa/) (or now rebranded to the Composable Storefront). A headless storefront talking to the SCAPI, rather than the monolithic setup of SiteGenesis and SFRA, will allow back-end systems to be swapped more easily. Off course, the composable storefront has many more advantages, but composability is one of the signature advantages! ## Advantages of moving to the “Core” ### Hook into everything Unlike the current stack, we can [hook into all events](https://www.salesforce.com/products/platform/solutions/automate-business-processes/) that happen to objects: - Create - Update - Delete And we can do this for all cases: imports, “Business Manager” modifications, REST API, … This would solve one of the most common gripes of not being able to hook into Business Manager pages to add validations or other extensions. And, of course, it gives us much more flexibility about what we can do. With great power comes great responsibility Given this flexibility, you can also mess up a lot more. You could, for instance, break the entire import with a click of a button. ### Truly API first The force.com platform comes with a way more extensive array of integration options than we have with Salesforce B2C Commerce: - [SOAP API](https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_quickstart_intro.htm) (got to mention it, sorry ) - [REST API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_rest.htm) - [Connect REST API](https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/intro_what_is_chatter_connect.htm) - [Apex REST & SOAP API](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_rest_intro.htm) (Custom Endpoints through code) - [Tooling API](https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/intro_api_tooling.htm) - [Bulk API](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/asynch_api_intro.htm) - [Metadata API](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_intro.htm) - [Streaming API](https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/intro_stream.htm) - [Pub/Sub API](https://developer.salesforce.com/blogs/2021/07/pub-sub-api-building-event-driven-integrations-just-got-even-easier) - [Composite API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_composite_composite.htm) (part of the REST API) - [Composite Graph API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/using_resources_composite_graph.htm) (part of the REST API) And maybe I missed one… But that sure is a lot of options, isn’t it? ### Actually integrated I am not going too deep into B2C Solution Architecture as it stands now. There is [an excellent book for you](https://www.amazon.com/Salesforce-Solution-Architects-business-consumer/dp/1801817030) already available! But anyone who has had to integrate Service Cloud, Marketing Cloud, or Order Management can see the advantages of having B2C Commerce Cloud join the fray on the core platform. Now don’t get me wrong. The grass is always greener on the other side, and if this move happens, we will have other fish to fry! ### Sandboxes and replication You have many more options for Sandboxes on the core platform, including [copying metadata from a production instance to a Sandbox](https://help.salesforce.com/s/articleView?id=sf.data_sandbox_refresh.htm&language=en_US&type=5). This could also open up the road for Trailhead to have hands-on exercises! ### Flows ![Salesforce Flow builder as a no-code automation option on the core platform.](/what-is-commerce-on-core/salesforceflow-8728e6c02c_hu_eb4d1ca2a3c7f5fc.webp) Does anyone miss pipelines? The good news is that there is a low / no-code alternative to Apex (code) to do automation: [Lightning Flow](https://www.salesforce.com/blog/introducing-lightning-flow-blog/). ## Will bits and pieces remain from the current stack (Demandware) I am optimistic some bits and pieces will be used to resolve some of the “shortcomings“ of the core platform. A good example is the high-scale cart/basket service already used behind the scenes in the “Demandware” stack. It would make a lot of sense to move this over. Maybe the promotion engine is also a good contender, as it will work well in conjunction with the cart service. But this is something that only the future (and Salesforce) can tell. Wouldn’t we all wish to get a glass ball to see what the future holds? But this keeps things exciting and fresh. ## What is stopping the move ### Features Currently, the core platform does not have all the features that B2C Commerce Cloud offers. Before making the switch possible, it will take time to “migrate” all of these. ### Performance Currently, B2B and B2B2C are already on the core platform. But generally have lower traffic (but higher volume) than a B2C site. Especially during the holiday seasons and days like Black Friday, I am not sure that the way it stands, the platform will be able to provide a good and performant user experience. The Composable Storefront end [Genie](https://www.forward.eu/blog/salesforce-genie-the-architecture/) is possibly the first step to make this happen, but we are not there yet. I will keep an eye on all the channels to see this evolve and maybe even try to get some hands-on access. But for now, I have more questions than I have answers. ### Existing customers Did I scare some of you? Have you just bought or started implementing SFRA? No worries. The current setup is not going anywhere soon. If you look at how many customers are still on SiteGenesis, it will take a very long time to migrate everyone away from how everything is set up now. And I hope Salesforce will give us a heads-up a few years in advance on the Commerce on Core road map and how this affects customers. ## Should I worry ![People reacting with uncertainty while considering a future platform migration.](/what-is-commerce-on-core/confused-people-on-the-street-1713a479da_hu_e848aab3ab8c5efe.webp) As mentioned in the previous section, it will take a while before existing customers are contacted about migrating to the new platform. I guess a minimum of 5-7 years before this will start occurring, but who knows - I have been wrong before. In the meanwhile, updates will happen to the current stack. And new features will be added. You might see a shift that features are separate products rather than being built in, such as the OMS, Marketplace, Composable Storefront, and OCI. Some will be included in the license, and others will come at an extra cost. This is a long time to prepare for this change as a customer and developer. And have you recently chosen the Composable Storefront (PWA Kit) as your go-to solution? Then there is nothing to worry about, as this will make migrating the back end “easier.” ### What about SFRA Did you choose an [SFRA](/sitegenesis-vs-sfra-vs-pwa/) setup? Then again: there is nothing to worry about. This change will take many years to come to fruition. You have a solution for your needs now (and in the near to medium future), and SFRA will do that perfectly. In many cases, a need to renew your stack arises every few years. Technology evolves rapidly, and who knows what options will be available in 5 years! ### I am on SiteGenesis - What do I do At any rate, moving away from [SiteGenesis](/sitegenesis-vs-sfra-vs-pwa/) should be somewhere at the top of your priority list. But as to what the best option for your situation is: Talk to [your implementation team](https://www.forward.eu) and Salesforce. Everyone has their requirements and needs for now and the future, and all options on the table have pros and cons. And the good news is - With Salesforce, you have many options to choose from: - SFRA - Composable Storefront - Hybrid migration from SiteGenesis to the Composable Storefront - Build your own Headless Storefront - Commerce on Core ([B2B2C](https://trailhead.salesforce.com/content/learn/modules/b2b2c-commerce-basics)) ### My personal take I have no negative and no positive feelings about this change. It will all depend on the future and whether all missing features make it to the core platform to handle B2CE customers. The most important thing is that the new stack can provide a stable, secure, performant, and “ready to tackle the future” solution for customers. I am not married to a particular stack and have made many switches over the past decade. I like to discover new ways of doing things, and whichever way you put it - the force.com platform does resolve some of the shortcomings we have in the current setup. But then again, the current stack has a lot of advantages over the force.com platform too. ### How do you feel about this change Leave a reply on this page to express your opinion! --- ## Office Hours for Salesforce B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/office-hours-for-salesforce-b2c-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/office-hours-for-salesforce-b2c-commerce-cloud/index.md Content type: article Published: 2022-10-03T18:06:14Z Updated: 2022-10-03T18:06:22Z Summary: You might have some burning questions about Salesforce B2C Commerce Cloud. Or do you want to stay up to date? Then join Office Hours! Categories: Community Tags: ohana, sfcc, technical, trailhead ## Key Takeaways - Explains what Salesforce office hours are and why they matter for staying current on product direction - Highlights the main B2C Commerce, OMS, solution architect, and marketplace office hour series - Positions office hours as a direct route for roadmap questions, technical discussion, and partner feedback Office Hours are a great way to stay up to date on a specific topic within the Salesforce ecosystem. But what are these “Office Hours,” and why should you care? Let us have a look! ## What are Office Hours In short, these are (usually) monthly recurring meetings where Salesforce presents exciting new developments in a particular area offering a Q&A at the end. The Product team usually presents these office hours, which means you can go technical! And if they don’t have an answer immediately, they will try to figure it out (if it is within their power) Link Location Most of the Office Hour links are located in the Partner Community. I am not sharing the links directly on this page for security reasons. When clicking on the below links, you will be directed (usually) to a Partner Community Group, where the link to the Office Hours is **on the left side.** This also has the added advantage that I do not have to keep the links up to date. ## B2C Office Hours - [Registration Link Location](https://partners.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F93A0000009SFY) > Are you interested in hearing more on our updates to SFRA, CC PWA Kit and Managed Runtime, Headless, and our Commerce APIs? Mark your calendars for our upcoming B2C Commerce Office Hours. The main Office Hours for Salesforce B2C Commerce Cloud. Here the possible roadmap is discussed and an open discussion is held about multiple topics: - New features - Positioning - Ideas - Improvements If at any point you want to voice your opinion and help Salesforce with choosing a direction, this is the Office Hours to join as a partner. ## Order Management: Consulting Partner Office Hours & Roadmap QA - [Registration Link Location](https://partners.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F93A000000HZ5o) > Come learn about all of the exciting new developments around Order Management with our Product team. Time will be reserved for Q & A with Product as we know there are a lot of questions related to our exciting Roadmap! [Order Management](https://www.salesforce.com/products/commerce-cloud/ecommerce/order-management/) has made its way into the Salesforce B2C Commerce Cloud world over the past two years. I have seen more traction to this offering in the past few months, so I wouldn’t be surprised to see more “multi-cloud” projects popping up, including the OMS. If you are working with the OMS or are interested in its capabilities, this is the Office Hours to subscribe to. ## B2C Solution Architect Success Office Hours Missing Link Since I have written this article, the link to register for the office hours has disappeared. Keep an eye out in the group for new dates! - [Registration Link Location](https://partners.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F94V000000DR36) > Office Hours To Have Your Certification Questions and Others! B2C Solution Architecture is aimed at Architects who want to learn and grow within the Best Practices used to connect different products. This webinar series is for everyone: - Certified B2C Solution Architects - Aspiring B2C Solution Architects - Simply wanting to learn how to connect the clouds successfully More and more B2C Commerce Cloud projects are coming in contact with the other products of Salesforce. Be it by native integration or because of necessity. Gathering information and learning best practices will help you grow in this domain and prepare you for your first multi-cloud implementation (or improving your existing ones). ## Commerce Marketplace (B2B/B2B2C) Office Hours - [Registration Link Location](https://partners.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F94V000000HdGW) > Come learn about all of the exciting new developments around B2B and B2B2C Commerce with our Product team. Time will be reserved for Q&A with the Product team as we know there are many questions related to our exciting Roadmap! With the addition of the Commerce Marketplace, we have quite a few products related to B2C Commerce Cloud built on the force.com platform. For now, it appears that the Commerce Marketplace is part of the B2B/2C wing for office hours, so for any questions or news be sure to sign up for it! --- ## Salesforce B2C Commerce Cloud 22.10 Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-22-10/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-22-10/index.md Content type: article Published: 2022-09-28T13:33:05Z Updated: 2022-10-03T11:59:36Z Summary: Review the Salesforce B2C Commerce Cloud 22.10 release and the final platform updates worth noting before the year wraps up. Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc, technical ## Key Takeaways - Highlights the major 22.10 updates around staging eCDN APIs, edge caching, and sandbox URL changes - Explains new platform and API behaviors such as basket hook changes and negative inventory allocation limits - Calls out related cartridge and storefront tooling releases that matter for hybrid, SFRA, and SLAS projects What a year it has been, and now it is time for the final release of this year: the [October 2022 (22.10) release](https://documentation.b2c.commercecloud.salesforce.com/DOC3/index.jsp?topic=%2Fcom.demandware.dochelp%2FReleaseNotes%2F22_8%2Frn_b2c_rn_22_9_release.html&cp=0_1_2)! And yes, as it is every year, there will be no releases between November and January to provide stability on the platform during the holiday period. Are you interested in last month’s release notes? [Read the 22.9 release notes](/salesforce-b2c-commerce-cloud-22-9-release/)! ## Staging eCDN configuration ![Staging eCDN configuration flow for a hybrid storefront.](/salesforce-b2c-commerce-cloud-22-10/ecdn-staging-464848555e_hu_25b74ef4a1f78663.webp) Hybrid storefront teams finally got a clearer path for staging the eCDN setup. A big update for those working with hybrid deployments using the PWA Kit (Composable Storefront). Many issues popped up in the staging environment that had to do with custom certificates and SLAS. With this update, these will hopefully be out of the picture! There will be **no Business Manager interface for this one**, only APIs that you have to call using the SCAPI: - [Create an eCDN zone](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=createStorefrontZone) - [Upload a certificate](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=addCertificateForZone) Business Manager The UI in the Business Manager will not reflect the changes made on staging! ## TikTok for Ads ![Business Manager view for the TikTok integration cartridge.](/salesforce-b2c-commerce-cloud-22-10/tiktok-bm-9172b705bb_hu_324a08428db5bf1c.webp) The TikTok cartridge adds another marketing surface directly inside Business Manager. Since the start of this year, there has been a lot of talk about “Social Commerce,” which means the integration of Salesforce B2C Commerce Cloud into different social channels such as TikTok. A positive move that has been made is this is a cartridge that you can install yourself, rather than being a feature switch where you have no control over what happens in the back-end. This gives developers (and architects) more power over how the integration with these Social Channels is made! The cartridge can be downloaded [from the Social Channel Integrations repository](https://github.com/SalesforceCommerceCloud/social_channel_integrations)! ## Platform ### Origin Shielding Phase 3 ![Origin shielding rollout note for Demandware.net lockdown.](/salesforce-b2c-commerce-cloud-22-10/origin-shielding-phase3-d9fa09fa33_hu_cdeaf8dcb64b2aa9.webp) Phase 3 matters because it further locks traffic down to Salesforce-controlled entry points. Phase three of Original Shielding will come into effect by locking down Demandware.net for Development and Production instances. This is probably the deadline for customers requesting a migration extension. ## Business Manager ### Self-provision Order Integration Before you had to contact support in order to provision an OMS integration, after this release this is something we will have full control over and do ourselves at: “Administration > Global Preferences > Salesforce Order Management Configuration” Permissions It might be necessary to give permission to your role in the Business Manager before seeing this new menu item! ## OCAPI & SCAPI ### Disabling of negative allocation amounts in inventory lists It will no longer be possible to set negative values for the allocation amount in an inventory record using the PUT/PATCH endpoint. Not sure why anyone would want to do this, but at least now you can’t. ```text /inventory_lists/{}/product_inventory_records/{} //error status code: 400 "type": "PropertyConstraintViolationException" "message": "An error occurred while decoding the request. There's a value constraint violation of property '$.allocation.amount' in document 'product_inventory_record'.” ``` ### beforePOST v2 for baskets To fix some issues in the v1 hook: - Using an incorrect input type (created basket, which isn’t available before the basket creation instead of the basket request document). - Using an incorrect execution order (hook was executed after the creation of the basket, which is too late for a before hook to function). A new hook has been introduced. ![beforePOST v2 basket hook reference in the API documentation.](/salesforce-b2c-commerce-cloud-22-10/new-hook-basket-f116a5da90_hu_8104bc02b0f5b65b.webp) This new hook gives teams another extension point in basket creation flows. > **Deprecated:** Hook The v1 hook will continue to exist but is discouraged from being used. ### Edge Caching for SCAPI Edge caching is introduced to increase the performance of the most often called APIs in the SCAPI: - /product - /category - /product\_search The performance of the SCAPI will improve with this change, as it no longer relies on caching on the client side but on the CDN layer in front of it. This will increase the response time and allow the Mulesoft layer to scale better since it is no longer responsible for serving 100% of the requests. > **Documentation:** ~~The documentation for this change is not available yet, so questions like “Can we manipulate the time?” or “Can we clear this cache?” is not something that we can answer yet.~~ **Update:** It is not possible to manipulate the cache time, or clear it. (For now, at least. This might change in the future) ## Development ### Unified Sandbox URL & API Server Currently, all ODS (On-Demand Sandboxes) operates under a unique URL based on the cluster they are located in (e.g., us01, us02, us03, …) A singular URL will be introduced for both the sandbox and the management APIs to make it easier to manage. **Current ODS URL:** zzzz-001.sandbox.us01.dx.commercecloud.salesforce.com/on/demandware.store/Sites-Site `<https://admin.us01.dx.commercecloud.salesforce.com/>` **New Unified ODS URL:** zzzz-001.dx.commercecloud.salesforce.com/on/demandware.store/Sites-Site `<https://admin.dx.commercecloud.salesforce.com/>` ## SFRA v6.2.0 ![Comparison between SiteGenesis and SFRA storefront stacks.](/salesforce-b2c-commerce-cloud-22-10/sfra-vs-sitegenesis-965c09b9a6_hu_b93be19e82ca4e6f.webp) SFRA 6.2.0 continues the gradual shift away from the older SiteGenesis model. - [https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/releases/tag/v6.2.0](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/releases/tag/v6.2.0) A new version of SFRA has popped up after months of silence, though nothing major or “wow” has happened besides maintenance tasks. ### Updates - Replace node-sass with sass [#1305](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/pull/1305) - Add legal notice region that showcases component type inclusions feature [#1311](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/pull/1311) - Use latest sgmf-scripts [#1317](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/pull/1317) ### Chores - Update dev dependencies [#1318](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/pull/1318) ## PWA Kit v2.2.0 ![PWA Kit release graphic for version 2.2.0.](/salesforce-b2c-commerce-cloud-22-10/e0468610-0e86-403f-b486-743a38d4b763-d68cf607f8_hu_511d88d25569bcb6.webp) PWA Kit 2.2.0 keeps the composable storefront track moving forward in parallel. - [https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v2.2.0](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v2.2.0) Development of the PWA Kit continues steadily, and new releases happen often. In August, a new release occurred with the following changes: ### Template Retail React App - Update zzrf-001 instance url [#694](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/694) - Optimize Server-side performance [#667](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/667) - Remove references to session bridging [#684](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/684) ### pwa-kit-dev Added option to specify where/from the credentials can be saved/read [#647](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/647) ## Bugfixes Here is a list of fixes made to the platform in the past month or planned in the 22.10 release! - [Custom setting for session timeout does not update cached value](https://trailblazer.salesforce.com/issues_view?id=a1p4V000002aVvRQAU&title=custom-setting-for-session-timeout-does-not-update-cached-value) - [Folder picker fails to load with ’library\_id’ undefined error](https://trailblazer.salesforce.com/issues_view?id=a1p4V000000wtu4QAA&title=folder-picker-fails-to-load-with-library_id-undefined-error) ## Updated Cartridges & Tools ### plugin\_slas (v6.2.9) - [https://github.com/SalesforceCommerceCloud/plugin\_slas](https://github.com/SalesforceCommerceCloud/plugin_slas) > The SLAS plug-in cartridge replaces the method for authenticating shoppers used by commerce applications based on the Storefront Reference Architecture (SFRA). Instead of using the B2C Commerce script API, the SLAS plug-in cartridge uses the Shopper Login and API Access Service (SLAS) to establish guest user logins and registered user logins. Some significant code changes have made their way into this cartridge, hopefully fixing some issues people have run into in production environments. **Updates** Use latest sgmf-scripts [#36](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/36) ### Bugs - Prevent httpRedirect in SLAS Auth service [#45](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/45) - Add session guard to preserve sessions after session bridge [#26](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/26) - Preserve client IP through the session bridge [#32](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/32) - Restore missing authenticated customer data for other plugins [#38](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/38) **Chores** Include and run prettier [#46](https://github.com/SalesforceCommerceCloud/plugin_slas/pull/46) ### b2c-tools (v0.11.0) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances. It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. - `export page` now supports a `-r` option to indicate that the page selectors are regular expressions and export all matching pages - Underlying page designer APIs were refactored and exposed to migration scripts. See [examples/page-designer.js](https://github.com/SalesforceCommerceCloud/b2c-tools/blob/main/examples/page-designer.js) for usage - page designer refactoring by [@clavery](https://github.com/clavery) in [#84](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/84) - update clean cartridge logic by [@clavery](https://github.com/clavery) in [#81](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/81) - bugfix cli to coerce code version to string by [@clavery](https://github.com/clavery) in [#85](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/85) ### plugin\_passwordlesslogin - [https://github.com/SalesforceCommerceCloud/plugin\_passwordlesslogin](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin) > Passwordless login is a way to verify a user’s identity without using a password. It offers protection against the most prevalent cyberattacks, such as phishing and brute-force password cracking. Passwordless login systems use authentication methods that are more secure than regular passwords, including magic links, one-time codes, registered devices or tokens, and biometrics. A new cartridge in town uses the SLAS API to allow passwordless login. As it is a new and a community cartridge, test it thoroughly before releasing it to production! It is great to see more SLAS make their way into SFRA, allowing for more flexible login methods. --- ## AI (Einstein) in Salesforce B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/ai-einstein-in-salesforce-b2c-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/ai-einstein-in-salesforce-b2c-commerce-cloud/index.md Content type: article Published: 2022-09-26T13:42:24Z Updated: 2025-03-12T11:00:54Z Summary: Salesforce B2C Commerce Cloud has an AI that can power different areas of the site. But what is it, why use it, and what can it do for me? Categories: Salesforce Commerce Cloud Tags: ai, einstein, headless, sfcc ## Key Takeaways - Explains what Einstein is in SFCC and how it differs from other Salesforce AI products - Covers core Einstein capabilities like recommendations, search, insights, and predictive sort - Highlights privacy, shared-data, and headless API considerations before adoption When you are first introduced to Salesforce B2C Commerce Cloud, one of the selling features that will increase conversion and customer satisfaction is [Einstein](https://www.salesforce.com/products/commerce-cloud/commerce-cloud-einstein/). Einstein is the “built-in” AI engine that powers product recommendations and other tools to guide a potential buyer. But what are these features, and will they increase my AOV (Average Order Value) by 26% as advertised? ## History Even though the product is called Einstein right now, it wasn’t always the case. Before Salesforce acquired Demandware, it was called CQuotient ([which was acquired by Demandware in 2014](https://www.businesswire.com/news/home/20141014005186/en/Demandware-Acquires-CQuotient)). You will still notice the reference in the URL when accessing the [Administrative Portal](https://configurator.cquotient.com). ![Legacy CQuotient administration screen before the Einstein rebrand.](/ai-einstein-in-salesforce-b2c-commerce-cloud/cquotient-demandware-history-v2-942e794c7b_hu_ad363f80236c4e7.webp) The old CQuotient branding shows how deeply Einstein is rooted in earlier tooling. This history lesson also clarifies that this “Einstein” is unrelated to all of the other “Einstein” products [in the Salesforce lineup](https://www.salesforce.com/products/einstein/overview/). Though probably some connections are made behind the scenes, this is - like with different features - a black box. ## Separate Product As CQuotient was an acquired AI product, it has a separate management console which I mentioned in the previous section. There are some screens inside the Business Manager, but they mainly push or pull data out of CQuotient: - [Slot Configuration](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/recommendations/b2c_configuring_slots_for_predictive_recommendations.html) - Page Designer components - [Einstein Status Dashboard](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/recommendations/b2c_configure_einstein_deployment.html) (Configuration & Monitoring) ## Shared Data Model For an AI (Artificial Intelligence) to work, it needs to be fed with **quality** data. And the more data, the better it can give the correct responses to given questions. For this sharing of data, consent needs to be given in the Business Manager at: Administration _\>_ Global Preferences _\>_ Einstein Search Dictionaries Opt-In ![Einstein Search Dictionaries Opt-In setting used to enable shared-data consent.](/ai-einstein-in-salesforce-b2c-commerce-cloud/einstein-cquotient-shared-database-6ab8c2ae5e_hu_556d8aaa73244c36.webp) Shared data only works when the opt-in setting is enabled for Einstein features. ## Black Box Before we continue with this story about Einstein, one thing to understand is that the general idea is to give merchandisers easy access to AI with point-and-click tools without having to worry about any of the technicalities behind it. This is great on one side. But on the other, it means that Salesforce controls 90% of how the AI does its thing. And we do not get any insights into how it does it unless you work at Salesforce on this particular product. ## Privacy for the consumer For the AI (Einstein) to learn, I already mention it needs to collect quality data. And that data is extracted from the visitors of the SFCC sites: - Categories navigated to - Products viewed - Products added to the basket - Products ordered - … And for this to work, the consumer needs to be tracked. Some visitors will want to block these behaviors by looking at GDPR, CCPA, and [Do Not Track](https://allaboutdnt.com/) options. > **Documentation:** The necessary tools to comply with this are documented in the [Infocenter](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/einstein/b2c_einstein_set_privacy_preferences.html). ## Features ### Product Recommendations - [Trailhead Module](https://trailhead.salesforce.com/content/learn/modules/cc-einstein-product-recommendations) ![Einstein product recommendations rendered in a storefront experience.](/ai-einstein-in-salesforce-b2c-commerce-cloud/sfcc-einstein-product-recommendations-75e024ae7c_hu_50811ce88f86b84c.webp) Product recommendations are the most visible Einstein feature for storefront merchandising. SFCC: Einstein Product Recommendations in the PWA Kit Product recommendations are among the more prominent features available in the Einstein lineup. This feature aims to promote relevant products to an individual shopper based on their purchasing history and current behavior on the site. #### Complete the Set One possible product recommendation type is “Complete the Set,” which recommends products to the shoppers to complete an outfit or to buy accessories that match that specific product. ### Commerce Insights - [Trailhead Module](https://trailhead.salesforce.com/content/learn/modules/cc-einstein-plan-and-implement/cc-ai-work-better) ![Commerce Insights report showing shopper and basket trend data.](/ai-einstein-in-salesforce-b2c-commerce-cloud/commerce-insights-report-c598e1214b_hu_c26e4ca71698ea19.webp) Commerce Insights turns Einstein data into trend reporting teams can actually act on. Einstein: Commerce Insights Report This feature in the Einstein dashboard allows you to view statistical data about products often bought together in the same basket based on the shopper, product, and order data. So, in short: “An analytics tool to view shopper behavior on a product-by-product basis.” ### Search Dictionaries - [Trailhead Module](https://trailhead.salesforce.com/content/learn/modules/cc-einstein-smarter-search/cc-einstein-search-recommendations) ![Einstein search dictionaries suggesting phrases and synonym refinements.](/ai-einstein-in-salesforce-b2c-commerce-cloud/einstein-search-dictionaries-suggestion-phrases-467a548c85_hu_83bc7f519549295e.webp) Search Dictionaries let merchandisers shape synonyms and suggestions instead of leaving them fully automatic. Not a lot to tell about this feature. It looks at your current configuration like synonyms and suggestion phrases… and suggests configuration items that could improve search results for the shoppers. The important thing about this feature is that it only makes suggestions. You still need to accept or reject the recommendations. So to make optimal use of this feature, you should check it often and review the proposals. ### Predictive Sort - [Trailhead Module](https://trailhead.salesforce.com/content/learn/modules/cc-einstein-smarter-search/cc-einstein-predictive-sort) ![Category page showing products reordered by predictive sort.](/ai-einstein-in-salesforce-b2c-commerce-cloud/sfcc-category-page-3297251518_hu_c6f4552013be08a8.webp) Predictive Sort changes category ranking based on shopper behavior, not static merchandising alone. Salesforce B2C Commerce Cloud Category Page The predictive sort option allows Einstein to optimize the “browsing” experience on the category and search pages. By looking at shopper behavior, it will continuously re-order the products in the lister pages so that the products they are most interested in are moved to the top of the results. There are some things to keep in mind when using this feature: 1. Do not rely entirely on Einstein’s Predictive Sort. Add other attributes into the mix. An example on the Trailhead module is like this: 25% revenue, 40% text relevance, and 35% “Predictive Sort” 2. Caching must be disabled on the Categories and Search Results pages (Search-Show for the developers amongst the readers, the tiles can still be cached). So expect a performance hit on these pages. A/B Testing When working with a feature that allows fine-grained configuration like this, it is a good idea to experiment with the sorting weight percentages. And do not forget to A/B test the comparison of Predictive Sort against your regular sorting rules to verify that it is making the difference you were expecting and not lowering the conversion rate. ### Search Recommendations - [Trailhead Module](https://trailhead.salesforce.com/content/learn/modules/cc-einstein-smarter-search/cc-einstein-search-recommendations) ![Search box suggestions generated by Einstein as the shopper types.](/ai-einstein-in-salesforce-b2c-commerce-cloud/sfcc-search-suggestions-d172038c0b_hu_d0f9e5c840ff5246.webp) Search Recommendations start influencing discovery before a shopper even submits a query. Einstein: Search Suggestions Do you ever feel like search suggestions didn’t understand the message you were trying to convey? Einstein is here to help shoppers find the correct products by already aiding at the start of the search. It will analyze your entered search term, look at information like current location and device type, and try to auto-complete the search term for you. > For example, if the shopper types “swe” and they haven’t already searched for sweater or sweat pants, Einstein looks for phrases that start with swe for the device and location. If there’s enough data at that level, Einstein returns a phrase. If there isn’t enough data, Einstein searches across a larger data pool and devices until it finds a result. Trailhead ## Other features ### Feed Einstein data from other channels If you have other channels besides Salesforce B2C Commerce Cloud that can be used to place orders, this data can be fed into Einstein in the form of a [gzipped TSV file](/ai-einstein-in-salesforce-b2c-commerce-cloud/send-ext-order-feeds-to-einstein.pdf). ### Einstein Profile Connector [Using a Headless API](https://developer.salesforce.com/docs/commerce/einstein-api/guide/einstein-profile-connector-overview.html), it is possible to feed additional information about customers to Einstein, such as: - Gender - Favorite colors - Favorite brands And use this information to give more fine-grained recommendations to the shoppers. ### Headless API [Einstein has headless APIs](https://developer.salesforce.com/docs/commerce/einstein-api/guide/einstein-recommendations-overview.html) (besides the one already mentioned above) to send shopper activity and fetch recommendations. An excellent example of a use case is the PWA Kit, which already fully uses these APIs. Other use-cases for these APIs could be: - Recommendations in newsletters or other types of mailings (transactional) - Mobile Application - Customer Service ## Learn more Want to learn more about Einstein? Salesforce has provided a learning path dedicated to Einstein. And it is [publicly available](https://einstein-b2c-exp-salesforce.herokuapp.com/)! --- ## Helpful Salesforce B2C Commerce Cloud Cartridges Canonical URL: https://rhino-inquisitor.com/helpful-salesforce-b2c-commerce-cloud-cartridges/ Markdown URL: https://rhino-inquisitor.com/helpful-salesforce-b2c-commerce-cloud-cartridges/index.md Content type: article Published: 2022-09-20T06:29:08Z Updated: 2022-09-20T06:31:08Z Summary: There are quite a bit of third-party cartridges available for Salesforce B2C Commerce Cloud. Let us look in detail at a few of these! Categories: Salesforce Commerce Cloud, Technical Tags: cartridge, technical ## Key Takeaways - Surveys useful SFCC cartridges from Salesforce and the community beyond the marketplace listings - Highlights practical strengths and limitations of tools like plugin_slas, Resource Manager, and custom feeds - Encourages teams to treat open-source cartridges as accelerators that still need review and upkeep Over the years, an extensive list of cartridges has grown in the [marketplace](https://www.salesforce.com/products/commerce-cloud/partner-marketplace/). These are certified integrations that have gone through a checklist and verified by Salesforce. Whether or not this checklist is as complete as it should be is another topic I will probably give a stab at in a future blog post. But besides these third-party integrations, there are a lot of other cartridges [available on GitHub](https://github.com/SalesforceCommerceCloud). These range from third-party integration to utility cartridges to make our lives a little bit easier. Let us have a look at a few of these! **Note:** If you do not have access to the Salesforce B2C Commerce Cloud GitHub repositories, follow the [documentation](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_development/b2c_github_repo_access.html). ## Custom Feeds [![Custom Feeds configuration screen with a Google feed example.](/helpful-salesforce-b2c-commerce-cloud-cartridges/custom-feed-9148030910_hu_925455260720e6b7.webp)](custom-feed-9148030910.png) Custom Feeds helps teams turn repetitive export work into manageable configuration. - [GitHub Repository Link](https://github.com/SalesforceCommerceCloud/custom-feeds) When a request has come in to generate a “custom” feed towards an external system, this is probably one of the first cartridges that pop up in searches for pre-made solutions. This cartridge allows you to generate Custom XML or CSV feeds from the business manager through a custom-built interface. In a sort of “programming language,” you define the structure of your file and which attributes to print. A convenient cartridge! But there are some things to keep in mind: - **It is old:** Looking at the last commit date being five years ago, it goes without saying that a lot has changed in that period. I have a version kept up to date with all deprecated code removed. So for anyone new to the cartridge, it is no longer plug-and-play. You will need to update a bit of code! - **Complex Use Cases:** Some use-cases that are a bit more complex will require modification to the code. e.g., in the screenshot, you see {{locale}}, this is not available by default and has to be customized to allow the generation of files per locale. - **Demandware library:** Besides being “old,” it is also dependent on a secondary cartridge called “Demandware library.” This cartridge was “abandoned” more than five years ago. - **Heavy Job:** The cartridge uses a job to generate all configured feeds. Remember that the more data you have, the longer the job will run. **With an extensive catalog, it could run for hours!** ## plugin\_slas - [GitHub Repository Link](https://github.com/SalesforceCommerceCloud/plugin_slas) This cartridge integrates the SLAS (Shopper Login and API Access Service) within SFRA. [I have covered this one extensively](/slas-in-sfra-or-sitegenesis/) in a separate article which I recommend reading! ## Resource Manager [![Resource Manager interface inside Business Manager.](/helpful-salesforce-b2c-commerce-cloud-cartridges/resource-manager-4a86b3a33c_hu_423e73d3b5316a48.webp)](resource-manager-4a86b3a33c.png) Resource Manager is useful because it exposes content and configuration teams usually script around. - [GitHub Repository Link](https://github.com/SalesforceCommerceCloud/resource-manager) Most people involved with Salesforce B2C Commerce Cloud will have probably asked or get the question(s): “Can we work with translations easier?”, “Can we quickly deploy this translation to production?” and many more in that area. Since translations are part of the code (resource files), they depend on the code’s release cycles. This can be a very long time for translations to wait for a simple change. The Resource Manager project is an attempt to answer these questions. It moves translation management from the code repository to the Business Manager by cleverly using the [Velocity Template](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_development/b2c_velocity_templates.html) system. There are some things to keep in mind when switching to this method: - **Initial Migration:** If you are already live with a large number of translations, you will have to think carefully and plan your migration as it takes a few steps to do (conversion of property files to custom objects) - **Site-Specific:** With this setup, all of your translations become site-specific. If you have a lot of different sites in your structure, maintenance could become tricky. - **Instance Specific:** Since translations are stored in custom objects, they are instance-specific (sandbox vs. staging vs. development vs. production) - **Sandboxes:** Resource Manager is designed with replication in mind, but not your sandboxes. So a workflow needs to be thought up to keep all instances up-to-date with all translations. ## Page Designer Plus [![Page Designer Plus example showing enhanced page-building components.](/helpful-salesforce-b2c-commerce-cloud-cartridges/page-designer-plus-9eedd5b72f_hu_ad763c5b55b59601.webp)](page-designer-plus-9eedd5b72f.jpg) Page Designer Plus extends the native experience where standard Page Designer starts to feel cramped. - [GitHub Repository Link](https://github.com/SalesforceCommerceCloud/link_royalcyberpd) People who follow [Royal Cyber Inc.](https://www.linkedin.com/company/royal-cyber-inc-/) on LinkedIn have probably seen this cartridge pop up in their feed. But a little-known secret is that this is available on GitHub for anyone to use (for now)! This cartridge adds new page types and components to Page Designer: - HTML Markup - Video - Slider - Content Assets within Page Designer - … ## Commerce Cloud Libraries - [GitHub Repository Link](https://github.com/taurgis/salesforce-commerce-cloud-libraries) A little bit tooting my own horn, but I honestly believe this collection of cartridges is something people should at least know exists. A few years ago, I was frustrated that I couldn’t use a few popular libraries on the server-side of Salesforce B2C Commerce Cloud. So I set out to convert a few to cartridges: - Moment.js - Lodash - date-fns - fast-XML-parser - chance - ramda - jsPDF The list hasn’t grown much in the last two to three years (I switch side projects a little bit too much). But the most recent addition (jsPDF) [received an extensive blog post](/pdf-and-salesforce-commerce-cloud-b2c/). ## B2C CRM Sync [![A slide from the B2C CRM Sync presentation showing a list of advantages and features.](/helpful-salesforce-b2c-commerce-cloud-cartridges/b2c-crm-sync-96c282e333_hu_fb116f90701e19e3.webp)](/helpful-salesforce-b2c-commerce-cloud-cartridges/b2c-crm-sync-96c282e333.gif) - [GitHub Repository Link](https://github.com/SalesforceCommerceCloud/b2c-crm-sync) This might seem a little out of place than the others as “multi-cloud.” The main goal of this solution is to link Salesforce B2C Commerce Cloud and Salesforce CRM together, and it does it well. But why is it in there? Well, it is an excellent source of inspiration for other cartridges or tools for your projects: - **CLI:** The entire system can be set up using an environment file and commands. The commands include deploying code and running jobs. A great cheat sheet if you ask me! - **CRM:** Integrations with other platforms of Salesforce have happened more often in recent years; this gives you a sound basis for setting up your connection! ## And many more There are [a lot of cartridges like this](/community-repositories/) out there, and covering them all is quite impossible. If you have an interesting one to share, [reach out on LinkedIn](https://www.linkedin.com/in/thomas-theunen-10905680/). --- ## A new Commerce Cloud community in town! Canonical URL: https://rhino-inquisitor.com/a-new-commerce-cloud-community-in-town/ Markdown URL: https://rhino-inquisitor.com/a-new-commerce-cloud-community-in-town/index.md Content type: article Published: 2022-09-12T08:14:56Z Updated: 2022-09-12T17:52:21Z Summary: After Connections '22, I decided to have a look into Trailblazer Communities and how one could start a group! Let's embark on a new journey! Categories: Community Tags: ohana, sfcc ## Key Takeaways - Introduces the Benelux Salesforce Commerce Cloud community and its purpose - Explains who is leading the group and which audiences and products it targets - Invites readers to the first session and encourages topic and speaker submissions Starting a community was a plan I have had in my head for a while now but never acted on - with what was going on in the world: a pandemic, a war, and an economic crisis. The list never ends with reasons to delay, so I stopped waiting and plowed ahead! And at the end of August, I got the mail titled “Welcome to the Trailblazer Community Group Program!” I got accepted! But … oh damn … now I have to push on! [![Trailblazer Community Group welcome banner for the Benelux commerce community.](/a-new-commerce-cloud-community-in-town/join-the-salesforce-benelux-commerce-cloud-community-v4-afd7195f3b_hu_aaa3f9d300ffe459.webp)](https://trailblazercommunitygroups.com/salesforce-developer-group-hasselt-belgium/) ## What’s in a name So let’s get one confusing part out of the way. The group is called “[Salesforce Developer Group, Hasselt, Belgium](https://trailblazercommunitygroups.com/salesforce-developer-group-hasselt-belgium/),” but the only reason for that is the rules of engagement with the Trailblazer Community Groups. The actual name for the group is: “**Benelux Salesforce Commerce Cloud Community**.” Ok, that name might not be “the best” either, but it describes the group’s goal a lot better! ## Community Group Leaders Setting up and running a community is not easy, and that is why I will not be doing this alone! To ensure the group will continue to thrive, not depending on one person to keep it alive, I will do this together with two others! A big thanks to them for making this community happen! ### Wouter de Boer - [View profile](https://www.linkedin.com/in/wouterdeboer) Wouter is the lead Architect at [Wolfpack Agency](https://www.wolfpack-agency.com/), designing solutions for Salesforce B2C/B2B Commerce Cloud, Service Cloud, and Marketing Cloud. With 7+ years of knowledge of the Commerce Cloud (Demandware), he started as a developer, giving him a deep technical understanding of the platforms he works with today. ### Kiran George - [View profile](https://www.linkedin.com/in/kirantgeorge) Salesforce technical/solution consultant with a deep affinity towards Ecommerce and the Salesforce platform’s omnichannel possibilities. Working with SFCC/Demandware since 2011. Still fond of working with pipelines. Currently living in Amstelveen, NL . Co-Founder of [CommerceForz](https://www.commerceforz.com/). ### Thomas Theunen - [View profile](https://www.linkedin.com/in/thomas-theunen-10905680) Thomas started in 2011 as an Intershop Commerce developer and, after seeing the light six years later, switched to Salesforce B2C Commerce Cloud. Spreading his wings, Thomas learned about multiple products of Salesforce over the past few years to implement multi-cloud projects (Commerce, Service, and Marketing.) Leading a team of 60, Thomas is currently the Head of Commerce at [Forward](https://www.forward.eu). Since 2021 Thomas is also a Salesforce Instructor for the ARC300 (B2C Commerce Architect) course and, since 2022, the recipient of [the first Belgian and Commerce Cloud Golden Hoodie](/events-and-the-golden-hoodie/). Besides keeping himself busy with Salesforce during working hours, he owns a Salesforce B2C Commerce Cloud Blog: [https://www.rhino-inquisitor.com/](/), where you can find the latest news about the platform! ## The goal The main goal of this community group is to gather all Salesforce Commerce Cloud enthusiasts in the Benelux: - Developers - Merchandisers - Project Managers - Business Analysts - Job-hunters And what about products? Anything within the Salesforce Commerce Cloud range of products: - B2C Commerce Cloud - B2B Commerce Cloud - B2B2C Commerce Cloud - OMS - OCI - Commerce Marketplaces (Atonit) ### What about people outside of the Benelux As the language of choice will be English, global attendees are more than welcome to join the Hybrid and Virtual meetings! ## When is the first meeting Very soon! The first session is scheduled for the [6th of October](https://trailblazercommunitygroups.com/events/details/salesforce-salesforce-developer-group-hasselt-belgium-presents-lets-get-to-know-each-other/)! ## What will be the topics The topics will range from technical workshops to networking events. Some ideas that I have for topics are: - How to get started with B2C Commerce Cloud? - How to get started with B2B Commerce Cloud? - B2C vs B2B vs B2B2C - The future of Salesforce Commerce Cloud - OMS and Commerce Cloud, how does it work? - How does Composable and Headless fit into the Salesforce ecosystem - How to get certified - …. Have ideas in mind of your own? Then join the 6th of October session or [reach out on LinkedIn](https://www.linkedin.com/in/thomas-theunen-10905680/)! [![Announcement card for the community's first get-to-know-each-other session.](/a-new-commerce-cloud-community-in-town/get-to-know-each-other-v2-60539cfd30_hu_1c310fafe1b38051.webp)](https://trailblazercommunitygroups.com/events/details/salesforce-salesforce-developer-group-hasselt-belgium-presents-lets-get-to-know-each-other/) ## Looking for speakers Have something to share with everyone; no matter where you are, I want to make it happen! So please send me a mail at [thomas.theunen@trailblazercgl.com](mailto:thomas.theunen@trailblazercgl.com) or contact me on [LinkedIn](https://www.linkedin.com/in/thomas-theunen-10905680). --- ## Inside the Ohana Canonical URL: https://rhino-inquisitor.com/inside-the-ohana/ Markdown URL: https://rhino-inquisitor.com/inside-the-ohana/index.md Content type: page Published: 2022-09-11T08:34:33Z Updated: 2022-09-11T08:36:40Z Summary: Episode Summary - Thomas Theunen, Head of Commerce at Forward and the first Belgian Golden Hoodie winner, shares practical tips! Categories: Podcasts, Video The original recording linked to this page is currently unavailable on YouTube. An interview of my story within the Ohana and how I found my way into a beautiful community of Salesforce enthusiasts! --- ## Life With Goldie Canonical URL: https://rhino-inquisitor.com/life-with-goldie/ Markdown URL: https://rhino-inquisitor.com/life-with-goldie/index.md Content type: page Published: 2022-09-11T08:28:07Z Updated: 2022-09-11T16:31:42Z Summary: A fun interview about my journey within the Salesforce Ohana and how I received my Golden Hoodie in 2022 at Salesforce Connections. Categories: Podcasts, Video The original recording linked to this page is currently unavailable on YouTube. A fun interview about my journey within the Salesforce Ohana and how I received my Golden Hoodie in 2022 at Salesforce Connections! There are only about a hundred Golden Hoodies worldwide, so getting one presented to you by Salesforce is pretty rare. [Being the first in Belgium](/events-and-the-golden-hoodie/) to receive one and the first Commerce Cloud community member is quite an honor! Hopefully, more Commerce Cloud community members will be presented with a Golden Hoodie in the future, but only one person can be the “first”! So how do you get one? This is a question I have gotten quite often in the past few months since receiving one, but there isn’t really “one thing” that you should do. Salesforce decides who gets one, which is an entirely different system than the MVP one. Putting it as simply as possible: “[Get noticed](/community-salesforce-events-and-commerce-cloud/) by the community, and more importantly by Salesforce with your efforts towards Salesforce customers and the community.” --- ## Headless Canonical URL: https://rhino-inquisitor.com/headless/ Markdown URL: https://rhino-inquisitor.com/headless/index.md Content type: page Published: 2022-09-11T08:06:14Z Updated: 2022-09-11T08:23:01Z Summary: A short headless-commerce primer from Thomas Theunen on why decoupled storefronts change customer experience and delivery flexibility. Categories: Podcasts, Video Play video If your organization is looking for a way to improve its online presence and connect with more customers, Headless may be a good fit. Headless can help you create a more modern and responsive website and enhance customer engagement and conversions. Headless commerce can provide a better user experience. In a traditional eCommerce setup, the front and back end are often tightly coupled, making it difficult to change the front end without affecting the back end. However, with a headless commerce setup, the front end can be developed independently of the back end, allowing for a more customized and personalized user experience. --- ## The path to being an Architect Canonical URL: https://rhino-inquisitor.com/the-path-to-being-an-architect/ Markdown URL: https://rhino-inquisitor.com/the-path-to-being-an-architect/index.md Content type: page Published: 2022-09-11T07:39:31Z Updated: 2022-09-11T07:50:23Z Summary: A podcast conversation about moving from hands-on development into solution, technical, and enterprise architecture roles in commerce delivery. Categories: Podcasts, Video Play video The journey to being an architect has assumed many forms over the years, and does it all start at development? I started as a Java developer more than a decade ago and slowly moved towards being a “Salesforce Solution Architect But Solution Architect is only one of the many architectural roles that exist. Technical Architects and Enterprise Architects have their own roles within a project, and these different titles will most likely collaborate over one or many tasks in a brand/business. This podcast episode discusses how I have experienced this journey and what to expect from the changes that will happen in your day-to-day job. It is a journey about growth and learning how a platform works and learning how to connect it with other systems that live in every commerce architecture..” --- ## Me, Myself, and Headless: A Composable Commerce Cloud story Canonical URL: https://rhino-inquisitor.com/me-myself-and-headless-a-composable-commerce-cloud-story/ Markdown URL: https://rhino-inquisitor.com/me-myself-and-headless-a-composable-commerce-cloud-story/index.md Content type: page Published: 2022-09-10T17:03:23Z Updated: 2022-09-11T07:34:06Z Summary: A session on Salesforce Commerce Cloud's headless direction, PWA Kit, and what composable architecture means for existing implementation teams. Categories: Sessions, Video Play video Salesforce Commerce Cloud has shifted its focus to investing in Headless development for the past two years. Mobify was acquired and rebranded to PWA Kit And Managed Runtime, providing the next headless storefront offering. But the PWA Kit requires an entirely new way of development in React.js. Does that mean the knowledge you have built up of the Salesforce Commerce Cloud products will be thrown into the trash can in a few years? What if you don’t like React.js? And what does “Composable Commerce” mean? Many terms are thrown around, confusing the Commerce space. At the end of this presentation, we hope to have eliminated some of this confusion. --- ## Connecting the Clouds: Wedding or funeral Canonical URL: https://rhino-inquisitor.com/connecting-the-clouds-wedding-or-funeral/ Markdown URL: https://rhino-inquisitor.com/connecting-the-clouds-wedding-or-funeral/index.md Content type: page Published: 2022-09-10T16:53:02Z Updated: 2022-09-10T20:12:59Z Summary: A session on the real-world challenges of connecting B2C Commerce Cloud, CRM, and Marketing Cloud across security, GDPR, and delivery constraints. Categories: Sessions, Video Play video Connecting different clouds, in this case: B2C Commerce Cloud, CRM, and Marketing Cloud, to work together in harmony can be a challenge. Theoretical guidelines and base solutions are provided by Salesforce to get you started, but are these sufficient to connect the clouds? In this session, we will find out! Over the past five years, we have done multiple multi-cloud projects and have run into those challenges head-on (security, GDPR, robustness, and more). In this presentation, we share lessons learned, things to be mindful of, and different use cases for connecting the clouds, from greenfield implementation to connecting live silo systems. Experience in multi-cloud or not, it does not matter. This presentation offers practical starting points, pitfalls to watch for, and guidance on what to keep in mind when shaping a multi-cloud project. --- ## A look back at Origin Shielding Canonical URL: https://rhino-inquisitor.com/a-look-back-at-origin-shielding/ Markdown URL: https://rhino-inquisitor.com/a-look-back-at-origin-shielding/index.md Content type: article Published: 2022-09-07T19:53:27Z Updated: 2022-09-07T19:53:35Z Summary: Salesforce B2C Commerce Cloud activated Origin Shielding on production in August 2022. But for some, it did not go as planned. Why? Categories: Community Tags: ohana, security, sfcc, technical ## Key Takeaways - Argues origin shielding issues were often caused by missed communication, not the feature itself - Shows how critical updates were spread across many channels over more than a year - Recommends broader internal distribution so platform notices do not rely on one person September has shown its face, and the sunny weather (at least here) is ending. And with that also the complete activation of [Origin Shielding](https://help.salesforce.com/s/articleView?id=000364472&type=1), or it simply: “Putting everything behind the eCDN.” For most, this change had little effect as it meant switching all third-party integrations from the demandware.net domain to the brand vanity domain. But for some, this was not a fairytale story. Why is that? **Note:** This article is pure speculation on my part, and I did not look at which percentage of Salesforce B2C Commerce Cloud customers did not have the “fairytale story.” Even though this percentage is probably on the low side, I do feel the need to look at the possible cause. ## Communication The first thing to make people aware of a change is communicating it to them as soon as possible. And from personal experience, I did get this notification quite a while in advance. I looked back in my documents and e-mails and found the first reference to this change in July 2021! A year in advance! [![First communication about origin shielding from July 2021.](/a-look-back-at-origin-shielding/origin-shielding-first-mention-9d41cb51f2_hu_f8891c69d122c197.webp)](origin-shielding-first-mention-9d41cb51f2.jpg) But, of course, the information given back then was pretty vague. And the impact on projects could not be estimated by this alone. ### What about 2022 Months go by without any mention of this change, but I did know that this “Origin Shielding” for “dotted” URLs (i.e., [http://production.xxx.demandware.net/](http://production.xxx.demandware.net/)) was [already active for new customers since June 21’](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_selective_origin_shielding_w9343605_je.htm&type=5). In March, I joined the B2C Roadmap Session again (or a different webinar, I can’t remember), and here we got the announcement for “phase 2”: Origin Shielding activation for ‘hyphenated’ URLs (i.e., production-xxx.demandware.net). [![March 2022 roadmap slide announcing the next origin shielding phase.](/a-look-back-at-origin-shielding/march-2022-origin-shielding-815c30777b_hu_67af49aa6c5d90ff.webp)](march-2022-origin-shielding-815c30777b.jpg) So again, quite a bit in advance: about six months to change demandware.net to your vanity domain. Over the months, this was shared across multiple channels: Trailblazer Communities, Webinars, [and slides shared with the release notes](https://help.salesforce.com/articleView?id=b2c_rn_release_notes.htm&type=5). I probably missed other media that might have been customer-facing. But as a partner, I do not get these. All in all, quite a lot of warnings ahead of time. ## Monitoring of these channels But for communication to work, you need a second crucial thing to happen: “People need to read or view your communication.” And honestly, I believe this is where the issue lies. Over the past few years, I have been monitoring multiple channels to stay up to date with everything: - Trailblazer communities - Partner communities - Webinars - Round tables - Slacking with people and monitoring different Slack channels Without making all this effort, I would have missed quite a lot of vital information (which I probably did before I started monitoring.) Most of all, when I talk about all of these channels - especially the Partner Community - it appears that most people do not know these existed in the first place! And that is a problem because a lot of communication only happens there. If we look at all information about On-Demand-Sandboxes, I think about 95% of the communication happens in [a dedicated Partner Community](https://partners.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F93A000000DQ6f). ### Single point of failure But what if someone is monitoring this communication (or has received an email) but is not sharing it with everyone? Or maybe the person receiving the communication is no longer working at the company, causing vital communication to be missed. I think it is essential that multiple people receive these notifications, so maybe it makes sense to set up a mailing list rather than having a single person receive this communication. ## Who is to blame This question probably drove you to this article. But sorry to disappoint, I don’t feel anyone is to blame here. Partners and customers should be aware of these communities and subscribe to appropriate channels. But Salesforce needs to make people aware that these channels exist, and maybe they do - but do not express the value that monitoring these channels brings. I have brought all these sites into our onboarding process to ensure everyone can access this valuable information. But in the end, it is up to the individual to do the necessary actions of subscribing. So, in conclusion, work needs to be done on all sides! And hopefully, this article has made people aware of these channels and the value they bring. --- ## Let's GO-LIVE: SEO Canonical URL: https://rhino-inquisitor.com/lets-go-live-seo/ Markdown URL: https://rhino-inquisitor.com/lets-go-live-seo/index.md Content type: article Published: 2022-09-05T08:35:42Z Updated: 2022-11-19T10:02:48Z Summary: Bringing your first site live on SFCC can be challenging. In this series, we will be looking at different parts. Part 3: SEO Categories: GO-LIVE, Salesforce Commerce Cloud Tags: sfcc, technical ## Key Takeaways - Frames SEO as a launch-critical workstream that must start well before go-live - Explains why SEO delivery depends on coordination across content, product, commercial, development, and specialist teams - Emphasizes clear requirements and continuous SEO validation instead of assumption-driven implementation When going live with a website, SEO is an integral part that should not be overlooked. It is a long-term strategy that should be started before your website goes live. This article is part of a [GO-LIVE series](/category/go-live/) that should give you all the tools necessary to have a comfortable release! ## What is SEO Let us start with the basics here; what is SEO? Well, it stands for [Search Engine Optimization](https://en.wikipedia.org/wiki/Search_engine_optimization). This is a process you want to use to ensure that the people looking for your site or a specific part (products most likely in the Salesforce B2C Commerce Cloud space) can easily find that page. The people who use a search engine and consequently find the page are called “organic” traffic, a term you will come across quite often when working on traffic analytics data. ## Why should I care I think the answer to that question is quite obvious! Any owner of a website/store wants to drive traffic to it. And optimizing a website so that Search Engines and other channels will put those pages at the top of the results is a fundamental way to do that. ## When should I start the analysis and investigation This will depend on the project and who you have available (maybe a specialist is in the team that focuses on this?). But a general rule of thumb is to start as soon as possible, as SEO can impact a project on multiple levels. Depending on the requirements, this can be on the business or development side. ## It is a team effort Doing optimizations to the SEO of your site requires the involvement of many different people in and out of the organization. Think of it this way: to get good SEO, you need good quality data and content. And someone needs to write that content, push it to the correct channels, translate it if necessary to all supported languages, … So involvement is required from: - The team managing the marketing/content - The team managing the product data ( PIM, ERP, … ) - The commercial team - The development team - … - Oh… and the SEO team 😎 That is a lot of people that need to talk to each other, right? Unless someone manages all the above on their own (good luck to them)! Make sure to get these parties around the table when needed! You do not need to involve everyone all the time, but for most requirements, it is pretty evident who you need to invite. e.g., “We need a good product description to show on the product detail page” will require the involvement of at least three parties listed above. (I will let you think about which ones) And before I forget, the above is an excellent example of a “vague description.” So maybe we should have clear requirements? ## Clear requirements The rules of SEO change often, and experimentation is part of the game. Developers know quite a few rules of engagement, but will never be as educated as someone specializing in this topic. When creating requirements for the development team, give as much information on what you are trying to achieve and how. Do not leave too much to guesswork, as this could hurt your efforts in the long run. If a requirement was not described in as good detail as it should, making the developer take “assumptions,” the amount of time to recover from possible damage could be months. SEO takes time SEO improvements (in most cases) do not pay off visibly in days or weeks. Some can take months to show their “worth” or their “damage.” ## Involvement of the SEO team I talk about a team, but this could also be a single person (internal or hired gun). In any case, it is essential to involve them every step of the way. And that includes the validation of the implementation. Even if a requirement was clear, some things might not be implemented correctly. Or maybe the required data wasn’t provided by the PIM? Then the development work was done, but the data quality needs improvement. Detecting these issues/challenges as early as possible is critical to your strategy. But that doesn’t only apply to SEO, now does it? ## Where do I start I am not someone who likes to re-invent the wheel or write an article when there is already great content about all the different steps in a project and how to configure Salesforce B2C Commerce Cloud. So here is a list of some great articles by [Edwin Romero](https://www.linkedin.com/in/edwinromero/): - [SEO Glossary](https://www.edwindanromero.com/seo-glossary/) - [How to do an SEO Project Plan](https://www.edwindanromero.com/seo-project-plan/) - [Salesforce Commerce Cloud SEO Guide](https://www.edwindanromero.com/salesforce-commerce-cloud-seo-guide/) (The Business Manager Explained) - [Site Migration](https://www.edwindanromero.com/website-migrations-seo-timeline-of-launch-essentials/) There is much more great content available on his site! So be sure to do a bit of perusing. --- ## The deprecation of the UUID Token for API Clients Canonical URL: https://rhino-inquisitor.com/the-deprecation-of-the-uuid-token-for-api-clients/ Markdown URL: https://rhino-inquisitor.com/the-deprecation-of-the-uuid-token-for-api-clients/index.md Content type: article Published: 2022-08-29T07:37:05Z Updated: 2023-03-03T12:25:16Z Summary: Salesforce announced the deprecation of the UUID access token that you can use for integrations with SFCC. But what does it mean? Categories: Salesforce Commerce Cloud, Technical Tags: headless, ocapi, security, sfcc, technical ## Key Takeaways - Explains the deprecation of UUID bearer tokens for SFCC API clients and the move toward JWT access tokens - Shows how to switch an Account Manager API client from UUID to JWT and what changes downstream integrations should expect - Highlights the practical migration concern that longer JWT tokens may require validation with third-party systems and storage layers Last week (end of August 2022), many received an email warning us of a change to integrations in 2023: “Deprecation Announcement for UUID Token for API Clients in Account Manager.” But what does this mean? And what can be done to make sure integrations keep working? Update ( 03/03/2023 ) A date has been published: [June 15th 2023.](https://help.salesforce.com/s/articleView?id=000394343&type=1) ## UUID Token When doing an OAuth integration with Salesforce B2C Commerce Cloud, you must set up an “[API Client](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/account_manager/b2c_account_manager_add_api_client_id.html)” in Account Manager. During this process, you have the option of choosing which type of “bearer (access) token” format you want to use: - JWT - UUID **Note:** Currently the default is JWT, but I am not sure if the default was UUID before. [![Account Manager screen showing API client token format options.](/the-deprecation-of-the-uuid-token-for-api-clients/account-manager-api-client-token-format-808bcccc72_hu_6cb0aeac90fccde9.webp)](/the-deprecation-of-the-uuid-token-for-api-clients/account-manager-api-client-token-format-808bcccc72.jpg) ## How do I change it Changing your API Client from UUID to JWT is a straightforward process. You go to [Account Manager](https://account.demandware.com/), open your API Client and go to the “Access Token Format” shown on the screenshot in the previous section. Change that option from UUID to JWT and click “Save”! That’s it! Easy isn’t it? ## What is the effect of this change Not a lot actually. To put it as “simple” as possible: “**Your bearer token becomes a much larger string.”** Your bearer token changes from a simple and short UUID to a [JWT](https://jwt.io/). ```text // An examle of a UUID token response to: // URL: https://account.demandware.com/dw/oauth2/access_token { "access_token": "aEVhfDrzSoQ23Xd1m9m-nb8PKL4", "scope": "mail", "token_type": "Bearer", "expires_in": 1799 } ``` The above token is 27 characters long, which does not leave much room for “usable information.” A JWT is much more suited for that. So let me change this API Client to the JWT format! ```text // An examle of a JWT response to: // URL: https://account.demandware.com/dw/oauth2/access_token { "access_token": "<sample-jwt>", "scope": "mail", "token_type": "Bearer", "expires_in": 1799 } ``` Pfoo… that is quite a bit longer, isn’t it? About 1269 characters, which is a lot more than 27! But that is because this access token contains much more information than the UUID we previously saw. ### Call other APIs using this token Like before, you can use the (longer) token to call other APIs. ## What information can be found in the JWT To figure that out, we need to [undo the encoding](https://jwt.io/) of our “access\_token”. If we do that, we get the following information: ```json { "sub": "a2b32fe3-9373-4ca1-b643-60355a6cefe2", "cts": "OAUTH2_STATELESS_GRANT", "auditTrackingId": "ac7b2645-e71b-49a9-8539-2846ea449d1a-272809643", "subname": "a2b32fe3-9373-4ca1-b643-60355a6cefe2", "iss": "https://account.demandware.com:443/dwsso/oauth2", "tokenName": "access_token", "token_type": "Bearer", "authGrantId": "WAHrDv5q2Vpuf4BlBQbxIUqVR2E", "aud": "a2b32fe3-9373-4ca1-b643-60355a6cefe2", "nbf": 1661757640, "grant_type": "client_credentials", "scope": [ "mail" ], "auth_time": 1661757640, "realm": "/", "exp": 1661759440, "iat": 1661757640, "expires_in": 1800, "jti": "baXcufo3e0YqvJMadXlES5c8AjA", "client_id": "a2b32fe3-9373-4ca1-b643-60355a6cefe2" } ``` That is a lot more information to work with, which is why this change is happening! ## Why do this change Before we get started, I do not work for Salesforce! So I will be making some assumptions here based on the small amount of information that has been shared. The change itself makes sense. Because the UUID does not contain much information, the Account Manager needs to “fill in the blanks” when doing an authentication call. This causes extra “strain” on the servers (probably additional database calls and processing) to fetch certain information and do validation. This change will cause the Account Manager load to drop, leaving more room for other, more important things. And in the end, make the solution more scalable for the future! ## When should we migrate Just be sure to contact your third-party integration teams about this change. Why? Because it needs to be verified if they can handle this longer token. We are going from 27 characters to more than a thousand, which could mean database changes need to be made to facilitate this change. Update ( 09/15/2022 ) Currently, not all Use Cases support JWT - and Salesforce is required to make changes on their end. This is (probably) why they have not yet communicated a timeline/deadline. Tobias Lohr has provided a help article to explain which cases only work using UUID (for now): [https://github.com/SalesforceCommerceCloud/sfcc-ci/wiki/Token-format-change-from-UUID-to-JWT](https://github.com/SalesforceCommerceCloud/sfcc-ci/wiki/Token-format-change-from-UUID-to-JWT) There is no time like the present. Even though you will probably have a year (possibly more - possibly less - depending on when this is planned in 2023), I see no reason to postpone this change. It is a relatively small change that can easily be tested. --- ## 20 years of Dreamforce Canonical URL: https://rhino-inquisitor.com/20-years-of-dreamforce/ Markdown URL: https://rhino-inquisitor.com/20-years-of-dreamforce/index.md Content type: article Published: 2022-08-24T19:21:06Z Updated: 2022-11-19T10:06:22Z Summary: Get ready for Dreamforce 2022 with a quick look at the event's 20th anniversary, standout commerce sessions, and what to watch on site. Categories: Community Tags: ohana, sfcc ## Key Takeaways - Highlights commerce-focused Dreamforce sessions worth adding to your agenda - Explains where the Commerce Lodge and community meetups fit into the event - Recommends balancing learning, networking, and flexibility during Dreamforce **Note:** I gave the text “20 years of Salesforce Dreamforce” to an AI to render an image. The image you see above is what it created! Salesforce is celebrating 20 years of Dreamforce, which is quite a track record! As with all Salesforce events, it is the opportune moment to meet people, learn and have fun! But how does Salesforce B2C Commerce Cloud fare in this large event, and what content is available? Let’s have a look! ## Let us meet up ![Dreamforce attendee checking a phone in a lounge area.](/20-years-of-dreamforce/dreamforce-cosy-c3b16ff3d4_hu_e26e1dec1a42fb4c.webp) Ok... don't be on your cellphone the entire time! It won’t be a Salesforce event if you don’t meet with other people you have been “slacking” with for the past years. There is already a channel on the Salesforce B2C Commerce Cloud Unofficial Slack to connect! [Join the SFCC Unofficial Slack](https://docs.google.com/forms/d/e/1FAIpQLSdy875PlJuib35naCkr3-Frn2qtaSuuRgYezRSb2uBYkhXt7g/viewform) or [open the existing channel](https://sfcc-unofficial.slack.com/archives/CC62W7S5C). I will be there this year! It will be my first Dreamforce, and coincidentally, it is my birthday on the 21st of September! Even though there is no “official” meetup on the schedule, it doesn’t mean we can’t get together! Be sure to also leave a message in the [Commerce Trailblazers](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000HFCBv) group to make it ✨extra special✨! ### Commerce Lodge The Commerce Cloud Lodge is a dedicated zone where Trailblazers and commerce experts across industries will come together to learn, connect, and celebrate in a creative space. Be sure to look at the map to locate it. Curated roundtables, workshops, and demos will be held here to light the spark of inspiration and show how Commerce Cloud can help make every transaction more profitable. The Commerce Cloud Lodge will be a ‘can’t-be-missed’ destination for the community. There will be a dedicated space within the Lodge for Trailblazers to meet, mingle, and even get some work done a few hours each day! Seats are limited to 16 people, but I am sure we can find ways to make it work! (I am hoping we can have a large gathering!) ## Trailhead Quest Want to learn more about Dreamforce and how to connect with your peers? And even win some fun prizes\* while you are at it? Do the “[Road to Dreamforce 2022](https://trailhead.salesforce.com/users/teamtrailhead/trailmixes/quest-road-to-dreamforce-2022)” quest! ## Can’t attend The keynotes can be viewed through [Salesforce+](https://www.salesforce.com/plus/experience/Dreamforce_2022) for free! ## Building your agenda​ ![Notebook and laptop laid out while planning a conference agenda.](/20-years-of-dreamforce/writing-agenda-ba6ec896c4_hu_e8e1a8793270d625.webp) There are about 1200 sessions over three days at Dreamforce. Building a schedule will not be an easy task! And be sure your predefined schedule will be thrown in the trash when the day arrives. You will bump into people unexpectedly and change your pace and goals for the day on the spot! And there is nothing wrong with that. This event should be a balance of learning, networking, and fun! Salesforce provides a handy tool to [build your schedule on the Dreamforce website](https://reg.salesforce.com/flow/plus/dreamforce22/maincontentcatalog/page/Catalog). ## Sessions that stand out I created a schedule in previous editions of this event post ([TrailblazerDX](/trailblazerdx-2022-for-b2c-commerce/) and [Connections](/get-connected-at-salesforce-connections-2022/)). This time I will list the sessions that stand out or have exciting speakers! You will probably notice that I made sure to make the people active in the Salesforce Commerce Cloud community (Salesforce employees included) stand out a “little bit [😝](https://emojipedia.org/squinting-face-with-tongue/).” For now, session length and time are not known yet. I will update the article once this information is made public. > **Community Speakers** Did I miss someone? Please don’t be shy and [send me a message on LinkedIn](https://www.linkedin.com/in/thomas-theunen-10905680/)! ### Next-Gen Commerce: Maximize Profit Your Way - [Kimberley Zatlyn](https://www.linkedin.com/in/kimberleyzatlyn/) - [Michael Affronti](https://www.linkedin.com/in/michaelaffronti/) - [Erin Dorshorst](https://www.linkedin.com/in/erindorshorst/) - [Amanda Hatker](https://www.linkedin.com/in/amandahatker/) - Katherine Ferguson - Sharon John - Keynote > Join the main event for commerce pros and learn how to maximize profit, cut costs, and build a Customer 360 your way with flexible tools, automation, and the Customer Data Platform. The main keynote of Salesforce Commerce Cloud! No reason not to miss the main event and learn what is in store for the commerce landscape in Salesforce. ### 5 Best Practices for a Frictionless Checkout - Cassandra Funk - Aesh Verma - Theatre Session > Get insider insights from a team of payments experts as we share the best practices for creating payment experiences that are seamless and frictionless. Getting UX advice and learning how to improve your checkout experience is always a topic of interest! ### 6 Steps to a Successful Headless Commerce Implementation - [Pei En Thong](https://www.linkedin.com/in/thongpeien/) - [James Semple](https://www.linkedin.com/in/james-semple-8884093b/) - Karly Cyr - Theatre Session > Implementing a headless architecture is no small feat. This session for business leaders outlines 6 key steps to headless transformation success — bringing people, technology, and processes together. Given the more prominent focus on allowing customers to go Headless on the Salesforce Commerce Cloud products, getting some tips and tricks are always helpful! ### Architect’s Guide to Building a Cross-Cloud Career ![Community speaker spotlight graphic used for featured sessions.](/20-years-of-dreamforce/community-speaker-9f72758dd2_hu_99e949c772c49eec.webp) A community-led session focused on building a stronger cross-cloud career path. - [Mike King](https://www.linkedin.com/in/mikeeking/) - Theatre Session > Breaking into a cross-cloud solution architect role can be a big challenge. Learn three steps to build valuable cross-cloud skills and increase your value as an architect. For me, an exciting session as I have been focussing on connecting multiple clouds within the Salesforce ecosystem. And I am pretty sure I am not alone on this! And it is being presented by Mike King! ### B2C Commerce Product Roadmap - [Igor Faletski](https://www.linkedin.com/in/igorfaletski/) - [Alex Bucher](https://www.linkedin.com/in/alexbucher1/) - Theatre Session > Learn first-hand how upcoming B2C commerce features deliver on exceptional holiday performance, composable storefronts for headless, TikTok and SnapChat integrations, and more. Getting insights into the roadmap for the upcoming holiday season and social commerce is something to keep your eye on! Who knows, I might be wearing a new fitting shirt design. ### Architect’s Review of Cross-Cloud Customer Data Modeling ![Community speaker spotlight graphic used for featured sessions.](/20-years-of-dreamforce/community-speaker-9f72758dd2_hu_99e949c772c49eec.webp) A community session on cross-cloud customer data modeling and architecture. - [Mike King](https://www.linkedin.com/in/mikeeking/) - [Melissa Murphy](https://www.linkedin.com/in/melissa-murphy-312681b8/) - Theatre Session > A well-designed cross-cloud customer data model is the foundation of successful architecture. Learn to model data across the Salesforce ecosystem and design best practice solutions. Same as the previous session of Mike King. I am quite a large fan of sharing knowledge about cross-cloud architecture! Especially when working with customer data, a well-architected foundation is a requirement! ### Headless Unpacked: How Retailers Build API-Led Experiences - [Jameson Wildwood](https://www.linkedin.com/in/jtwildwood/) - Theatre Session > The future of commerce is headless. Delve into the story of how VF Corp used MuleSoft APIs and Salesforce Commerce Cloud to achieve headless commerce. Whether or not you agree that Headless is the future, catching all the sessions related to this session is an excellent idea to keep yourself up to date on this topic! Headless, API-first, composable, etc., have many approaches. And hearing other people’s visions on these topics is always interesting. ### How to Boost Ecommerce Sales with Commerce for Social ![Community speaker spotlight graphic used for featured sessions.](/20-years-of-dreamforce/community-speaker-9f72758dd2_hu_99e949c772c49eec.webp) A featured session on using social commerce to grow ecommerce performance. - [Francesca Liu](https://www.linkedin.com/in/francesca-liu-b5757797/) - [Bhagath Ganga](https://www.linkedin.com/in/bhagathganga/) - Theatre Session > Shopping at the edge is expected to grow exponentially over the next five years. Learn how to improve product discoverability and boost sales on today’s leading social channels using Commerce Cloud. Next to headless, social commerce has gotten a lot more attention. If you are also active in the SCAPI/SLAS space in the Unofficial Slack community/webinars, you will recognize Bhagath! ### Increase Conversions and Agility with Headless Commerce - [Pei En Thong](https://www.linkedin.com/in/thongpeien/) - Theatre Session > Learn how you can build fast, flexible, digital experiences with headless commerce. Hear how brands can accelerate ROI and unlock organizational agility with a trusted Composable Storefront. Another session on headless. My gut feeling is that this presentation is about rebranding the PWA Kit to “Composable Storefront.” ### Serving Friction-Free Food Shopping Experiences - [Kimberly Barach](https://www.linkedin.com/in/kimberly-barach-28baa12/) - [Bruno Mourão](https://www.linkedin.com/in/bmourao/) - Theatre Session > The shopping paradigm has changed. Learn how food retailers are removing friction from the purchasing process and delivering meaningful connected experiences for shoppers like never before. Learning about the particular use cases, you can run into as a food retailer is an excellent session to attend! ### Winter ‘23 Release Readiness Live: Commerce Cloud - [Akshatha Rao](https://www.linkedin.com/in/akshatharaog/) - [Eric Lerner](https://www.linkedin.com/in/ericdlerner/) - [Sid Gupta](https://www.linkedin.com/in/sid-gupta-a777756/) - [Priyasha Mehta](https://www.linkedin.com/in/priyashamehta/) - Theatre Session > Release Readiness Live is here at Dreamforce! Join our product managers to learn about exciting new developments across B2C Commerce, B2B Commerce, Order Management, and Salesforce Payments. Another session about the roadmap, but always good to have a peek to learn what is coming in the Salesforce Commerce space! ### Commerce Cloud Developer Experience ![Community speaker spotlight graphic used for featured sessions.](/20-years-of-dreamforce/community-speaker-9f72758dd2_hu_99e949c772c49eec.webp) A session worth catching if developer experience and tooling are your focus. - [Andrew Lawrence](https://www.linkedin.com/in/andrew9990/) - Theatre Session > Learn about the latest tools, SDKs, and features for building amazing user experiences powered by Commerce Cloud. A look at developer experience! Probably the only session I have come across dedicated to developers, so a must-attend if you are one! ### And many more And the list goes on. Before this article becomes too large, I will end the list here! Like mentioned before, there are over a 1000 sessions, so choices will have to be made! ## Party Time ![Red Hot Chili Peppers performing on stage at Dreamforce.](/20-years-of-dreamforce/dreamforce-red-hot-chili-peppers-2e81650f2f_hu_d4f667d92ef15026.webp) Dreamfest is part conference, part celebration, and the headline concert is part of the draw. It wouldn’t be a Salesforce event if there weren’t a big party! Dreamforce is no different; a fantastic night of entertainment has been planned. ## Red Hot Chili Peppers ### Red Hot Chili Peppers - Californication \[Official Music Video\] Play video ### Red Hot Chili Peppers - Otherside \[Official Music Video\] Play video ### Red Hot Chili Peppers - Can’t Stop \[Official Music Video\] Play video ### Red Hot Chili Peppers - Under The Bridge \[Official Music Video\] Play video --- ## Let’s GO-LIVE: The Salesforce B2C Commerce Cloud Environment Canonical URL: https://rhino-inquisitor.com/the-salesforce-b2c-commerce-cloud-environment/ Markdown URL: https://rhino-inquisitor.com/the-salesforce-b2c-commerce-cloud-environment/index.md Content type: article Published: 2022-08-22T17:37:46Z Updated: 2022-08-23T07:19:42Z Summary: Do you want to know more about the server architecture of Salesforce B2C Commerce Cloud? You have come to the right place! Categories: Architecture, GO-LIVE, Salesforce Commerce Cloud, Technical Tags: security, sfcc, technical ## Key Takeaways - Explains the major components that make up the Salesforce B2C Commerce environment, from storefront runtime to support tools and APIs - Shows how a shopper request moves through the environment layers, including the eCDN and the application stack - Acts as a practical architecture primer for developers preparing to launch or operate SFCC channels Welcome to the [GO-LIVE series](/category/go-live/), a set of articles about preparing for the launch of one or more channels on Salesforce B2C Commerce Cloud. This is only the second article so far, but after releasing the first one about the [eCDN](/lets-go-live-ecdn/), I felt I might have skipped some vital information. Sure, there was an explanation of the eCDN and its use. But not how it fits in the “bigger picture.” So let us look at the architecture of the different environments in Salesforce B2C Commerce Cloud! ## An overview Before we move into the details where the [Embedded CDN](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/admin/b2c_embedded_cdn.html) (eCDN) is mentioned, let us get an overview of the components that make up “SFCC.” ![System overview diagram of the main Salesforce B2C Commerce environment components](/the-salesforce-b2c-commerce-cloud-environment/system-overview-systems-v2-96d8264c0f_hu_fc241ef37b9abe6c.webp) Figure 1: Salesforce B2C Commerce Cloud environment system overview [View on Lucidchart](https://lucid.app/lucidchart/b0626d57-dcec-4892-a5e9-5931606b6347/edit?viewport_loc=-594%2C632%2C3328%2C1558%2CCbsI46FLCC7p&invitationId=inv_90859153-9efa-47b0-89e1-e099b200ab73#) ### Commerce Cloud Core It all starts with the big chunk of functionality at the center, “Commerce Cloud,” which consists of: - The monolithic storefront using [SFRA or SiteGenesis](/sitegenesis-vs-sfra-vs-pwa/) - The Open Commerce API for Headless applications - The WebDAV filesystem ### Einstein We can’t forget about one of the big selling points of SFCC, the “built-in” AI that will analyze shopper behavior and give recommendations to increase revenue and the average size of the basket. **Note:** I have an article explaining what Einstein is and what it can do in the pipeline! ### SCAPI As you can see in the diagram at the top of the section, the SCAPI is a set of RESTful APIs built in MuleSoft that proxy the OCAPI behind the scenes to allow some extra things on top of the original OCAPI. But besides having some APIs that the OCAPI does not have, there are [some drawbacks (for now)](https://developer.salesforce.com/docs/commerce/commerce-api/guide/get-started.html). MuleSoft Even though this is MuleSoft, you do not get access to it yourself. It is fully managed by Salesforce and has probably been put in place to allow for flexibility in the future. ### Log Center Can’t find your way in the logs on the WebDAV? Have no fear; Log Center is here. In the Log Center, you can easily filter and search for specific log entries and even be notified when particular thresholds are met. ### Reports & Dashboards Need insights on your sales or site performance? In this tool, you can view statistics on: - Sales - Products - Promotions - Search - Traffic - Einstein - Technical data (performance) ### Control Center The place to be if you want to manage all of your environments (Sandboxes, PIG Instances). Using this tool, you can create, start, restart, stop and reset environments linked to your account. ### Composable Storefront The latest addition to the diagram, the answer to all your [Headless Storefront needs](/sitegenesis-vs-sfra-vs-pwa/)! ### Account Manager Since all of the items mentioned above are separate tools/sites you have to visit, it would be a shame if you had to keep track of different credentials (you had to for a long time). Account Manager provides you with “[Unified Authentication](https://help.salesforce.com/s/articleView?id=000358615&language=en_US&type=1)” so that permissions and user credentials can be managed from a central location, rather than having separate ones for each application. ## From the perspective of a request In the diagram below, we look at a potential request to an SFRA or SiteGenesis channel and see what different layers it passes before a visitor gets a page rendered in their browser! In this case, the explanation of each component of the environment is in the diagram itself. Word of warning though, this is a lot more “technical” than the previous section. ![Request flow diagram showing how traffic moves through the Salesforce B2C Commerce environment](/the-salesforce-b2c-commerce-cloud-environment/system-overview-journey-of-a-request-de0673b3bd_hu_790086d326ccf079.webp) Figure 2: End-to-end request flow through the Salesforce B2C Commerce environment [View on Lucidchart](https://lucid.app/lucidchart/b0626d57-dcec-4892-a5e9-5931606b6347/edit?viewport_loc=-658%2C62%2C3328%2C1558%2C0_0&invitationId=inv_90859153-9efa-47b0-89e1-e099b200ab73#) ### Layering the CDN It is possible to introduce your CDN (e.g., Akamai) or your own Cloudflare account next to the eCDN. The critical thing to remember is that the eCDN will **always be part of the chain**! ### Origin Shielding As of August 2022, [Origin Shielding](https://help.salesforce.com/s/articleView?id=000364472&type=1) has become active. All storefront (shopper) traffic must pass through the eCDN (Cloudflare). This change does not affect: - Business Manager - Inventory Service - Analytics Service - Mainstreet Order Management Service - Order Integration Service - Salesforce Commerce API (SCAPI) calls - Shopper Login (SLAS) - Image Downloader Service - WebDAV calls - /dw/monitor calls for health checks - sffc-ci tool (developer instance only) - Data APIs --- ## Salesforce B2C Commerce Cloud 22.9 release Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-22-9-release/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-22-9-release/index.md Content type: article Published: 2022-08-17T18:45:35Z Updated: 2022-08-18T08:09:00Z Summary: Explore the Salesforce B2C Commerce Cloud 22.9 release, from Page Designer copy and paste to Shopper Context updates and Salesforce Payments changes. Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc, technical ## Key Takeaways - Highlights the main 22.9 changes across WebDAV limits, Page Designer usability, and Salesforce Payments - Explains the Shopper Context API enhancements that matter for personalization and hybrid headless deployments - Calls out supporting tool and cartridge updates that affect migration, security, and storefront integration work We have been getting some lovely new goodies in the past few releases, but this trend is not ending! This time we look at the [September 2022 (22.9) release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_22_9_release.htm&type=5)! Are you interested in last month’s release notes? [Read the 22.8 release notes](/salesforce-b2c-commerce-cloud-22-8/)! ## Platform ### WebDAV upload limit relaxed ![Meme-style graphic celebrating the higher WebDAV upload limit.](/salesforce-b2c-commerce-cloud-22-9-release/upload-limit-relaxed-stonks-meme-f8e9bd0b5b_hu_7f98115932e6100e.webp) A big update that will make many happy! The limitation of 100MB has been relaxed to 500MB for uploading to the WebDAV. This change will make it a lot easier to integrate with other systems that have to send over large amounts of data. Until now, you had to split it into multiple “chunks” of 100MB. Some will still wish the limit was higher, but this is still a considerable improvement! ## Business Manager ### Copy & Paste components in Page Designer A big update to Page Designer as it will now be possible to copy and paste components (up to 10). Not only will this be possible in the same page, but to other pages - even across browser tabs! Idea: This [feature](https://ideas.salesforce.com/s/idea/a0B8W00000GdYHjUAN/page-designer-add-ability-to-copypaste-components) was initially submitted by [Ryan Rubis](https://www.linkedin.com/in/ryanrubis/). Play video ### Target components to a specific locale in Page Designer You could only target components to specific customer groups or campaigns until now. Starting from this release, locales have been added to that list! Play video ### Performance increase to Page Designer Pages loaded in Page Designer are responsive before all referenced images, external resources, or client-side scripts have completed loading, cutting down on wait time. I suspect this improvement is only for the performance of the Business Manager as we are (mostly) in control of how the front behaves. But let’s find out after this update hits the first sandboxes! ### AfterPay and Venmo added to Salesforce Payments ![AfterPay and Venmo payment options highlighted for Salesforce Payments.](/salesforce-b2c-commerce-cloud-22-9-release/venmo-d5992ec262_hu_7e3bd370971530eb.webp) Let your shoppers pay in interest-free installments with AfterPay. Salesforce Payments offers AfterPay through your Stripe Merchant account. When AfterPay is active on your storefront, the product details page and checkout cart list it as a payment option (Default SFRA & Payments Cartridge). Venmo has also been added as an express and multi-step payment service for U.S.-based merchants. This integration does require a PayPal integration with Salesforce Payments, and a payment zone configured that conforms with the Venmo criteria. ## OCAPI & SCAPI ### Shopper Context API Enhancements To personalize Headless applications with Salesforce B2C Commerce Cloud, you will need the [Shopper Context API](https://developer.salesforce.com/docs/commerce/commerce-api/guide/shopper-context-api.html). In this release, a few new options have been made available: - Source code support (trigger promotions, payment, and shipping methods) - Support for Hybrid Deployments by adding support to the OCAPI for Shopper Context - Personalize prices and promotions based on store-specific promotion and pricing rules (imported with [assignments.xml](https://developer.salesforce.com/docs/commerce/commerce-api/guide/shopper-context-api-store-specific.html)) ## Development ### Updated Retention Period of Unregistered baskets > Unregistered baskets are now stored a maximum of 7 days, depending upon preference settings, which mitigates the risk of negative performance and error rates. This one was already the case before this update, so not sure what has changed in this release. ## Bugfixes In August, someone at Salesforce has been cleaning house at the “[Known Issues](https://trailblazer.salesforce.com/issues_index?page=3&tag=Commerce+Cloud+Platform).” Many were updated in the past few weeks with a “Fixed” status, but for past releases (22.4, 22.5, 22.7, and 22.8), I will only mention those here that were fixed in at least 22.8. - [AttrubuteValueEditor can shows wrong values for “Enum” types](https://trailblazer.salesforce.com/issues_view?id=a1p4V0000029kX2QAI&title=attrubutevalueeditor-can-shows-wrong-values-for-enum-types) - [Currency symbol of Tanzanian Shilling (TZS) prices is null](https://trailblazer.salesforce.com/issues_view?id=a1p4V0000029kd3QAA&title=currency-symbol-of-tanzanian-shilling-tzs-prices-is-null) ## Updated Cartridges & Tools ### b2c-tools (v0.9.2-v0.10.0) - [https://github.com/SalesforceCommerceCloud/b2c-tools](https://github.com/SalesforceCommerceCloud/b2c-tools) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances. It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. - Fixes an out of order issue with the previous release when bootstrapping new instances - Code coverage for features - change in bootstrapping order to ensure that errors during bootstrapping do not leave an inconsistent state - Fixes the path for private library export. by [@mihaivilcuosf](https://github.com/mihaivilcuosf) in [#77](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/77) - Fixes an out of order issue with features - delete cartridges prior to unzip to replace all files by [@sandragolden](https://github.com/sandragolden) in [#78](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/78) - adds runAsScript method to execution migration scripts directly by [@clavery](https://github.com/clavery) in [#80](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/80) - see `examples/run-current-file.js` ### link\_beecloud\_recaptcha (v2022.1.0) - [https://github.com/SalesforceCommerceCloud/link\_beecloud\_recaptcha](https://github.com/SalesforceCommerceCloud/link_beecloud_recaptcha) > BeeCloud provides a LINK cartridge to integrate with Salesforce Commerce Cloud (SFCC). This cartridge provides integration with Google reCaptcha for checkout process. A new addition to public community repositories, always great to see! This one adds a quickstart to add Google reCaptcha to your order process! --- ## What is the OCAPI session bridge? Canonical URL: https://rhino-inquisitor.com/what-is-the-ocapi-session-bridge/ Markdown URL: https://rhino-inquisitor.com/what-is-the-ocapi-session-bridge/index.md Content type: article Published: 2022-08-15T19:08:02Z Updated: 2023-12-07T10:36:32Z Summary: It is possible to link a SiteGenesis/SFRA session with an OCAPI "session." But how can we do it, and what is it suitable for? Categories: Salesforce Commerce Cloud, Technical Tags: ocapi, sfcc, technical ## Key Takeaways - Explains the OCAPI session bridge as a way to exchange storefront session cookies and JWT tokens between monolithic and headless touchpoints - Walks through the practical request flow for converting a guest OCAPI token into storefront cookies and back again - Highlights the hybrid-deployment and mobile-app scenarios where session bridging is useful, along with the sensitive-data caveats to keep in mind With the added attention to [Headless architecture](/sitegenesis-vs-sfra-vs-pwa/) in Salesforce B2C Commerce Cloud and the option for “[hybrid deployments](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/phased-headless-rollouts.html),” the [Session Bridge](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/SessionBridge.html) has also gotten some more airtime. But what is it? What do I use it for? What do I watch out for? Let us dig deeper into these questions and try to give them a clear answer! ## TLDR; Solution For those who want a quick answer to this, I have created a postman collection with three API calls: - Start an anonymous session in the OCAPI - Exchange JWT for cookies - Exchange cookies for JWT (_Postman automatically stores the cookies to the domain in the second call - that is why you will not see any variable or script in this call_) - [OCAPI- Session Bridge.postman\_collection.json](https://gist.github.com/taurgis/5c31294867fc406669effa6fddc48b8a) ### Looking for the SLAS Session Bridge A new option is available for session bridging linked to SLAS. This alternative is handy if you primarily work with SCAPI endpoints and SLAS. It provides a more efficient and effective way to manage sessions and streamline your transfer workflow. You can find the documentation [in the SLAS Session Bridge guide](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-session-bridge-auth.html?q=session%20bridge)! ## What is it First things first, let us dig into what the Session Bridge is. And luckily for us, it is not rocket science! It is a set of services that allow the exchange of a [session cookie](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DataProtectionAndPrivacy/LocalDataStorage.html) (Site) for a [JWT](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/JWT.html) (OCAPI/SCAPI) and visa-versa. Using this service, you can keep a session alive across different touchpoints. A good example is a mobile application with a button redirecting to the site. In this scenario, it would be a shame if someone logged into the application would have to log in again on the site. Come into play the “Session Bridge!” The mobile application, before being redirected, exchanges its JWT token for a valid cookie and sets it before pushing the customer to the site. Result: Happy customer (hopefully 😊)! ![Mobile app session bridging flow that transfers a shopper into the storefront.](/what-is-the-ocapi-session-bridge/session-bridge-mobile-app-v3-scaled-93e60b2f4b_hu_82174da2635397d4.webp) ## Scenario: OCAPI to Site ### Prerequisite: Configure OCAPI For this scenario, we will be making use of the following API key: ```text aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ``` For those unaware, the above key does not need to be configured in the Account Manager to be used on Sandboxes and test systems. **It is not meant to be used in production!** With this API key, we can configure access to the necessary APIs in the Business Manager at “_Administration_” > “_Site Development_” > “_Open Commerce API Settings_” ```json { "_v": "22.6", "clients": [ { "client_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "allowed_origins": [], "resources": [ { "resource_id": "/customers/auth", "methods": [ "post" ], "read_attributes": "(**)", "write_attributes": "(**)" }, { "resource_id": "/sessions", "methods": [ "post" ], "read_attributes": "(**)", "write_attributes": "(**)" } ] } ] } ``` ### Step 1: Get a OCAPI session JWT > **Site ID** > > In the examples below, you will see the site “RefArch” used. Do not forget to replace this with your own. The first resource we need to call is customer authentication. And with this, we will get a JWT bearer token we can use other OCAPI endpoints linked to that customer “session.” - [/customers/auth](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/Customers.html#id152105914__id-98588883) In this example, to make it a bit easier to test out, we will use a guest session by forming a request like this: ```text REQUEST: POST /s/RefArch/dw/shop/v22_6/customers/auth HTTP/1.1 Host: example.com Content-Type: application/json x-dw-client-id: [your_own_client_id] { "type" : "guest" } ``` The result is a response containing the bearer token we need to continue talking to the OCAPI. ```json { "_v": "22.6", "_type": "customer", "auth_type": "guest", "customer_id": "abEJE0Q5dATRwio9DZjEvBuDUq", "preferred_locale": "en_US", "visit_id": "477caf41e8a3d6a4ede60aa354" } ``` But what you need is not visible in the response… huh? Not to worry, it is in the Authorization header! ![Authorization header containing the OCAPI bearer token in Postman.](/what-is-the-ocapi-session-bridge/bearer-token-authorization-header-e377c64b9c_hu_ec07e5d03bd9d2aa.webp) ### Step 2: Exchange the bearer JWT token for cookies Let us exchange that token for a cookie, shall we? And for that, we need the “sessions” endpoint. - [/sessions](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/Sessions.html#id-2104258718__id-514053870) > **Important:** The link above contains much information on things to keep in mind! Be sure to give it a good read. The request itself is pretty easy! Call the endpoint with the correct authorization header (type bearer), and you are as good as gold! ```text POST /s/RefArch/dw/shop/v22_6/sessions HTTP/1.1 Host: example.com x-dw-client-id: [your_own_client_id] Authorization: Bearer <sample-jwt> ``` If all goes well, you will get a response that will attempt to set cookies on the current host domain. ```text RESPONSE: HTTP/1.1 204 NO CONTENT Set-Cookie : dwsecuretoken_<suffix>=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Set-Cookie : dwsid=<sample-session-cookie>; Set-Cookie : dwanonymous_<suffix>=<sample-anonymous-id>; Max-Age=15552000; ``` For the next step to work, copy the **dwsid** cookie. We need it to convert the cookie back to a JWT bearer token. ### Step 3: Exchange the cookie for a bearer JWT In some scenarios, we need to be able to do it the other way around and convert our cookie to a JWT token. To do this, we use a familiar endpoint (step 1)! - [/customers/auth](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/Customers.html#id152105914__id-98588883) The most significant difference from step 1 is that we send a different body and, of course, our cookie. ```text REQUEST: POST /s/RefArch/dw/shop/v22_6/customers/auth HTTP/1.1 Host: example.com Content-Type: application/json x-dw-client-id: [your_own_client_id] Cookie: dwsid=<sample-session-cookie> { "type" : "session" } ``` Similar to our first request, we get a JSON response with the JWT token in the “Authorization” header. ```json { "_v": "22.6", "_type": "customer", "auth_type": "guest", "customer_id": "abEJE0Q5dATRwio9DZjEvBuDUq", "preferred_locale": "en_US", "visit_id": "51e8f8af5015bd57bfeea12bed" } ``` > **Matching `customer_id`** > > To verify that the flow worked, the `customer_id` from step 1 should match the value you receive in response to this call. ## SCAPI & SLAS Suppose you are making use of SLAS to get a JWT token, no worries. This JWT token is also compatible with the session bridge and is used actively by the PWA Kit (Composable Storefront) and the [SFRA SLAS Plugin](/slas-in-sfra-or-sitegenesis/). ## Guest basket and sensitive data > If the customer is authenticated and has a storefront basket, that basket is transferred into the session and can be retrieved using BasketMgr.getCurrentBasket(), along with sensitive data such as addresses and payment information. Something to keep in mind when using the Session Bridge is how it handles sensitive data; let us look at two scenarios. ![Secure guest-basket handover where sensitive basket data remains protected.](/what-is-the-ocapi-session-bridge/session-bridge-guest-basket-secure-order-df1146c25d_hu_733340d6c527b58b.webp) A secure way of working with sensitive data ![Insecure handover example where SFCC blocks sensitive basket details after transfer.](/what-is-the-ocapi-session-bridge/session-bridge-guest-basket-insecure-order-a252675925_hu_1308d93171a40120.webp) SFCC Makes sure no sensitive data is shared in a possibly insecure scenario _**A basket is created/modified**_ _**after the session handover**_ in the second scenario. As a security precaution, Salesforce ensures that SiteGenesis/SFRA can not access this data. Consider this if you have a scenario where one might modify or set a basket after a session handover. ## Use Case: Hybrid deployment As mentioned in the intro, this API endpoint has gotten much more attention since the release of the PWA Kit. One of the official scenarios supported by this new storefront option is a hybrid deployment, which means keeping some pages running on SFRA/SiteGenesis and others on the PWA Kit. This allows existing clients to slowly migrate from the “monolithic architecture” to a “headless architecture.” Want to know more about how to implement this approach? Head to [the official documentation](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/phased-headless-rollouts.html)! --- ## What is OCI (Omnichannel Inventory) Canonical URL: https://rhino-inquisitor.com/what-is-oci-omnichannel-inventory/ Markdown URL: https://rhino-inquisitor.com/what-is-oci-omnichannel-inventory/index.md Content type: article Published: 2022-08-08T14:35:58Z Updated: 2022-11-19T10:09:21Z Summary: OCI (Omnichannel Inventory) is an offering part of Salesforce Commerce Cloud. But what is it, and why should you use it? Categories: Salesforce Commerce Cloud Tags: oci, sfcc ## Key Takeaways - Explains what Omnichannel Inventory is, what capabilities it brings, and why it matters for near real-time multi-location inventory use cases - Highlights that OCI is included in the B2C Commerce license and natively integrates with SFCC inventory lists - Balances the product's omnichannel benefits against the added architectural complexity, API-first setup effort, and development work it can introduce OCI ([Omnichannel Inventory](https://trailhead.salesforce.com/content/learn/modules/omnichannel-inventory)) has been a part of the Salesforce B2C Commerce Cloud offering for a while. Originally it was part of the OMS ([Order Management](https://www.salesforce.com/products/commerce-cloud/ecommerce/order-management/), but it was decided to split it off as a separate product to provide a flexible offering. But why should you use it? And if you decide to use this product, what are the things to keep in mind? ## Wait?!! It’s included in the B2C license ![Quip note highlighting that OCI is included for B2C Commerce customers.](/what-is-oci-omnichannel-inventory/oci-included-in-license-b4aca05118_hu_7d986bc685a686ce.webp) Let us first get this topic out of the way; I am sure this information will increase the interest in this product! If you are a B2C Commerce Cloud customer, OCI is included! I only learned about this because I took the OMS Administrator and Developer certification exam (and passed 😊). ## What is OCI Omnichannel Inventory is an offering that provides near real-time inventory information at the location level for an [omnichannel](https://en.wikipedia.org/wiki/Omnichannel) experience. But what does that mean? The OCI exists out of multiple components: - **Omnichannel Inventory service:** An API-first approach service that allows you to get and manage inventory information across all of your fulfillment channels. - **Omnichannel Inventory App:** A Salesforce console app to manage your locations and inventory availability in the [visual interface you know and love](https://www.salesforce.com/campaign/lightning/). ![Omnichannel Inventory app interface for managing locations and availability.](/what-is-oci-omnichannel-inventory/omnichannel-inventory-0b29da8f29_hu_eb0831acb59634ca.webp) The Omnichannel Inventory provides a set of Headless APIs so any system can communicate with it to get the latest inventory information, be it your website, app, or any other system connected to the web (which can include your physical stores). Using OCI brings the following benefits: - **Granular location visibility:** Manage location-level inventory availability. - **Powerful grouping:** Segment inventory by combining multiple locations. For example, merge your EU-located warehouses to one location group for a Salesforce B2C Commerce Cloud channel. - **Flexibility:** Easily add or remove a location. - **Centralized visibility:** View availability information across all of your channels. - **Accuracy at scale:** Gain near real-time insights into availability to prevent costly underselling and overselling during flash sales or holidays! And this is important as many systems struggle to get a near real-time view, causing mispicks in the warehouse. - **Omnichannel:** Easily support omnichannel experiences, such as ship from store and buy online, pick up in-store (BOPIS) ![An overview of grouping inventory locations together into delivery groups. It shows for example a Physical store and warehouse being merged to an inventory group to use for online delivery as a single 'list'.](/what-is-oci-omnichannel-inventory/inventory-grouping-6f9edbe7b9_hu_a8fdba264d3a230f.webp) Example of location grouping ## Natively integrated This might be a sentence you have heard before and are skeptical about. But in this case, you can lower your guard a little bit. The Omnichannel Inventory comes natively integrated with Salesforce B2C Commerce Cloud! Once activated, a few things change how things work in the Business Manager and how developers access APIs. In a few sentences: “Once this has been enabled by support/CSM (Customer Success Manager), your Inventory Lists are fed with data from the OCI, rather than having to manage or import them via a different channel into SFCC.” You still have to upload that data to the OCI! It is just a different system that you integrate with to update inventory information. But you do not have to think about getting that data to Salesforce B2C Commerce Cloud; these updates are also near real-time! ### Documentation - [Data Synchronisation (B2C <> OCI)](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/inventory/b2c_inventory_management_omnichannel_inventory.html) - [API Documentation (Salesforce Help)](https://help.salesforce.com/articleView?id=inv_omnichannel_inventory_service.htm) - [Trailhead: Omnichannel Inventory](https://trailhead.salesforce.com/content/learn/modules/omnichannel-inventory?trailmix_creator_id=rr820768&trailmix_slug=tcs-omnichannel-inventory) - [Training: Omnichannel Inventory](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=fvb19UvtLP1ohuV8EthlGEFZQ0vGXPFygtDSet8YjuK0Vmu6uWVIqSToV0n%2Bdisz) ## Should I use OCI This depends on your situation and if you need this amount of flexibility. Have a good look at your current needs and the roadmap before making this decision. If you only have one location from which you ship, have no plans for features such as BOPIS, and do not plan to add more warehouses, you might not need OCI just yet. ### API First Since OCI is an API First approach service, some features are only available through REST services. Keep this in mind when planning, as getting to know the ins and outs of OCI will take longer than how inventory lists work. These features are available in the OCI Application on force.com: - Look up available inventory for an SKU. - View, add, edit, and delete locations. - View, add, edit, and delete location groups. - Assign locations to location groups. - Remove locations from location groups. - Commit location and location group updates. As you can see, there is only an interface to look up inventory. But not to update or delete it! ### Not as “easy” to set-up as Inventory Lists Since we are working with REST JSON APIs rather than XML files that can be put on an SFTP or WebDAV, expect to be spending more time to set this up in both Salesforce B2C Commerce Cloud and in the OCI itself. As with many things, with more flexibility comes more **complexity**. An excellent example is how to import inventory, [have a look](https://developer.salesforce.com/docs/commerce/commerce-api/references/impex?meta=submitInventoryImport)! Felt like something was missing in the documentation there? Not to worry, it was on the [Summary page](https://developer.salesforce.com/docs/commerce/commerce-api/references/impex?meta=Summary). Have a good read on that summary page, it should give you a clear understanding of the complexity you need to take into account. ### It adds other complexities We are heading into “composable” territory here, which adds complexity to your architecture. And what do I mean by that: - There is no management interface available, as mentioned in one of the previous items. - Since it is a separate system, you need to keep track of that in your architecture (e.g., consider possible data or performance issues). - It is a separate system for merchandizers to view and manage the inventory (to the extent possible) besides the regular Business Manager. ### Development needed You can ignore this topic if you just want the standard Inventory List functionality. But development in Salesforce B2C Commerce Cloud is still required when: - You want to do real-time inventory checks on the PDP/Checkout - Implement BOPIS - Want a management interface for the inventory Integration You also need to do the integration with OCI through the REST APIs that are available. ### It can’t do everything While Omnichannel Inventory offers many vital benefits, keep in mind that it does not replace the inventory system of record, supply chain management, warehouse management, and other systems you depend on to run your retail operations. --- ## Let’s GO-LIVE: eCDN Canonical URL: https://rhino-inquisitor.com/lets-go-live-ecdn/ Markdown URL: https://rhino-inquisitor.com/lets-go-live-ecdn/index.md Content type: article Published: 2022-08-04T06:53:47Z Updated: 2022-08-05T07:52:02Z Summary: Bringing your first site live on SFCC can be challenging. In this series, we will be looking at different parts. Part I: eCDN Categories: GO-LIVE, Salesforce Commerce Cloud, Technical Tags: cloudflare, sfcc, technical ## Key Takeaways - Explains what the SFCC embedded CDN is and which storefront controls it exposes in Business Manager - Walks through the production vanity-domain flow from alias setup to DNS verification and certificate upload - Highlights go-live risks like apex-domain handling, production-only setup, and timing DNS changes before launch day So, you want to set a website live on Salesforce B2C Commerce Cloud. It is all relatively new to you, but your task is to set up the Staging and Production instance to prepare your “GO-LIVE.” Not to worry! The ECDN is not rocket science, far from it. Once you have set up your first vanity domain, the second one will be peanuts. **Update August 5, 2022:** Added some warnings to this post with things to keep in mind. Thank you, [Sachin Upmany,](https://www.linkedin.com/in/sachin-upmanyu-82428828/) for the reminder that this information is also essential in these guides! ## What is the eCDN But first things first. It is as essential to know what the eCDN is to configure it! What does [Salesforce have to say](https://www.salesforce.com/products/commerce-cloud/resources/ecdn-for-commerce-cloud-digital-datasheet/) about this feature: > Salesforce Commerce Cloud provides digital customers an embedded content delivery network (eCDN) designed to accelerate site speed access and content delivery. The end result is a more secure, reliable online shopping experience for the consumer. Ok, ok. The sentence above might not explain what the eCDN is and does. To put it in simple terms: it’s [Cloudflare](https://www.cloudflare.com/)! If you have been active in web development for a while, you probably are already familiar with the service. For the most part, Salesforce has put itself in between and taken complete control of the Cloudflare configuration. But luckily, they have left us with a few buttons and switches to fiddle with in the Business Manager. ![Embedded CDN settings for the my-domain.com storefront.](/lets-go-live-ecdn/ecdn-overview-fea46a41af_hu_33d3cb4a80d168ec.webp) Business Manager's eCDN workspace is where the storefront domain, certificates, and traffic rules come together. Within this interface, you can configure: - Your supported [vanity domains](https://en.wikipedia.org/wiki/Vanity_domain) - Managing SSL certificates - Firewall & [WAF](https://www.cloudflare.com/waf/) (Web Application Firewall) - Performance Optimization - Custom Error/Under Attack Pages ## Getting Prepared Before configuring the **Production** Business Manager, a few things need to be in order and prepared. ### Domain This one should be pretty obvious, but I’ll mention it anyway. Make sure the domains you will be using have been purchased. If you don’t own the domains, you won’t be able to point them to Salesforce B2C Commerce Cloud. ### DNS Configuration Access To point the domain to Salesforce B2C Commerce Cloud, you need access to the domain DNS configuration. In later steps, you (or someone else you are in contact with) must add [TXT](https://en.wikipedia.org/wiki/TXT_record) and [CNAME](https://en.wikipedia.org/wiki/CNAME_record) records to the DNS configuration. ![DNS record editor for the vanity domain.](/lets-go-live-ecdn/add-dns-record-domain-com-245d883c43_hu_7e8833dafa13768e.webp) This DNS panel is where the TXT and CNAME records for the new storefront domain are added. APEX Domain Pointing / Naked Domain It is essential to know that the APEX Domain or Naked Domain does not support CNAME records. Usually, a DNS provider has solutions for this, but this needs to be considered. In a worst-case scenario, you need to set up a “mini-server” to do the redirection of the naked domain to the www subdomain. You can find some [information on Salesforce Help](https://help.salesforce.com/s/articleView?id=000361629&type=1) on this topic. With a naked domain we mean [https://mybrand.com](https://mybrand.com) (without the www). ### Get your SSL certificates We have come to a time where no website should operate without a secure connection. To achieve that, an [SSL certificate](https://en.wikipedia.org/wiki/Certificate_authority) is required. To do the configuration later, you need the following: - The certificate - The private key Note: If you are unfamiliar with how certificates can be obtained, [a lot of helpful information](https://letmegooglethat.com/?q=how+to+get+a+ssl+certificate) is floating around on the net. ## Alias Configuration A prerequisite for a domain to be available in the eCDN is that it is configured in one of the sites in the [alias](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/search_engine_optimization/b2c_hostname_aliases.html) configuration. An example config you can use to get you up and running quickly: ```json { "__version": "1", "settings": { "http-host": "www.my-domain.com", "https-host": "www.my-domain.com" } } ``` Once an Alias is configured on at least one site in your production environment, we can continue to the next step! Alias Configuration Setting up this configuration can be a pain in the \*\*\*, so be prepared to fiddle around with it for a few hours if you are unfamiliar with it, especially if you are handling multiple sites with multiple domains. ## Add the domain to the eCDN Use the correct environment Setting up the eCDN is done on the production instance! Zone Creation with care Once a zone is created, this can not be undone, and you will have to go through support to be able to undo this. To get to the eCDN configuration, go to “**Administration**” > “**Sites**” >"**Embedded CDN Settings**" Once the page has loaded (be patient), you will see the following at the top right of the page. ![Add Hostname action in Embedded CDN Settings.](/lets-go-live-ecdn/ecdn-add-hostname-719cd44c57_hu_6044b5b77b69d1ec.webp) Start the eCDN setup by adding the storefront hostname from the Embedded CDN Settings screen. You should see the message “x hostname(s) available” if everything goes well. If not, go back to the Alias configuration to verify everything was saved correctly. Click “Add Hostname.” A screen should show your configured Alias domain and to which site it is assigned. ![Create Zone dialog for the selected hostname.](/lets-go-live-ecdn/ecdn-add-hostname-second-step-1cfd425363_hu_56ae583e55d877d9.webp) The zone-creation dialog links the selected alias domain to the correct storefront. Click “Create Zone.” Be patient; it can take a while before something happens. ### Verify ownership of the domain Once the page responds in the previous step, you should see something like this. ![Hostname row marked as verification needed.](/lets-go-live-ecdn/ecdn-verification-needed-4d10fff1bf_hu_1e9151522b84b535.webp) A new hostname stays blocked here until Salesforce can verify that you own the domain. If you see the above, you are well on your way! But there is a clear message: “Verification needed.” Before continuing, we need to verify that we own the domain. Click the text “Verification needed,” and you will see more information on the next steps. ![Verification details with the required TXT record value.](/lets-go-live-ecdn/ecdn-verification-needed-step2-7bd0bfea95_hu_327d26af458c956e.webp) This panel gives the exact TXT record your DNS team must publish before setup can continue. This builds on the pre-work steps where you need access to the domain’s DNS. Before we can continue with the following steps, a TXT record with the provided value needs to be added to the DNS settings of your domain. DO NOT DO THIS ON THE DAY OF THE GO-LIVE. As the warning says, it can take up to 6 hours for these changes to take effect. And on the go-live day, you don’t want to spend your time “stressing out” on something you have no control over. From personal experience, this usually takes a couple of minutes rather than hours. But the warning is there for a reason! ## Domain Configuration Now that we are a “verified owner” of the domain within the eCDN, we can start configuring that domain. ![eCDN overview screen for a configured storefront domain.](/lets-go-live-ecdn/ecdn-overview-fea46a41af_hu_33d3cb4a80d168ec.webp) Once the domain is verified, this becomes the main screen for certificate and traffic settings. To start, click the “settings” to the right of the top-level domain. ### Set up an SSL Certificate ![TLS and certificate controls for the embedded CDN.](/lets-go-live-ecdn/ecdn-crypto-settings-b5ebdefdd6_hu_4db94d399cc58bc0.webp) TLS settings are where the storefront certificate is added and managed. The first screen you will land on is the “crypto” settings. This is where you manage everything about SSL and TLS settings. To add a certificate, click the “Add Certificate” button! ![Certificate upload form for the embedded CDN.](/lets-go-live-ecdn/ecdn-upload-certificate-2447fc3d76_hu_e72108c38e6f80b.webp) Use this form to upload the certificate and private key for the storefront domain. The screen itself is pretty self-explanatory. If you followed the “get prepared” section at the beginning of this article, these should already be in your possession. Once entered, the system will validate if it is correct. If it passes the validation, click “Upload Certificate,” and bam… you are done! #### TLS 1.3 You might have noticed that a BETA feature was marked in the screenshots above. Do you want to know more about this feature? Then visit [Cloudflare Docs](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/tls-13/). Even though the notification popup warns you that this is a BETA feature, it has already gotten that mark for two years. I have enabled this feature on most projects with no adverse effects. #### HSTS Once a certificate has been uploaded, a new setting should appear called [HSTS](https://hstspreload.org/). Enabling this option will tell browsers that your domain only operates over HTTPS and that all HTTP connections should be blocked. Since this includes all subdomains, ensure that no system besides Commerce Cloud operates on HTTP. Otherwise, people will be “barred” from using that site for the remainder of the TTL. ### Firewall Settings ![Firewall settings for security level and trusted IPs.](/lets-go-live-ecdn/ecdn-firewall-settings-ee94d7af54_hu_e6ea8459a947b459.webp) These firewall controls are where the baseline launch protection is tightened before traffic arrives. You can manage the Security Level and Trusted IP Addresses in the firewall settings. As the help popup informs, this part of the firewall looks at IP Address reputation to act appropriately. Using the IP Allowlisting feature, you can inform the firewall to ignore specific IPs. ### WAF Settings ![Cloudflare Speed tab with Auto Minify for HTML, CSS, and JavaScript plus Polish enabled.](/lets-go-live-ecdn/ecdn-waf-settings-3ec4c7f73e_hu_35897b2ab2a60126.webp) Some of the Cloudflare-backed security and optimization options surface through these eCDN settings tabs. The WAF ([Web Application Firewall](https://www.cloudflare.com/learning/ddos/glossary/web-application-firewall-waf/)) is a Cloudflare feature that is well documented. This will look at more areas to detect malicious traffic using the OWASP rules. There is a lot to say about this feature, but lucky for me Salesforce [has written extensive documentation](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/admin/b2c_waf_application.html) on this topic! #### Download Log Files In this section, you can also download log files per hour. It is essential to keep in mind that this is an asynchronous operation, and after clicking “Request Log,” you will receive an email containing a download link at a later time (usually not so long) These files contain a log of all network traffic, how the WAF analyzed it, and how it responded. ### Speed Settings HTML Minification Those who have enabled this in the past might have wondered if this “did anything.” Well, it deletes all of the comments from the HTML. If you have comments on an environment that have value for an external system, be sure not to activate this type of minification. **Note:** This also breaks the deprecated toolkit on Development as it relies on comments. ![eCDN Speed panel showing Auto Minify and Polish options for the storefront.](/lets-go-live-ecdn/ecdn-speed-settings-cccba25f5e_hu_66dfb62d6a5dac5.webp) Performance tuning starts here, with minification and image optimization for the storefront. Not much to say about this section; here, you can control a few settings that improve speed, such as minification of Javascript, CSS, and HTML. The Polish Level settings are something to look into, though, as these can improve the performance of your images. One thing to watch out for is if you choose to enable “Polish Level Basic+JPEG,” your images might lose quality as this will use lossy compression. If you work for a brand that wants crisp and clear photos, you may want to do extensive testing before permanently enabling this. Enabling [WebP](https://en.wikipedia.org/wiki/WebP) is a no-brainer, allowing a lossless compression that performs better on the web. It is also [supported](https://caniuse.com/webp) by all major browsers now (except Safari…). Since these features are Cloudflare behind the scenes, you can also look at [their documentation](https://developers.cloudflare.com/images/polish/). ### Customize Settings ![Custom error page settings for the embedded CDN.](/lets-go-live-ecdn/ecdn-customize-settings-87c4ccf54c_hu_52e2d220d01a0dda.webp) Custom error pages let the CDN fail more gracefully when traffic spikes or attacks hit. A section you hope you will never need. When “\*\*\*\* hits the fan,” Cloudflare provides standard error pages. In this section, you can choose to load your own rather than the default. ## Commerce API Configuration The not-so-well-known thing is that some Cloudflare features you can enable are missing in the Business Manager. There is a REST service available however: [https://developer.salesforce.com/docs/commerce/commerce-api/references?meta=cdn-api-process-apis:updateSpeedSettings](https://developer.salesforce.com/docs/commerce/commerce-api/references?meta=cdn-api-process-apis:updateSpeedSettings) Using these APIs, you can enable: - [Brotli Compression](https://blog.cloudflare.com/brotli-compression-using-a-reduced-dictionary/) - [HTTP2 Prioritization](https://blog.cloudflare.com/better-http-2-prioritization-for-a-faster-web/) Make sure you do not forget about these! As they can also increase performance on certain pages. HTTP2 Prioritization will help a lot on lister pages with many images processed by the [DIS](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/image_management/b2c_image_transformation_service.html) (Dynamic Image Service). --- ## Delta exports in Salesforce B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/delta-exports-in-salesforce-b2c-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/delta-exports-in-salesforce-b2c-commerce-cloud/index.md Content type: article Published: 2022-08-01T14:18:24Z Updated: 2022-09-10T04:43:39Z Summary: Salesforce B2C Commerce Cloud supports delta export jobs. But how do I enable this feature and what do I need to watch out for? Categories: Salesforce Commerce Cloud, Technical Tags: file, jobs, sfcc, sftp, technical ## Key Takeaways - Explains how delta exports work in SFCC and which data types they can cover - Highlights enablement constraints like support activation, change-log retention, and PIG-only support - Warns about runtime, performance, and synchronization trade-offs before relying on the feature You probably already knew that it is possible to do full exports of your customer lists and catalogs from Salesforce B2C Commerce Cloud. This can be done through the [business manager](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/import_export/b2c_catalog_object_import_export.html) or a [job](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/jobstepapi/html/api/jobstep.ExportCatalog.html). But did you also know that delta job steps are available for the following items? - [Catalog](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/jobstepapi/html/api/jobstep.CatalogDeltaExport.html) - [Content Library](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/jobstepapi/html/api/jobstep.LibraryDeltaExport.html) - [Customer Lists](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/jobstepapi/html/api/jobstep.CustomerListsDeltaExport.html) - Maybe even more? Stick around to find out! But as with many things, a few things should be kept in mind before using this functionality. Let us take a look! A big thanks to [Tim Loibl](https://www.linkedin.com/in/tloibl/) for experimenting with this feature and sharing some intel! ## Support needs to enable these If you already opened the links in the introduction you probably noticed a warning. > Support must be contacted to enable delta exports. This is because it is a hidden [feature switch](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/admin/b2c_feature_switches.html) and is only available for Salesforce support. So keep in mind you might have to wait a few hours to a few days, depending on how quickly support can activate this switch. **Important:** This switch has to be turned on separately in each environment (DEV, STG & PRD). So be sure to mention in the ticket which ones you want this switch turned over. ## Business Manager Module Once this feature has been enabled, you get a new toy to play with in the Business Manager at “_Administration _” > “_ Site Development _” > “_ Delta Exports._” You can consider this to work the same as configuring the Sitemap or replications. It is not under the regular list of jobs, but behind the scenes, they are one. ![Business Manager screenshot showing Delta Exports module under Administration > Site Development](/delta-exports-in-salesforce-b2c-commerce-cloud/delta-jobs-overview-dccafc63a7_hu_e65443e1ac2908f7.webp) Delta Exports module overview Let us open that “Test” configuration! ### General ![Delta export job configuration form showing Name field, Consumers field, and Data Type dropdown](/delta-exports-in-salesforce-b2c-commerce-cloud/delta-job-selection-718f8a1686_hu_8061bd557edce228.webp) Delta export general settings When we create a new job or open an existing one, we configure multiple items: - **Name:** The name of the job - **Consumers:** The comma-separated list of external systems you are generating this for (consumers of the feed) - **Data:** The data to export But? Huh? I see more types listed here than there are Job Steps available! And you are correct; you get more options here. A list of supported types can be found [in the Delta Exports documentation](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/import_export/b2c_delta_exports.html). ### Schedule ![Delta job Schedule tab showing fixed interval configuration options](/delta-exports-in-salesforce-b2c-commerce-cloud/delta-job-schedule-1c300976ae_hu_8077fdecea9cccca.webp) Delta export schedule tab Just like regular jobs, you can schedule this to be executed at your chosen interval. ### History ![Delta export history table showing previously generated export files](/delta-exports-in-salesforce-b2c-commerce-cloud/history-70bccb6f6f_hu_8c6808ce25b67fa0.webp) Delta export file history This historical overview is unlike your usual “job” history, even though the description might seem similar. This overview will show a history of all exported files rather than the job executions. Only if a job execution produces a file will it appear in this overview. ### Consumer ![Consumer tab showing WebDAV export folder path for each configured consumer](/delta-exports-in-salesforce-b2c-commerce-cloud/delta-job-consumer-867e8bc380_hu_ee425e1a47961d1d.webp) Delta export consumer folder mapping For each “consumer” you have configured in the general tab, a new tab appears in which you get the path where the files are exported. This gives each external system (consumer) its dedicated folder on the WebDAV to monitor. **Note:** Remember that you can limit access to a third-party system to this specific folder with [WebDAV Client Permissions](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/permissions/b2c_web_dav_client_permissions.html)! ### Status ![Status tab displaying the scheduled delta export job execution log](/delta-exports-in-salesforce-b2c-commerce-cloud/delta-job-status-9552cad99f_hu_65e1a8957be5732f.webp) Delta export status log You can view the log of the scheduled job on this page. ## Only available on PIG instances If you were hoping to test out this functionality on your sandbox, you are out of luck. This feature only works in these environments because it depends on the Change Log to operate. You can make use of delta exports on: - Staging - Development - Production ## Impact on performance > The Delta Exports feature requires the Change Log feature to be active, which can cause a slight (<5%) database performance penalty. This affects update and delete transactions on any entity types that can be selected for delta exports (not only the types that actually are selected). Since an extra step is being added when making modifications to these objects, a minor performance penalty takes place (less than 5 %). But if you have a lot of jobs that modify objects (imports), you need to take this information into account and recalculate the time you expect these processes to run. ## Initial enablement If you expect the first export to contain all objects, this will not be the case. The initial export will only include the objects that have been modified since the enablement of the feature. A solution for this is easy; use the existing options to do the full export if necessary. ## Seven days The retention time of the Change Logs is seven days, so make sure to do your exports once every seven days to ensure your delta exports towards external systems are correct! A good habit is to provide a full export to external systems every once in a while (maybe every month?) to ensure all systems are in sync! ## Large amount of modifications to data in SFCC The delta will become bloated when multiple processes (API Calls, Jobs, and manual) modify data within Salesforce B2C Commerce Cloud. This will cause the job runtime to be long, causing this feature to lose its value. ## Other Considerations In the [Info Center](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/import_export/b2c_delta_exports.html), there are more items to consider. --- ## Salesforce B2C Commerce Cloud 22.8 Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-22-8/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-22-8/index.md Content type: article Published: 2022-07-25T07:19:45Z Updated: 2022-07-25T14:32:45Z Summary: Review the Salesforce B2C Commerce Cloud 22.8 release, including quota changes, SCAPI hook updates, eCDN verification, and holiday readiness work. Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc, technical ## Key Takeaways - Highlights the notable 22.8 changes across sandbox operations, eCDN ownership verification, quotas, and hooks - Explains why the doubled HTTPClient quota and new SCAPI detection helper matter for implementation choices - Calls out related PWA Kit, SDK, and cartridge updates that affect headless and hybrid storefront teams A new month means new candy for us in Salesforce B2C Commerce Cloud. But what will we find in that jar this month? Let us find out! Are you interested in last month’s release notes? [Read the 22.7 release notes](/salesforce-b2c-commerce-cloud-the-22-7-release/)! Or are you looking for the [official release notes](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_22_8_release.htm&type=5)? ## Language A few changes are happening in “terms” used in Salesforce B2C Commerce Cloud: - **master product/variation master:** base product - **master catalog/master product catalog:** product catalog - **master and child items:** main items and secondary items - **master document:** main document This update is in line with the [inclusive language within the Salesforce ecosystem](https://www.salesforce.com/news/stories/how-were-bringing-inclusive-language-to-our-products/). Expect these changes to take effect in all communication slowly and inside the documentation! ## Platform ### Holiday Readiness Preparations Summer has just begun, but Salesforce is already underway to ensure all merchant instances can handle the holiday period! But nothing major in this release, just some database optimizations. [Sign up for this Salesforce webinar series](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000IRu3J) to prepare for the holidays! ### New Sandbox clusters With the steady growth of on-demand sandbox usage, Salesforce will add new clusters to ensure enough resources are available to support it. This change will affect partner sandboxes as they will be moved to US03. Currently, this is US01. > The usage of the on-demand sandbox has been steadily growing. To meet the demand and while maintaining the availability and performance of the on-demand sandbox, new ODS clusters have been added to provide more resources overall to all ODS. A change coming to this community is that the ODS you currently use will be moved to a new and dedicated cluster: US03. Salesforce engineers will make the move itself in batches. No actions are required from you, and your sandboxes should still work as they are after the move. The expected move is in batches and will be done in August on Friday evenings and Saturdays. More details will be posted here in the following days. All new realms provisioned after this announcement (including realm zyfo and zyft that are being provisioned) will be on the new cluster US03. If your realms fall into this category, please note the following: > > - The documentation and instructions you have received may still have the URLs that contain “us01” (e.g., [https://admin.us01.dx.commercecloud.salesforce.com/](https://admin.us01.dx.commercecloud.salesforce.com)). If that is the case, replace “us01” with “us03” in those URLs > - Please use the API, not the Control Center, to manage your sandbox for the time being as the integration of cluster US03 with Control Center is still in its final test stage > - If any issues create or access your sandbox, [please post in this forum and tag John Zhao directly.](https://partners.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F93A000000DQ6f&fId=0D54V00006G4PZ2&s1oid=00D300000000iTz&OpenCommentForEdit=1&s1nid=0DB3000000007Uh&emkind=chatterPostNotification&s1uid=0053A00000EITbU&emtm=1658419675624&fromEmail=1&s1ext=0) John Zhao (21/07/2022) ### New Sandbox maintenance times Everyone using the On-demand Sandboxes has known that maintenance always happens on a weekday (Thursday mornings for me). This has [annoyed many developers](https://ideas.salesforce.com/s/idea/a0B8W00000GdYE0UAN/b2c-commerce-od-sandboxes-maintenance-window), depending on the time zone. And for a good reason, it is in the middle of the week and during working hours for many. When you are ready to start your day and work on a ticket or a deadline is breathing in your neck, the last thing you need is your sandbox being unavailable! Good news: The weekly maintenance is moved to Saturday between 02:00 and 08:00 UTC! ### HTTPClient.send quota limit doubled ![Superhero-style illustration warning that higher HTTPClient limits still require restraint.](/salesforce-b2c-commerce-cloud-22-8/great-power-responsibility-844bd031ba_hu_690f179406545822.webp) Doubling the HTTPClient quota adds headroom, but it is still a budget to manage carefully. Good news, but with a warning, for many developers who have done real-time integrations! The quote limit of external API calls you can do in a single request has doubled, going from 8 to 16. But with great power comes great responsibility. Even though you can do more API calls now, it is not a good idea to take it to the limit. As always, when implementing third-party integrations, keep in mind performance. Ask the question: “Does this really have to happen in real-time? Or can I do this async in a job?” Any delay the third-party introduces will impact the storefront performance and user experience! ### Salesforce Payment Information in Customer Import The customer import ([customer.xsd](https://documentation.b2c.commercecloud.salesforce.com/DOC3/topic/com.demandware.dochelp/DWAPI/xsd/customer.xsd)) has added additional site-specific data about payments. **Note:** This information points to where the data is, not the actual data. ```xml <xsd:element name="customer-payment-profiles" type="complexType.CustomerPaymentProfiles" minOccurs="0" maxOccurs="1"> <xsd:annotation> <xsd:documentation>This element is for use with Salesforce Payments to track references of customer profiles between systems.</xsd:documentation> </xsd:annotation> </xsd:element> ``` ```xml <xsd:complexType name="complexType.CustomerPaymentProfiles" mixed="false"> <xsd:sequence> <xsd:element name="customer-payment-profile" type="complexType.CustomerPaymentProfile" minOccurs="0" maxOccurs="unbounded" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="complexType.CustomerPaymentProfile" mixed="false"> <xsd:sequence> <xsd:element name="creation-date" type="xsd:dateTime" minOccurs="0" maxOccurs="1" /> </xsd:sequence> <xsd:attribute name="account-id" type="simpleType.Generic.NonEmptyString.256" use="required"> <xsd:annotation> <xsd:documentation> The ID of the payment account used to create the customer payment profile. </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="account-type" type="simpleType.PaymentAccountType" use="required"> <xsd:annotation> <xsd:documentation> The type of the payment account used to create the customer payment profile. </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="account-customer-id" type="simpleType.Generic.String.256" use="required"> <xsd:annotation> <xsd:documentation> The ID of the customer payment profile in the payment account. </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> ``` ### Verify Hostname Ownership When uploading a custom hostname certificate, you are now required to [verify ownership by adding a TXT record](https://documentation.b2c.commercecloud.salesforce.com/DOC3/topic/com.demandware.dochelp/content/b2c_commerce/topics/admin/b2c_add_a_certificate_to_a_zone.html) in the DNS configuration of that domain. The value is shown in the Business Manager after uploading the certificate. ## Business Manager ### eCDN Interface Update [![Updated eCDN interface workflow for creating storefront zones.](/salesforce-b2c-commerce-cloud-22-8/ecdn-interface-update-8e83d9ac74_hu_d444024d5eae095e.webp)](ecdn-interface-update-8e83d9ac74.png) The revamped zone creation workflow uses SSL for SaaS V2 and CDN-API without requiring a full-page refresh, making bulk eCDN zone configuration noticeably faster. The workflow for creating zones gets an update: - Updated storefront zone creation UX workflow in Business Manager. - Zone is created using [SSL for SaaS](https://www.cloudflare.com/ssl-for-saas-providers/) V2 (No [USSL](https://developers.cloudflare.com/ssl/edge-certificates/universal-ssl/)\*) and configured and activated using CDN-API. - No need to refresh the entire page after zone creation. - Users can use the “Refresh” and “Verify Configuration” buttons to confirm that the zone has been verified/configured. This is nothing “too exciting,” except if you have to configure about 50 zones. This minor update will speed up the process a lot! ### Quotas: Site Specific [![Quota settings showing site-specific limit handling.](/salesforce-b2c-commerce-cloud-22-8/site-specific-quota-limit-information-c67623c0c3_hu_cd03fd36578f77c.webp)](site-specific-quota-limit-information-c67623c0c3.png) Site-level quota management lets Salesforce tune performance per site instead of per realm. This improvement is more for the engineering and performance team at Salesforce to make sure POD performance can be ensured. Rather than having to manage/relax a quota at a “realm” level, quotas can now be addressed at the Site level (when applicable). ### Change History for campaigns & promotions [![Change History interface for campaigns, promotions, and coupons.](/salesforce-b2c-commerce-cloud-22-8/1da84b9d-7a51-4f6f-bcb0-b0217c4e5cb7-bf0735587c_hu_2a36da05da099e99.webp)](1da84b9d-7a51-4f6f-bcb0-b0217c4e5cb7-bf0735587c.jpeg) Change History now tracks every modification to campaigns, promotions, and coupons, giving merchandisers a complete audit trail for every incentive change. The [Change History](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/change_history/b2c_change_history.html) feature is getting some more options! With this release, you can keep track (if you want to) of all modifications of: - Campaigns - Promotions - Coupons ## OCAPI & SCAPI ### Identify SCAPI requests in hooks Until now, you had to do a custom header check to differentiate between OCAPI and SCAPI requests. In this release, you get a new function/attribute on the [Request](https://documentation.b2c.commercecloud.salesforce.com/DOC3/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_system_Request.html) global object that makes life a little bit easier: [request.isSCAPI()](https://documentation.b2c.commercecloud.salesforce.com/DOC3/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_system_Request.html?resultof=%22%53%63%61%70%69%22%20%22%73%63%61%70%69%22%20%22%72%65%71%75%65%73%74%22%20#dw_system_Request_isSCAPI_DetailAnchor) > When writing your hook logic, it’s important to keep in mind the context of the API that is calling the hook. Both OCAPI and SCAPI share the same hooks, so it’s possible to write a hook that is used for both. Use request.isSCAPI() to determine SCAPI or OCAPI usage, especially if you’re already using the calculate hook in the context of controllers and use transactions in that hook, as that breaks SCAPI. Direct access to the \_sfdc\_ mercury HTTP header is deprecated. ### New SLAS Identity Providers supported SLAS does not allow you to hook in any external IDP at the moment. You need to ask the SLAS team to add support for these through [a message on the community groups](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-identity-providers.html). Newly supported IDPs are: - [SAP Gigya](https://www.sap.com/acquired-brands/what-is-gigya.html) - [AWS Cognito](https://aws.amazon.com/cognito/) - [Apple](https://developer.apple.com/sign-in-with-apple/) - [Azure Active Directory](https://azure.microsoft.com/en-us/services/active-directory/) ## PWA Kit v2.1.0 The PWA Kit is under continuous development as some features are still missing and new use-cases are presented to the team every week that might require some changes. This release can be found [in the PWA Kit v2.1.0 release notes](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v2.1.0). ### What’s New - 🔥 Client side hot module replacement. ### Changes #### pwa-kit-dev - Replace `Mobify` references/links with proper PWA Kit values. [#619](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/619) - Add support for a custom build directory to `pwa-kit-dev build`. [#628](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/628) - Introduce client-side hot module replacement. [#630](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/630) ## pwa-kit-react-sdk - Remove console logs from route component. [#651](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/651) ## Bugfixes For the 22.8 release, I have not found any newly accepted bug fixes, but that might change a few weeks after this article is released. I found that an issue was fixed in 22.7, which I didn’t mention in last month’s release note article. - [Navigation failing when orders are more than 1000](https://trailblazer.salesforce.com/issues_view?id=a1p4V0000029kTjQAI&title=navigation-failing-when-orders-are-more-than-1000) ## Updated Cartridges & Tools ### sfcc-cartridge-overrides-vscode-extension (v1.0.1) - [https://github.com/sfccdevops/sfcc-cartridge-overrides-vscode-extension](https://github.com/sfccdevops/sfcc-cartridge-overrides-vscode-extension) > VS Code Extension to Display SFCC Cartridge Overrides Fix issue with Workspace Detection Issues. Tested this solution with a few different workspace setups and it seems to resolve the following issues: Fixes [#1](https://github.com/sfccdevops/sfcc-cartridge-overrides-vscode-extension/issues/1), [#2](https://github.com/sfccdevops/sfcc-cartridge-overrides-vscode-extension/issues/2) & [#3](https://github.com/sfccdevops/sfcc-cartridge-overrides-vscode-extension/issues/3) ### commerce-sdk-isomorphic (v1.6.0) - [https://github.com/SalesforceCommerceCloud/commerce-sdk-isomorphic](https://github.com/SalesforceCommerceCloud/commerce-sdk-isomorphic) > The Salesforce Commerce SDK Isomorphic allows easy interaction with the Salesforce B2C Commerce platform Shopper APIs through a lightweight SDK that works both on browsers and NodeJS applications. API Changes ### Shopper Login New Endpoints | **Endpoint Name** | **Description** | | --- | --- | | getPasswordResetToken | Request a reset password token | | resetPassword | Creates a new password | Enchancements More error handling has been added in the SLAS helpers Bug fixes SLAS helper `loginRegisteredUserB2C` no longer calls `redirectURI` when running server side Documentation `README` updated to explicitly note lack of CORS support for SCAPI ### plugin\_redirect - [https://github.com/SalesforceCommerceCloud/plugin\_redirect](https://github.com/SalesforceCommerceCloud/plugin_redirect) > The Hybrid Storefront plug-in cartridge (name tentative) provides Storefront Reference Architecture (SFRA) and SiteGenesis sites with a mechanism for redirecting pages to PWA Kit as part of a hybrid storefront strategy. Not so much an update as this cartridge does not have an official release yet, but an important one exists if you want to implement a hybrid deployment using SFRA/SG in combination with the PWA Kit. ### sgmf-scripts (v2.4.2) - [https://github.com/SalesforceCommerceCloud/sgmf-scripts](https://github.com/SalesforceCommerceCloud/sgmf-scripts) > This repository contains a collection of scrips that are useful for creating Storefront Reference Architecture overlay cartridges. All of the scripts are executable through CLI. Changes - Added `--fix` option when linting js and scss files ([#33](https://github.com/SalesforceCommerceCloud/sgmf-scripts/pull/33)) - Removed unused `webdriverio` ([#60](https://github.com/SalesforceCommerceCloud/sgmf-scripts/pull/60)) ### sfra-webpack-builder (v3.3.2) - [https://github.com/SalesforceCommerceCloud/sfra-webpack-builder](https://github.com/SalesforceCommerceCloud/sfra-webpack-builder) > Webpack can be cumbersome to setup, especially in multicartridge projects for SFRA. This plugin let you bundle all your js, scss and jsx files out of the box. I don’t think anything has changed in this release besides updating the package version. But it might be good to put it on the list, so people know this one exists! ### b2c-commerce-toolkit-for-grocery (v1.3.0) - [https://github.com/SalesforceCommerceCloud/b2c-commerce-toolkit-for-grocery](https://github.com/SalesforceCommerceCloud/b2c-commerce-toolkit-for-grocery) > This demo version of a grocery storefront includes store and time slot selection, grocery-specific shopping experiences for all key store pages, and edit order capabilities. A sample grocery data set and a few typical configurations are also included. Changes > **Removed:** some redundant code which is now part of SFRA ### plugin\_einstein\_ api (v0.0.4) - [https://github.com/SalesforceCommerceCloud/plugin\_einstein\_api](https://github.com/SalesforceCommerceCloud/plugin_einstein_api) > This is the repository for the plugin\_einstein\_ api plugin. This plugin enhances the app\_storefront\_ base cartridge by adding the Einstein API capabilities. Einstein API is the API-led interface from Salesforce B2C Commerce Einstein, and can be leverage to include Einstein product recommendations in places that are not displayed through a content slot on the storefront, or even outside of the storefront. What’s Changed Bugfix/cart productlineitems by [@adrien-monte](https://github.com/adrien-monte) in [#8](https://github.com/SalesforceCommerceCloud/plugin_einstein_api/pull/8) New Contributors [\_@\_adrien-monte](https://github.com/adrien-monte) made their first contribution in [#8](https://github.com/SalesforceCommerceCloud/plugin_einstein_api/pull/8) --- ## SiteGenesis vs SFRA vs PWA Canonical URL: https://rhino-inquisitor.com/sitegenesis-vs-sfra-vs-pwa/ Markdown URL: https://rhino-inquisitor.com/sitegenesis-vs-sfra-vs-pwa/index.md Content type: article Published: 2022-07-17T13:42:22Z Updated: 2023-03-30T07:02:37Z Summary: Those interested in Salesforce B2C Commerce Cloud will hear the term SiteGenesis and SFRA (and PWA). But what is the difference? Categories: Salesforce Commerce Cloud Tags: headless, sfcc, sfra, sitegenesis ## Key Takeaways - Compares SiteGenesis, SFRA, and PWA Kit as the main storefront architecture options in the SFCC ecosystem - Explains the trade-offs around legacy constraints, third-party support, headless flexibility, and out-of-the-box feature coverage - Helps teams choose a storefront direction based on modernization goals, budget, and required integrations [Salesforce B2C Commerce Cloud](https://www.salesforce.com/products/commerce-cloud/ecommerce/) is a modern Commerce platform that empowers retailers of all sizes and industries to harness the power of the cloud to deliver world-class omnichannel experiences. With Salesforce B2C Commerce Cloud, you can effortlessly offer your customers a seamless and personalized shopping journey across the mobile, social, and in-store channels while gaining valuable insights into who they are and what they want. But after choosing SFCC to be the platform, a second big decision must be made. **On what architecture will you base your channels**? When introduced to Salesforce B2C Commerce Cloud, you will hear terms such as SiteGenesis, SFRA, and (more recently) PWA. But what are the differences? What should I watch out for? ## Timeline Before we get started, here is a timeline showing the history of the “development architectures” used on Salesforce B2C Commerce Cloud throughout the years. ![SFCC History: 2009 - SiteGenesis 1.0, with version 2.0 being released in 2014. The next release was in 2017 with MFRA, being rebranded to SFRA in 2018. The latest release was the PWA Kit in 2021.](/sitegenesis-vs-sfra-vs-pwa/sfcc-history-86f56e594a_hu_75a7becca850c12b.webp) This timeline shows how Salesforce storefront architecture moved from SiteGenesis to SFRA and then PWA Kit. ## SiteGenesis ![SiteGenesis storefront example representing the legacy architecture.](/sitegenesis-vs-sfra-vs-pwa/sitegenesis-9a921c285a_hu_bfc37c8c0076ccc5.webp) SiteGenesis reflects the older monolithic storefront model many teams still inherit. Let us start with the oldest (and least exciting option): [SiteGenesis](https://production-sitegenesis-dw.demandware.net/on/demandware.store/Sites-SiteGenesis-Site). If anyone still suggests that you start your journey with SiteGenesis, you should ask the question, “why do we need to do that?”. Why would I say this, even though minor updates are still happening to it in 2022? Looking at the timeline above, it is clear that newer options are available. And why these options are better suited for new projects should become clear as you continue to read this article. ### It’s the old way of doing things (for SFCC) The biggest reason not to use SiteGenesis or migrate away from it, is that it uses outdated techniques and relies on older frameworks. An example is the SCSS, which uses “[responsive design](https://en.wikipedia.org/wiki/Responsive_web_design).” Not saying that this is a bad thing, as it was “the” way to do it in 2014. But this was replaced by a mobile-first methodology a few years later (which MFRA is based on, but we’ll get to that later!) Responsive Design still has a place, especially if most of your visitors are not mobile but on desktop devices. But for most merchants, mobile claims the most significant percentage of visitors. ### Third-party integrations Salesforce B2C Commerce Cloud comes with a lot of features out-of-the-box. But it can’t do everything, so it depends on third parties to create “cartridges” that extend that base (payment providers, shipping providers, OMS, ERP, …). **NOTE:** The above statement is also true for other platforms besides SFCC. But since 2020, it is no longer required to build for SiteGenesis; SFRA compatibility is enough. This shows that Salesforce wants to push new (and existing) clients away from using SiteGenesis. ### Pipelines VS Controllers ![Pipeline editor used in legacy SiteGenesis development.](/sitegenesis-vs-sfra-vs-pwa/pipelines-eed67b4c67_hu_593b294936b3aed3.webp) Pipelines were central to SiteGenesis development before controllers became the norm. Pipelines in SiteGenesis ![Controller-based storefront code replacing pipelines in newer architectures.](/sitegenesis-vs-sfra-vs-pwa/controllers-130298bfb4_hu_33bf471336664d42.webp) Controller-based development was one of the key shifts that came with newer storefront stacks. Controllers in SiteGenesis Looking at the timeline, you will see that pipelines have disappeared in MFRA (2017). This is a legacy way of development within Salesforce B2C Commerce Cloud and has been replaced by JavaScript (controller-type) development. It is time to migrate if you are still using SiteGenesis with pipelines in your project/site since new features will not be available in this framework. **Note:** It is also substantially harder to find developers who know how to work with Pipelines. And working with pipelines is not supported by the latest and greatest development tools. ## M(S)FRA ![Comparison between SiteGenesis and SFRA storefront stacks.](/sitegenesis-vs-sfra-vs-pwa/sfra-vs-sitegenesis-965c09b9a6_hu_b93be19e82ca4e6f.webp) SFRA modernized the storefront layer without fully abandoning the B2C runtime model. This part of the article will cover both MFRA and [SFRA](https://production-sitegenesis-dw.demandware.net/s/RefArch/home?lang=en_US) as they are the same. You can see MFRA as the ALPHA/BETA version of SFRA or simply as a rebranding. In 2016 Demandware (before [Salesforce acquired Demandware](https://www.salesforce.com/news/press-releases/2016/06/01/salesforce-signs-definitive-agreement-to-acquire-demandware/) in the same year) saw an increased need for high-quality mobile experiences. SiteGenesis was not up for the task, so MFRA was “born.” A new modern mobile-first web foundation was created that used technologies such as Bootstrap, HTML5, and CSS3, making it much easier to create mobile experiences. Along with using these technologies, better storefront performance and UX were part of this new architecture. ### Best Practices Based on research on many of the already live websites on the SiteGenesis platform, best practices were identified to improve user experience and the shopper journey. Using the gathered data, the pages part of the SFRA were designed together with the user flows. ### Development & Updates Although development on the central repository has halted, new features added to the platform are still being developed for SFRA. These are created as separate “cartridges” rather than putting them in the base template. This gives customers and partners the flexibility to only include the features they need rather than having to remove them to clean up the code. Salesforce is also actively pushing customers towards SFRA, even though a new headless architecture has become available (PWA Kit). The reason for this will become more apparent as you continue reading. ### Third-party integrations (M(S)FRA) I will keep this short. Third parties are actively integrating with SFRA and updating their cartridges! So choosing to go with SFRA now will be a good base for years to come. But be sure to continue reading, as the PWA Kit solution may be attractive for your organization! ## PWA Kit & Managed Runtime ![PWA Kit storefront running in the managed runtime.](/sitegenesis-vs-sfra-vs-pwa/pwa-kit-03394b0f92_hu_e56aa2bf1eb8f1c0.webp) PWA Kit pushes the storefront into a composable architecture outside the traditional stack. The [PWA Kit](https://pwa-kit.mobify-storefront.com/) is the most recent addition to the SFCC family. And it is important to note that this solution is not marketed at the moment to replace SFRA. You might be wondering why, and there is a good reason for that. ### Headless solution Unlike SiteGenesis and SFRA, the PWA Kit runs on a separate server. It connects with the [SCAPI](https://developer.salesforce.com/docs/commerce/commerce-api/guide) and [OCAPI](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/OpenCommerceAPI.html?cp=0_16) (REST APIs) of the Salesforce B2C Commerce Cloud environments. It is an entirely different type of architecture than the “[monolithic](https://en.wikipedia.org/wiki/Monolithic_application#:~:text=In%20software%20engineering%2C%20a%20monolithic,independent%20from%20other%20computing%20applications.)” approach we are used to within SFCC. But what does this mean, going Headless? You can find more information about it in this [blog post](https://forward.eu/blog/headless/) or [watch this YouTube video](https://www.youtube.com/watch?v=BTS6OqwMiK4&feature=emb%5c_title) where I explain what it means to go Headless with Salesforce B2C Commerce Cloud. Play video A great [podcast episode](https://www.youtube.com/watch?v=hIghXeYIsEs&list=PLAQgCOXBCvL360AJzTZKTQe1wqvq4TLkD&index=6) is also available on the “Unofficial Salesforce Commerce Cloud Podcast” about Headless and the PWA Kit. Play video ### Managed Runtime When talking headless, you need to think about the hosting for your storefront. Salesforce provides hosting for the “body”, but what about the “head”? No worries on that front! Salesforce provides a [Managed Runtime](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/mrt-overview.html) solution that is included in the license. > Managed Runtime provides the infrastructure to deploy, host, and monitor your PWA Kit storefront. ### React.JS Another significant change in working is that the PWA Kit is built upon [React](https://reactjs.org/), a modern library that does not have such a “niche” flavor that SFCC has known up until now. It will be easier to find and educate developers in this setup. > **Important:** to note that developers will still need to learn about the SCAPI and OCAPI endpoints, which have a steady learning curve. **Note:** The PWA Kit is only responsible for the front end. The back-end integrations such as importing products, prices, and inventory will still need to be done the “old-fashioned” way. ### Progressive Web Apps I will not go into much detail on what Progressive Web Apps are. There is a lot of great content available on the web which explains it and how it compares to native applications. And again, there is a [podcast episode available dedicated to this topic](https://www.youtube.com/watch?v=eOFC5rLHZZ4&list=PLAQgCOXBCvL360AJzTZKTQe1wqvq4TLkD&index=3)! Play video ### Third-party integrations (PWA Kit & Managed Runtime) As this solution is pretty new, few third-party solutions are plug-and-play like SFRA. A more considerable investment in budget/time is required for now. Looking at the past few weeks/months, there is a [good amount of interest](https://marketplace.magnolia-cms.com/detail/salesforce-commerce-cloud.html) in building integrations. Like SFRA in 2017, time is required to make a fair amount of third-party prebuilt solutions. ### Missing out-of-the-box features I may sound like a broken record, but a few features built into SFRA are not in the PWA Kit since the solution is new. A few examples are: - [A/B Testing](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/ab_testing/b2c_ab_testing.html) - ~~Personalization~~ (Added in 2023) - [~~Page Designer~~](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/page_designer/b2c_dev_for_page_designer.html) ( Added in 2023) - [Sitemap](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/search_engine_optimization/b2c_sitemap_overview.html) - [SEO URL Configuration](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/search_engine_optimization/b2c_configuring_seo_urls.html) - [Page Meta Tag Rules](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/categories/b2c_page_meta_tag_rules.htm) All of these “missing items” can be resolved with custom development. So be prepared to spend more time and budget to build these features if needed. And many of these are on the roadmap of Salesforce, so if you wait a bit longer (or adapt your implementation timeline/order of implementation), the above list will be much smaller. ## Comparison The following overview compresses the information above. ![Comparison table contrasting SiteGenesis, SFRA, and PWA Kit characteristics.](/sitegenesis-vs-sfra-vs-pwa/comparison-sitegenesis-sfra-pwa-5593ba325c_hu_1ec269f4beae05b7.webp) This final comparison makes the trade-offs between the three storefront approaches easier to judge. --- ## Creating custom OCAPI endpoints Canonical URL: https://rhino-inquisitor.com/creating-custom-ocapi-endpoints/ Markdown URL: https://rhino-inquisitor.com/creating-custom-ocapi-endpoints/index.md Content type: article Published: 2022-07-11T17:40:22Z Updated: 2023-09-26T09:54:35Z Summary: Officially there is no possibility to define custom OCAPI endpoints. But is there a clever way to create them anyway? Find out here! Categories: Salesforce Commerce Cloud, Technical Tags: headless, ocapi, sfcc, technical ## Key Takeaways - Shows the legacy custom-object hook workaround for building custom OCAPI GET endpoints - Explains the setup steps, limitations, and cartridge code behind the approach - Warns that the pattern is deprecated and carries real security and transaction constraints > **Deprecated:** Since writing this article, Salesforce has provided a new and better method for creating custom endpoints. You can find more information about it at [https://developer.salesforce.com/docs/commerce/commerce-api/guide/custom-apis.html](https://developer.salesforce.com/docs/commerce/commerce-api/guide/custom-apis.html). The OCAPI ([Open Commerce API](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/OpenCommerceAPI.html?cp=0_16)) has been around for many years, giving the platform a sound basis for “headless” applications to connect to different parts of Salesforce B2C Commerce Cloud. Although the APIs need to remain close to the standard, some endpoints have been given some freedom to be customized via a system called “[hooks](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/Hooks.html).” But how about adding completely custom endpoints? Warning! The example I have used (getCustomer) is an example of something you should not do because of security reasons. It just shows the possibilities, and you should consider performance, security, and common sense when building these endpoints. ## Is there no “official” way The OCAPI provides a set of predefined endpoints you can not stray from. There is no out-of-the-box feature that allows you to create your endpoint on top of the existing set of REST APIs. The only thing you are allowed to do is modify existing endpoints, but not all of them. A list of which customizations you are allowed to do is available on the [Salesforce Commerce Cloud Infocenter](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/Hooks.html). ## TLDR; Just give me the solution I have created a complete example available on GitHub based on the [sfcc-hooks-collection](https://github.com/SalesforceCommerceCloud/sfcc-hooks-collection/) project provided by [Holger Nestmann](https://github.com/hnestmann). You can find that repository [in the OCAPI custom endpoints example repository](https://github.com/taurgis/ocapi-custom-endpoints). Inside, you will find an example of a custom “get-customer” API added to the OCAPI **.** ## Limitation of this custom solution The solution provided in this article will only allow you to create custom GET calls without any transactions. This is because we will add a hook to the [GET call of Custom Objects](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/shop/Resources/CustomObjects.html#id1419723884__id-587924678) in the Shop API. And a limitation of a hook added to a GET call is that opening transactions is forbidden (no creates or updates in the database). > _**Note:** Do not modify a Script API object in an HTTP GET request or a modifyResponse hook, because they are never executed in a transactional context. It can cause an ORMTransactionException and an HTTP 500 fault response._ Infocenter ## Custom Objects Yes, custom objects! Since we have complete control of the naming and creation of custom objects, it is the perfect candidate. And because it allows us to add a hook to the REST GET call, it provides an ideal opportunity to create custom endpoints in the context of the customer session. ## Step 1: Create the Custom Object Type So let’s get cracking! The first step is to create a new custom object type in the business manager that we can use in the OCAPI. Go to “_Administration _” > “_ Site Development _” > “_ Custom Object Types_.” [![Custom Object Types screen with the CustomApi definition.](/creating-custom-ocapi-endpoints/custom-api-custom-object-051e16e59a_hu_ecef8328fe84968a.webp)](custom-api-custom-object-051e16e59a.png) The custom object definition becomes the registry for every endpoint the hook will expose. The Custom Object Definition is quite simple: - **ID:** CustomApi - **Key Attribute:** ID of the type _String_ - **Name:** Custom API (though this doesn’t matter) - **Description:** Whatever you like ;-) - **Data Replication:** Replicable (we don’t want to configure this separately per environment) - **Storage Scope:** Organization (it doesn’t make sense to do this on the Site level) There is also an [import file available on the GitHub repository](https://github.com/taurgis/ocapi-custom-endpoints/blob/main/metadata/custom-object-types.xml). ## Step 2: Create the Custom Object for your API Each custom API endpoint needs its unique object of the “CustomApi” type. So in this example, we will make one get customers by their “Customer Number.” To do this go to “_Merchant Tools _” > “_ Custom Objects _” > “_ Manage Custom Objects_.” [![Manage Custom Objects screen with the get-customer object.](/creating-custom-ocapi-endpoints/manage-get-customer-object-7b88237d34_hu_9c7ae2ae37cdffe0.webp)](manage-get-customer-object-7b88237d34.png) Each custom object instance maps a friendly endpoint name to real implementation data. The Custom Object is, again, easy to set up: - **ID:** get-customer (this is important as we need this ID to call the service and the script we will put behind it) There is also an [import file available on the GitHub repository](https://github.com/taurgis/ocapi-custom-endpoints/blob/main/metadata/CustomApi.xml). ## Step 3: Configure OCAPI access We also need to make sure we can access the GET call for the Custom Objects endpoint. To provide access we go to: “_Administration _” > “_ Site Development _” > “_ Open Commerce API Settings._” Fill in the following value for the type “_Shop _” and context “_ Global (Organization-wide)_.” ```json { "_v": "22.6", "clients": [ { "client_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "allowed_origins": [], "resources": [ { "resource_id": "/custom_objects/*/*", "methods": [ "get" ], "read_attributes": "(**)", "write_attributes": "(**)" } ] } ] } ``` [![Open Commerce API Settings showing access for custom objects.](/creating-custom-ocapi-endpoints/ocapi-settings-46b5f9c8b0_hu_5aa4cfaa1a010bed.webp)](ocapi-settings-46b5f9c8b0.png) OCAPI access still has to be granted explicitly before the endpoint becomes callable. In the example, we make use of “aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa” ( 30 x a ), which is a Client Id that works on test environments without creating it in the Account Manager. You can, of course, create your own Client ID, but we will not be covering that process in this article. ## Step 4: Create our custom hook Time to start coding (finally)! But before we start creating our scripts, we need to tell Salesforce B2C Commerce Cloud that we want to “hook” into an OCAPI endpoint. For this, we create a [package.json](https://github.com/taurgis/ocapi-custom-endpoints/blob/main/cartridges/plugin_custom_ocapi_endpoints/package.json) file in the root of our cartridge with the following contents. ```json { "hooks": "./hooks.json" } ``` This file says a “hooks” config file is available in our project. Now we also have to make [that file](https://github.com/taurgis/ocapi-custom-endpoints/blob/main/cartridges/plugin_custom_ocapi_endpoints/hooks.json)! ```json { "hooks": [ { "name": "dw.ocapi.shop.custom_object.modifyGETResponse", "script": "./cartridge/scripts/hooks/customObjectsHooks.js" } ] } ``` In this file, we declare that we want to modify the GET response of the Custom Object endpoint with a specific script. Not sure where to create these files? Have a peek at the [GitHub repository](https://github.com/taurgis/ocapi-custom-endpoints/tree/main/cartridges/plugin_custom_ocapi_endpoints)! You probably noticed that we also need to create a script file 😉. So let us also do that at the location defined in “[hooks.json](https://github.com/taurgis/ocapi-custom-endpoints/blob/main/cartridges/plugin_custom_ocapi_endpoints/hooks.json).” ```js 'use strict'; var toCamel = function (s) { // eslint-disable-next-line no-useless-escape return s.replace(/(-[a-z])/g, function ($1) { return $1.toUpperCase().replace('-', ''); }); }; /** * Custom Object Modify Get Hook * @param {Object} scriptObject - the database object * @param {Object} doc - the document */ exports.modifyGETResponse = function (customObject, doc) { if (customObject.type === 'CustomApi') { var result = require('*/cartridge/scripts/apis/' + toCamel(customObject.custom.ID)).get(request.httpParameters); doc.c_result = result; } }; ``` Another simple step as the script does not contain anything complicated. It does the following things: 1. Check if the API call is for an object of type “CustomApi,” which we created earlier. We should not execute any custom code if it is of another type. 2. Use the custom object ID we defined to call the correct script. This is, however, treated to become a camel-case filename. For example: “get-customer” becomes “getCustomer.” 1. The dynamic require is executed, and the result object is stored in a variable. 2. The resulting object is added to the response object prefixed with “[c\_](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/CustomProperties.html?resultof=%22%6f%63%61%70%69%22%20%22%63%5f%22%20%22%63%22%20).” In our example, the code will execute our “getCustomer.js” file, which looks something like this: ```js 'use strict'; /** * Fetch customer data using the Customer Number. * * WARNING: This is a very unsafe endpoint as you can fetch all accounts with an ID that is incremental! The idea is * just to show what is possible! And that with this possibility you can create serious security holes! * */ exports.get = function (httpParams) { var result = {}; if(!empty(httpParams.customer_no)) { var CustomerMgr = require('dw/customer/CustomerMgr'); var customer = CustomerMgr.getCustomerByCustomerNumber(httpParams.customer_no.pop()); if(customer) { result.first_name = customer.profile.firstName; result.last_name = customer.profile.lastName; } else { result.error = 'Customer not found'; result.customer_no = httpParams.customer_no; } } return result; }; ``` Are you a bit confused about where to place these files? Have a look at the [GitHub repository](https://github.com/taurgis/ocapi-custom-endpoints/tree/main/cartridges/plugin_custom_ocapi_endpoints/cartridge/scripts)! ## Step 5: Upload the cartridge As with any cartridge, we need to upload it to our environment. Don’t forget to add it to the cartridge path of your site(s) (not the BM Cartridge path). We add it to the sites because the API is part of the Shop API, which is meant for Storefront applications. ## Step 6: Call the API [![Custom OCAPI response payload returned by the get-customer endpoint.](/creating-custom-ocapi-endpoints/get-customer-custom-api-response-a6c8902585_hu_b85ac1da9fb5a49c.webp)](get-customer-custom-api-response-a6c8902585.png) A successful response proves the custom endpoint can shape payloads beyond the standard API. The final step is calling your endpoint (with the correct parameters). In this case, we have the parameter “customer\_no,” which we use in our custom code to fetch the right customer. To make it easier to understand how to test the API, I added a [Postman collection to the GitHub repository](https://github.com/taurgis/ocapi-custom-endpoints/blob/main/Custom%20API.postman_collection.json). This collection requires you to configure the following variables: [![Postman variables required to call the custom OCAPI endpoint.](/creating-custom-ocapi-endpoints/postman-variables-custom-api-ec0a89ffce_hu_48a45f25e3de727b.webp)](postman-variables-custom-api-ec0a89ffce.png) These Postman variables remove the manual busywork from repeatedly testing the custom endpoint. - **base\_url:** The domain of your environment. - **client\_id:** Your client ID, you can use the default one. - **client\_pw:** Your client password, you can use the default one. The collection also contains two premade API calls: - **1\. GetOAuth2 client token:** This fetches the bearer token - **2\. Custom API: Get Customer:** The call to fetch the Custom Object with the customized response ## Final thoughts Although this might seem like a “hacky” way to get a custom API up and running in the OCAPI, it allows you to create a custom endpoint without worrying about an authorization/authentication/caching framework. It’s not perfect, but this gives you another option to add to your arsenal to tackle specific use-cases thrown at you. And it is always nice to have options! --- ## Community Salesforce Events and Commerce Cloud Canonical URL: https://rhino-inquisitor.com/community-salesforce-events-and-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/community-salesforce-events-and-commerce-cloud/index.md Content type: article Published: 2022-07-04T17:24:31Z Updated: 2022-07-23T19:15:14Z Summary: Salesforce knows many community-organized events. But how does Salesforce B2C Commerce Cloud fit in? And how can we contribute? Categories: Community Tags: ohana, sfcc, yeurdreamin' ## Key Takeaways - Surveys community-led Salesforce events and where Commerce Cloud currently fits in - Explains why SFCC content is still sparse on broader community event agendas - Encourages Commerce professionals to submit talks and broaden cross-cloud participation Salesforce is known for hosting spectacular events all over the world. But did you know the community organizes some amazing ones as well? Maybe you don’t if you are a Salesforce B2C Commerce Cloud enthusiast, but why is that? Let us dig deeper into some of the events that caught my eye! ## Some of the events ### [YeurDreamin’](https://www.yeurdreamin.eu/) - [https://www.yeurdreamin.eu/](https://www.yeurdreamin.eu/) - [Session recording](https://www.youtube.com/watch?v=cV6N%5c_uuNku4) Play video If you have been following me, you will have noticed that I recently visited this one and also had the [privilege of presenting two sessions](/events-and-the-golden-hoodie/)! A relatively “new” event, as the first one was in 2019, and 2020, didn’t happen for obvious reasons. The year is now 2022, and the second edition occurred in person, and I can testify that it was a blast! ### [London’s Calling](https://www.londonscalling.net/) - [https://www.londonscalling.net/](https://www.londonscalling.net/) - [Session recording](https://youtu.be/wsv8nZkQkx8) The biggest community-led event in Europe, and I’m not kidding. Going strong since 2016, it had its 7th edition in 2022! Not surprisingly, this event is held in London, attracting many visitors from Europe and beyond. This one is on my wishlist for 2023! ### [CzechDreamin’](https://czechdreamin.com/) - [https://czechdreamin.com/](https://czechdreamin.com/) Another one from Europe, this time - you guessed it - in the Czech Republic! It calls itself a technical conference, but there are a few sessions that are not as technical as most of them. CzechDreamin is, just like YeurDreamin, relatively new as it started in 2019. It just had its third edition (one was virtual in 2021). ### [French Touch Dreamin’](https://frenchtouchdreamin.com/) - [https://frenchtouchdreamin.com/](https://frenchtouchdreamin.com/) - [Session recording](https://www.youtube.com/watch?v=zV8owFGyNEA) I will keep those European events coming, cause you guessed it - I am from Europe! This time we are going to France. 2016 was an excellent vintage for the community as this one also had its very first edition then! ### [Cactusforce](https://www.cactusforce.com/) - [https://www.cactusforce.com/](https://www.cactusforce.com/) - [Session recording](https://www.youtube.com/watch?v=HvjC5ZUg6Kk) Let us finally switch continents, shall we? We are heading to Arizona for a community event focused on developers and architects who want “More code. Less fluff.” So expect some technical deep dives at this conference! Even if you cannot attend in person, it is a hybrid event that will allow people to join in on the fun remotely! ### [North Africa Dreamin’](https://northafricadreamin.com/) - [https://northafricadreamin.com/](https://northafricadreamin.com/) - [Session recording](https://www.youtube.com/watch?v=MatNmbnz%5c_MA) Are they switching continents again? Really? Of course! The Salesforce Community is a global community; why are you acting so surprised I am switching continents again? Having its first edition in 2019, it is now on again in 2022 for its second! Another excellent opportunity to meet people from around the globe! ### [dreamOlé](https://dreamole.es/) - [https://dreamole.es/](https://frenchtouchdreamin.com/) - [Session recording](https://www.youtube.com/watch?v=fQxqdvya48E) Play video Olé, off to Spain we go and back to Europe 😛! So many countries with so many people willing to share their knowledge about Salesforce! Starting in 2017, this event has, like so many others, seen a break in 2020 and 2021. But this year, it was back, and hopefully again in 2023! ### And more The list doesn’t end here. There are [a lot more out there](https://meighanrockssf.com/2022/01/31/salesforce-events-2022/)! ## Are they organized by the community Yes! These events are not organized in any way by Salesforce. Usually, Salesforce does offer support in terms of communication, speakers, and other elements such as SWAG. This also means that these events have a completely different feel than those organized by Salesforce. Here experiences are openly shared between developers, architects, and other roles without the influence of Salesforce. These events tend to be much more technical, offering an excellent opportunity to learn! Not that this does not happen at the official Salesforce events, but there is always a “sales” vibe floating about when going to those events and the presentations themselves. (And there is nothing wrong with that). ## Is there B2C Commerce Cloud content Well…no. There have been a few sessions here and there if you look at the events’ past occurrences (maybe one max per event). But is that so surprising looking at the history of SFCC? Many of these events had their first occurrence just as the acquisition of Demandware happened. So agendas didn’t need Commerce Cloud content, and it is not like the SFCC community has pushed to get Commerce content on the schedule. And that makes it hard to have a bit of room in an already jam-packed list of speakers wanting to spread the word of [force.com](https://force.com/). It is an extensive ecosystem within one platform, with many different features that require someone to explain them. So is there room for some Commerce Cloud? ### Speaking at events Yes, there is! I took a chance, submitted two topics to YeurDreamin’, and got selected. I will be honest; I put the Commerce Cloud topics in a sauce of multi-cloud to make it more appealing to the public within the eco-system. But we need to start somewhere. To get Commerce Cloud content in these events, people must submit topics when the “Call for speakers” pops up! So what are you waiting for? Do you want to share your expertise about Salesforce B2C Commerce Cloud? Submit your topics to these events once the gates for the speakers are opened! **Hint:** Subscribe to the newsletters and follow the official Twitter channels to get notified when the “Call to speakers” is announced. ### Open your mind Will there be enough room to fill an entire day just about Commerce Cloud? No, of course not. I feel that the Commerce Cloud community should use this opportunity to learn about other products within the Salesforce ecosystem. Especially since they are becoming more and more intertwined, and connections with these products in projects happen more often than a few years ago. It is wonderful to connect with admins, developers, and architects who use these products daily, offering different perspectives. ### A Commerce Cloud-focused community event Well, that doesn’t exist right now. Is that something that you would love to have or are interested in? [Let me know on LinkedIn](https://www.linkedin.com/in/thomas-theunen-10905680/)! --- ## How to setup OAuth JWT for the OCAPI Canonical URL: https://rhino-inquisitor.com/how-to-setup-oauth-jwt-for-the-ocapi/ Markdown URL: https://rhino-inquisitor.com/how-to-setup-oauth-jwt-for-the-ocapi/index.md Content type: article Published: 2022-06-27T17:49:25Z Updated: 2022-07-23T19:16:34Z Summary: Setting up JWT with the OCAPI has not been the easiest thing to do. The documentation makes you make assumptions with vague instructions. Categories: Salesforce Commerce Cloud, Technical Tags: jwt, security, sfcc, technical ## Key Takeaways - Explains how to configure private_key_jwt authentication for OCAPI server-to-server access - Walks through key generation, Account Manager setup, and JWT payload requirements - Provides a practical Postman-based example for generating and exchanging the signed token _IMPORTANT_: This article is about server-to-server communication When working with the OCAPI ([Open Commerce API](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/OpenCommerceAPI.html?cp=0_16)), you need to do some sort of authentication to prove who you are and to verify what actions you are allowed to take. Salesforce B2C Commerce Cloud provides multiple methods for server-to-server authentication scenarios depending on the use case: - Basic Authentication using the API Key and the Secret - Basic Authentication using the API Key, Secret, Username, and User Password - JWT In this article, we will focus on the one most ‘challenging?’ to set up: the JWT token. ## Generating a public and private key pair When working with JWT, we will use a signing method to verify the authenticity of the requests sent to the server. These are easy to generate, and you have complete control over how long they are valid. Open up your favorite terminal and execute the following command in your folder of choice: ```text openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes ``` This command will create two files: - **key.pem:** Your private key that will be used to sign requests to the OCAPI authorization endpoint - **cert.pem:** The certificate containing the public key will be needed later when setting up the API key in AM (Account Manager). ## Create a new API Key Like always, when we set up a server-to-server connection, we need to generate an API key in the [Account Manager](https://account.demandware.com/). Follow the i[nstructions on the Infocenter](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/account_manager/b2c_account_manager_add_api_client_id.html), with a few minor changes. [![Account Manager client configuration for private_key_jwt authentication.](/how-to-setup-oauth-jwt-for-the-ocapi/account-manager-set-up-jwt-c2ed29ddca_hu_ac55752609551496.webp)](account-manager-set-up-jwt-c2ed29ddca.jpg) This Account Manager setup is the prerequisite for private\_key\_jwt authentication. 1. In the JWT field, copy and paste the entire contents of the “**cert.pem**” file we generated earlier (no modifications needed) 2. Set the Token Endpoint Auth Method to **private\_key\_ jwt**. And click save! ## Authenticate Ok, I made that title seem like this is an easy step to do. Generating the JWT might be the most challenging part as you need to be very specific, and there is a signing step with that private key mentioned before. ### JWT But let us look at the basics. A JWT has three different parts. [![Diagram showing the header, payload, and signature parts of a JWT.](/how-to-setup-oauth-jwt-for-the-ocapi/jwt-visualized-74d5a59116_hu_1e3f6645cd8f9671.webp)](jwt-visualized-74d5a59116.jpg) A JWT stays simple at heart: header, payload, and signature. The **header,** which describes what type the JWT is and what algorithm it is using. In this case, [RS256](https://auth0.com/blog/rs256-vs-hs256-whats-the-difference/) is used. The **payload,** which is the data we are trying to send to the server. To get a token back, Salesforce B2C Commerce Cloud requires the following information to be in the JWT: - **iss (issuer):** The client ID (API Key) - **sub (subject):** The client ID (API key) - **exp (expiration time):** Current time + x seconds (1 second should do it) - **aud (audience):** The Account Manager auth endpoint The **signature**, which is the header and payload signed with the private key to verify that you are allowed to send it to the server. ### Generating it If you look at the above example, the contents of a JWT are far from “rocket science.” The hard part is signing it correctly, as you need to find a sound library in your programming language of choice to get it done. As an example, I have created a postman library to get you started! In this example, you need to set two collection variables: - **pkey:**The entire contents of the \_** key.pem**\_ file we generated earlier - **api\_key:** The API key you generated in the Account Manager There is also a variable called [**pmlib**](https://joolfe.github.io/postman-util-lib/dist/bundle.js): a third-party library meant to extend the capabilities of the scripting framework within [Postman](https://www.postman.com/). In the collection, a request called “1. Download JS for Postman” downloads it in case the initial value is not working. Since Postman does not support generating JWT tokens out-of-the-box there is a “Pre-request script” within the second call “2. Authorization (JWT)” which generates it and stores it in a collection variable used during the request. ```js // Load third party library eval(pm.collectionVariables.get("pmlib")); // Prepare timestamp in seconds var currentTimestamp = Math.floor(Date.now() / 1000) // Create header and payload objects var header = { "typ": "JWT", "alg": "RS256" }; var payload = { 'iss': pm.collectionVariables.get('api_key'), 'sub': pm.collectionVariables.get('api_key'), 'iat': currentTimestamp, 'exp': currentTimestamp + 300, // expiry time is 30 seconds from time of creation 'aud': 'https://account.demandware.com:443/dwsso/oauth2/access_token' }; // Generate the JWT and sign it var sJWT = pmlib.jwtSign(pm.collectionVariables.get('pkey'), payload, header); // Store the JWT to set in the body pm.collectionVariables.set("jwt_signed", sJWT); ``` Once the script is in place and all required variables are configured in the collection we can execute the request as follows: - A **POST** to [https://account.demandware.com/dwsso/oauth2/access\_token](https://account.demandware.com/dwsso/oauth2/access_token) - A body containing these 3 values as a **x-www-form-urlencoded** type: - client\_assertion: The signed JWT generated by the script - client\_assertion\_ type: urn:ietf:params:oauth:client-assertion-type:jwt-bearer - grant\_type: client\_ credentials [![Postman request configured for OCAPI JWT authentication.](/how-to-setup-oauth-jwt-for-the-ocapi/postman-authentication-ocapi-d973adb2eb_hu_b19735368ee19187.webp)](postman-authentication-ocapi-d973adb2eb.jpg) Postman is the fastest way to prove the OCAPI JWT flow works end to end. [Download Postman Collection](https://gist.github.com/taurgis/df656968852275539d9f9d7a74bf62de) A big thanks to [Yuriy Boev](https://www.linkedin.com/in/yuriy-boev-3907002b/) and [John Boxall](https://www.linkedin.com/in/jboxall/) for helping me get to a working example! I will refer you to the [Unofficial Slack thread](https://sfcc-unofficial.slack.com/archives/CBB7YAAHW/p1656070265465869) for other scripts or languages! --- ## Events and the Golden Hoodie Canonical URL: https://rhino-inquisitor.com/events-and-the-golden-hoodie/ Markdown URL: https://rhino-inquisitor.com/events-and-the-golden-hoodie/index.md Content type: article Published: 2022-06-21T04:14:28Z Updated: 2022-07-23T21:41:31Z Summary: June 2022 is a month I will remember for a long time to come. It is a story of Salesforce events and getting a Golden Hoodie! Categories: Community Tags: connections, ohana, sfcc, trailhead, yeurdreamin' ## Key Takeaways - Recaps the author's 2022 event journey across Connections, Salesforce Live Belgium, and YeurDreamin' - Explains the Golden Hoodie as community recognition rather than a checklist achievement - Argues that in-person community events matter again for learning and connection June 2022, I think this month will stick in my memory for a long time to come. It has been a fun and ’event’ful one! The pandemic has not ended, but life, before it started, has slowly begun to come alive again. Instead of meeting people remotely, you can see them face to face once more! And for many people (including myself), this has been quite the relief. ## Connections ‘22 Going back to events, for me, started with a blast! Back to Chicago and Connections. This event was coincidentally my first Salesforce event ever in 2019! I was thrilled to be going again, this time not just as a visitor but as a speaker! With a lot of help (and pushing) from [Amalia,](https://www.linkedin.com/in/amaliamurray/) we got a spot on multiple stages! I was thrilled to get this opportunity to tell my story and have colleagues present one of our customer cases. You can [watch the Connections session recording here](https://www.youtube.com/watch?list=PL9MknC1SggvKAXr33VuslT-eaenf0RRxI&v=VE-XxWXKBz4&feature=emb%5c_title). Play video But boy, did Connections have more in store for me than I could have anticipated! I was already amazed that I could be in the keynote, but there was a bigger surprise in store for me. ### Is it a technical conference The short answer is no. You will mainly be able to see roadmap and customer cases presented here. But if you look around carefully, you will find sessions that have some technical learnings in there! If you want a Salesforce conference with more technical workshops and presentations, [TrailblazerDX](/trailblazerdx-2022-for-b2c-commerce/) is the event to go to! ### Receiving a “Golden Hoodie” Contradictory to what people may think, I was not told beforehand! Although I should have picked up on a few signs, such as [Sasha Taylor](https://twitter.com/sashamilam) helping me prep for the event. She has “keeper of the Goldies” in her Twitter description… That might have been a give-away, right? Well, I didn’t pick up on it in the slightest. But it will be a moment I will never forget, you can be sure about that! You can [watch the Golden Hoodie moment here](https://www.youtube.com/watch?v=lWY-5s7OwCA). Play video And since then, I have gotten the question quite often, “what do you have to do to get a Golden Hoodie?” There is no answer to that question; the Golden Hoodie is recognition for contributions to the community, partners, and customers of Salesforce. There might be a list of prerequisites somewhere, but I do not know what the list is. It represents giving back and a willingness to help others grow in and outside of Salesforce. That is really all I can say about it. ### An end to (fully) remote events For me, Connections rang a bell to the end of virtual-only events. It was time again to go out in the world to meet people face to face again. And it was a success! I have met many people (finally) in person that I had been slacking, video conferencing… with for the past two years. This has been quite the relief for me since virtual and in-person are still very different things. For COVID though, it was probably a playground. And I am guessing many people went home with unwanted presents. I was luckily spared, but I got a few messages from people that I might want to be a bit more careful as they were not as lucky. Wearing masks and using hand sanitizer all the time seems to be a thing of the past. People who could not join the event in person have to use [Salesforce+](https://www.salesforce.com/plus/experience/world_tour/series/best_of_connections) to watch some recorded sessions, but unfortunately, not all of them are available. At least you can’t catch COVID from that, right? ## Salesforce Live Belgium ![Salesforce Live Belgium event slide featuring the author's Golden Hoodie recognition.](/events-and-the-golden-hoodie/salesforce-live-belgium-bba64ad521_hu_4238b6320878179c.webp) Being the first-ever Belgian Golden Hoodie recipient sure puts your picture as one giant slide at local Salesforce events! I am sooooo not used to this much attention! Barely getting time to recover from my jetlag from Connections, I went to [Salesforce Live Belgium](https://www.salesforce.com/eu/events/salesforce-live-belgium/) to reconnect in person with existing and (possibly) new customers! Besides meeting known faces, I also had the opportunity to meet people from the Belgian and European Salesforce team at this wonderful event. Summing it up: I had a great time, but wearing the Golden Hoodie during summer at events really makes you sweat! (And for people wondering, this is not a technical event.) ## [YeurDreamin’](https://www.yeurdreamin.eu/) ![YeurDreamin' - Headless](/events-and-the-golden-hoodie/yeurdreamin-headless-dc38d91630_hu_568b1b404fe088c0.webp) The year 2022 is also when I decided to become more involved in the local (and European) community events. The first (and the closest) that caught my attention was [YeurDreamin’](https://www.yeurdreamin.eu/), a Community Conference focusing on the Benelux. As with most Salesforce events, I saw a lack of Commerce Cloud-related talks, so I immediately decided to try to go as a speaker. I submitted two possible topics: - Headless - Multi-Cloud Projects (With Commerce at the center, no worries 😀) I was happy to get the message that one submission was accepted a month later: Multi-Cloud! And because one speaker could not make it, I was also allowed to talk about Headless. ### An event of connecting and learning Looking back at my first experience at a Community-led Conference, I can honestly say I am going to as many as possible! I finally met many people I was following on Twitter and had wonderful conversations about our professional and personal lives. These events are about connecting with your peers and learning from each other in a different setting. I would recommend anyone to try to attend them. And for those who want to know how technical this conference is: _**very**_! There is content for many different roles being presented. But as I mentioned, there are not many talks related to Salesforce B2C Commerce Cloud. So maybe 2022 also rings the bell that we should be more involved, no? ### Recordings All sessions were recorded. As soon as I have them available, I will add them to this article! ## What now Well, not much new. I am going to continue doing what I love doing at the pace of my choosing. A few people asked if I would start doing more things now that I received the Golden Hoodie. But I want to do things my way and at my speed; I don’t think receiving this recognition (thank you for this, by the way) should mean that I need to up my game even more. The only significant change this year is that the chances of us meeting face to face have grown significantly compared to the past two years (and before). Be sure to follow me on [X](https://x.com/theunenth) or [LinkedIn](https://www.linkedin.com/in/thomas-theunen-%E2%98%81%EF%B8%8F-10905680/) to see what Conferences I will be attending! --- ## Salesforce B2C Commerce Cloud: The 22.7 Release Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-the-22-7-release/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-the-22-7-release/index.md Content type: article Published: 2022-06-13T15:06:49Z Updated: 2022-07-23T21:59:53Z Summary: Are you interested in what is new in each Salesforce B2C Commerce Cloud release? Then this is the article for you! Let us look at 22.7 (July) Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc, technical ## Key Takeaways - Highlights the major 22.7 changes around Rhino engine upgrades, social-commerce direction, and PWA Kit 2.0 - Explains why the compatibility-mode improvements matter for developers using newer JavaScript features in SFCC - Calls out the related cartridge and tooling releases that support commerce payments, Einstein, and hybrid storefront work Summer has arrived, and so has the next Salesforce B2C Commerce Cloud release! This time we look at the [July 2022 (22.7) release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_22_7_release.htm&type=5)! Are you interested in last month’s release notes? Read the [22.6 release overview](/salesforce-b2c-commerce-the-22-6-release/). ## Social Commerce ![Social commerce artwork introducing the 22.7 release theme.](/salesforce-b2c-commerce-cloud-the-22-7-release/social-commerce-salesforce-a88048dff4_hu_2c1544f76f70918a.webp) Forward-looking statements apply! During the [Connections ‘22](/get-connected-at-salesforce-connections-2022/) event, it became apparent a more significant focus has been put on Social Commerce! I already mentioned this in the [22.5 release](/salesforce-b2c-commerce-the-22-5-release/), but a Tiktok and [Snapchat](https://forbusiness.snapchat.com/) integration is happening now. To access these BETA features, contact your CSM (Customer Success Manager)! ## Development ### Rhino Engine Whenever an update happens to the Rhino Engine, many developers (including me) have a smirk. It means we get to use more modern JavaScript in the back-end! Some of the highlights: - [Shorthand property names](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer) - New JavaScript primitive type [`bigint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt), replaces `dw.util.BigInteger` - [Template literal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals?retiredLocale=nl) support - [`Object.values`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values) / [`Object.entries`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries) / … For a complete list, you can have a look at [the documentation](https://documentation.b2c.commercecloud.salesforce.com/DOC3/index.jsp?topic=%2Fcom.demandware.dochelp%2Fcontent%2Fb2c_commerce%2Ftopics%2Fsite_development%2Fb2c_compatibility_mode_considerations.html). If we look at this list, it is also clear this is an update to the 1.7.14 version of the engine. To get a complete list of what is possible, you can look at the [support list on the official website](https://mozilla.github.io/rhino/compat/engines.html). ### API Encryption Parameter Has Been Changed Some significant encryption changes have been made to the [Order.getOrderExportXML](https://documentation.b2c.commercecloud.salesforce.com/DOC3/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_order_Order.html#dw_order_Order_getOrderExportXML_DetailAnchor) API, mainly around the encryption of payment instrument data. A complete list of changes is available [in the order export encryption update notes](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_OCAPI_order_export_mc.htm&type=5). ## PWA Kit v2.0.0 A big release a lot of people have been waiting for. Focussing mainly on developer experience, this is an important release to set a solid base to support development for the future to come. - 🥳 TypeScript support. The build tools now support TypeScript by default—without having to update the configuration files for Babel or Webpack. - 🧰 An updated development server that supports hot reloading on the server-side and makes it possible to support hot reloading on the client-side in a future release. - 🤓 An all-new command-line tool called pwa-kit-dev that bundles our recommended development tools like Webpack, Babel, and Jest to support zero-config project templates. - 🖌️ Experimental support for non-React apps for those users interested in using Managed Runtime to host other Express-based apps (not just the Retail React App). For a full changelog, have a look at the [GitHub Repository](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v2.0.0). ## Bugfixes I had a look at the “[Known Issues](https://trailblazer.salesforce.com/issues_index?page=2&tag=Commerce+Cloud+Platform),” but I could not find any new “resolved” items for this 22.7 release. ## Updated Cartridges & Tools A new section to this monthly blogpost that I found could be handy for some people. The cartridges that have received updates in the past 30 days! Not all of them will be listed here, and I will mainly focus on [Salesforce and Community cartridges](/community-repositories/). ### [b2c-tools (v0.7.1)](https://github.com/SalesforceCommerceCloud/b2c-tools/releases/tag/v0.7.1) > b2c-tools is a CLI tool and library for data migrations, import/export, scripting and other tasks with SFCC B2C instances. It is intended to be complimentary to other tools such as sfcc-ci for development and CI/CD scenarios. What’s new: - temporary workaround for origin shielding on development (use `--hack-origin-shielding-workaround` hidden option). A cleaner solution to come later - typo “no serve or clientID found” by [@jlbruno](https://github.com/jlbruno) in [#42](https://github.com/SalesforceCommerceCloud/b2c-tools/pull/42) ### [plugin\_einstein\_api (v0.0.4)](https://github.com/SalesforceCommerceCloud/plugin_einstein_api/releases/tag/0.0.4) > Einstein API is the API-led interface from Salesforce B2C Commerce Einstein, and can be leverage to include Einstein product recommendations in places that are not displayed through a content slot on the storefront, or even outside of the storefront. What’s new: - Bugfix/cart productlineitems by [@adrien-monte](https://github.com/adrien-monte) in [#8](https://github.com/SalesforceCommerceCloud/plugin_einstein_api/pull/8) ### [social\_channel\_integrations (**New**)](https://github.com/SalesforceCommerceCloud/social_channel_integrations) > This repository contains Social Channel integrations with B2C Commerce. (Cartridge for Tiktok) An interesting new cartridge which you can track to see how Social selling will be implemented on Salesforce B2C Commerce Cloud. ### [plugin\_commercepayments (v4.2.0)](https://github.com/SalesforceCommerceCloud/plugin_commercepayments/releases/tag/v4.2.0) > This is the repository for the plugin\_commercepayments plugin. This plugin enhances the app\_ storefront\_base cartridge by providing payment functionality via Stripe. What’s new: - Add missing key and value, reorder entries - Bug: Fix not to show tax in order total summary on checkout and cart pages. - Bug: Fix email confirmation not translated for order placed with PM involving redirect - Change to use new saved payment - Add EPS payment method - Add keys for eps and ideal banks and update logic to use keys ### [resource-manager (v1.1.0)](https://github.com/SalesforceCommerceCloud/resource-manager/releases/tag/v.1.1.0) > This cartridge contains a Business Manager module that allows editing and publishing of resource bundles. What’s new: - This release introduces some new ES6 language elements and requires Compatibility Mode 21.1 or higher - New ‘global search’ feature allows searching for keys across bundles. - UI updates and fixes for the new Lightning Business Manager layout. - Bundle last updated date now shown correctly. - Bundle JSON keys get sorted alphabetically on save. --- ## Preparing for the B2C Commerce Developer Certification Canonical URL: https://rhino-inquisitor.com/preparing-for-the-b2c-commerce-developer-certification/ Markdown URL: https://rhino-inquisitor.com/preparing-for-the-b2c-commerce-developer-certification/index.md Content type: article Published: 2022-06-06T11:45:43Z Updated: 2022-11-19T10:18:39Z Summary: Prepare for the B2C Commerce Developer Certification with a practical starting point, study focus areas, and next steps. Categories: Certification Tags: sfcc, technical, trailhead ## Key Takeaways - Breaks down the B2C Commerce Developer certification into its main knowledge domains and study priorities - Links each exam area to concrete Trailhead, partner learning, webinar, and documentation resources - Sets realistic expectations about preparation depth, business manager knowledge, and what failure should mean for further study So, you decided to become a Certified B2C Commerce Developer. That is great! Getting certified is a great way to confirm the knowledge you have gained from projects or training is sufficient and up to par with the “Salesforce Standards.” But there is no harm in preparing specifically for the exam, is there? Let’s go over the [exam guide](https://trailhead.salesforce.com/help?article=Salesforce-Certified-B2C-Commerce-Developer-Exam-Guide) and point you towards the content you might want to review to improve your chances of passing the first try! ## B2C Commerce Setup (11%) The Official List - Given a sandbox environment, configure an IDE to use WebDAV to deploy cartridges to the correct version directories. - Given a sandbox instance and data import files, import files using the Business Manager Import/Export modules. - Given the code for a storefront site, add the correct sequence of cartridge names to the provided cartridge path. - Given a sandbox environment, use the Business Manager to add a new site to the instance, configuring the default currency and taxation type according to business requirements. - Given a recently created B2C site, assign the storefront data configurations according to business requirements. Setting up your environment to be ready to get started should come as no surprise with any project. Within this topic, you will be getting questions about getting your sandbox up and running, uploading code to it, and setting up your site to get cracking! It also includes some topics around configuring a site, so this topic intertwines with the next one. Everything around configuration I will add to that one! So, where can we find some review materials? Here is a list that will get you started! - [Trailhead: On-Demand Sandboxes](https://trailhead.salesforce.com/en/content/learn/modules/b2c-on-demand-sandbox) - [Trailhead: Salesforce B2C Commerce for Developers](https://trailhead.salesforce.com/content/learn/modules/cc-digital-for-developers?trailmix_creator_id=strailhead&trailmix_slug=commerced-cloud-gen-900-introduction-to-commerce-cloud-businessd) - [Trailhead: Tools & Resources for Salesforce B2C Commerce Developers](https://trailhead.salesforce.com/en/content/learn/modules/b2c-developer-resources-and-tools?trail_id=develop-for-commerce-cloud) - [PLC: B2C Commerce - Environment Setup](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=FklpqP6ZE9XyqMwxcTkRbihhza0lQDMyLN2XmF2ERAOsUpjOHxOut0xqG%2FqC0ksp) - [Webinar: Storefront Reference Architecture (SFRA) overview](https://salesforce.vidyard.com/watch/rgvLUk97rk1Kg58nYVcuy9?) ## Work With a B2C Site (12%) The Official List - Given a Business Manager task, work with the product data model to manage products and product search model, their categorization, and associated inventory and pricebooks. - Given a configuration for tasks, such as payment and shipping information, use Business Manager to complete storefront orders. - Given a configuration task, use Business Manager to work with Content Assets, Page Designer, Content Slots, and Content Folders. Why is this one in the second position? Good question; it is my opinion you need to understand the features that come out of the box. Knowing what built-in features exist is essential for answering the questions on the exam correctly (built-in always wins within certification exams) and for yourself and your implementations. There is no point in re-inventing the wheel, right? I’m going to put this site separately since it covers so many topics, and I have already mentioned this one in [a previous blog post](/getting-to-know-sfra-as-a-developer/): - [https://b2c.learncommercecloud.com/](https://b2c.learncommercecloud.com/) This site is your one-stop shop for a quick overview of all content available on getting to know Salesforce B2C Commerce Cloud. But, what else is available? - [Trailhead: Sell Everywhere with Commerce Cloud](https://trailhead.salesforce.com/en/content/learn/trails/cc-overview) - [Trailhead: Administer a Salesforce B2C Commerce Site](https://trailhead.salesforce.com/en/content/learn/trails/administer-b2c-commerce) - [Trailhead: Maxime Rebibo’s Trailmix](https://trailhead.salesforce.com/users/maxime-rebibo-sfcc/trailmixes/preparing-salesforce-b-2-c-commerce-developer-certification) - [Live SFRA Demo Site](https://production-sitegenesis-dw.demandware.net/s/RefArch/home?lang=en_US) - [B2C Commerce Videos (Infocenter)](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/video_content/b2c_videos.html) - [Salesforce Events](https://cs.salesforce.com/events?filter=true&product=b2c-commerce) - [Webinar: Getting Started with Page Designer](https://salesforce.vidyard.com/watch/C239ou4WP2nSagkxoA4D4m?) - [Customer Service Center](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/customer_service_center/b2c_customer_service_center.html) ## Data Management Using Business Manager Usage (24%) The Official List - Given a business requirement, modify site search preferences and settings to enable searching for a specified term or product attribute. - Given a business requirement, create and configure a new search refinement and sorting definition that can be used on the storefront. - Given a debugging requirement or code, configure the logging categories and access the logs in Business Manager. - Given business requirements, extend the storefront to expose a new attribute on an existing system object type. - Given a business need to store custom data, determine if a custom object is needed and create and configure as required. - Given a problem or performance issue and data, use relevant tools to inspect code performance and determine and implement solutions (cache configuration, profilers, etc) to resolve this issue. - Given a specification and a sandbox instance, configure OCAPI permissions for Data and Shop APIs. - Given a service configuration, recognize how they are applicable to the development process. Let us move on to the third section, focusing on configuration and the business manager. Prepare to get quite a few questions about the business manager, even though this is a “developer” certification. As I mentioned in the previous part, knowing what is out-of-the-box in a platform is as important (or even more critical) as writing good custom code. You will notice that the main focus of this section is actually on logging, debugging, and performance. Let’s make a list of available content! - [Search (Preferences, Settings, …)](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/search_and_navigation/b2c_search_overview.html) - [Log Files](https://documentation.b2c.commercecloud.salesforce.com/DOC1/index.jsp?topic=%2Fcom.demandware.dochelp%2Fcontent%2Fb2c_commerce%2Ftopics%2Fsite_development%2Fb2c_log_files_overview.html) - [Extending System Objects (Attribute Manager)](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OrderManagement/Administration/AdminAttributeManager.html) - [Managing Custom Objects](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/custom_objects/b2c_custom_objects.html) - [Site Performance (General)](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_performance/b2c_site_performance.html) - [Pipeline Profiler](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/LegacyDevDoc/AnalyzePerformancePipelineProfiler.html) - [Code Profiler](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_performance/b2c_using_code_profiler.html) - [Technical Dashboard (Reports & Dashboards)](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/analytics/b2c_technical_dashboard.html) - [Troubleshooting Performance Issues](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/admin/b2c_troubleshooting_platform_performance.html) - [Static and Page Cache](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/site_development/b2c_caching_content.html) - [Cache Information Tool](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/storefront_toolkit/b2c_using_the_cache_information_tool.html) - [Custom Caches](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/caches/b2c_custom_caches.html) - [OCAPI Settings](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/OCAPISettings.html) - [OCAPI & Web Service Framework](https://share.vidyard.com/watch/JUR9eco8noLmS11dQA1CKt?) - [Standard Job Steps](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/jobstepapi/html/api/jobStepList.html) ## Application Development (53%) The Official List - Given a development task, code ISML templates that use functionality such as: local include, remote include, components, and other ISML tags. - Use debugging best practices and techniques to troubleshoot scripts and controllers and verify outcomes. - Given a requirement, create and extend the functionality of a JavaScript controller that leverages models, decorators, factories, or helpers following API best practices and renders a template or returns a JSON response. - Given a business requirement and design for a new marketing page, develop page types and components to allow a marketer to build a page with the Page Designer tool. - Given a requirement to accept, validate, and persist information from a storefront customer, modify the appearance of a form, add validation and CSRF protection, and use bindings to process fields. - Given localization requirements, implement and enhance templates, form definitions, static files, properties files, and persistent object attributes to ensure that pages are displayed in the expected language. - Given a logging task and existing configuration, write code that logs non-sensitive data to custom log files with different log levels. - Integrate, deploy, and use a service instance based on a given requirement. - Given a use case, extend functionality or capture an event using hook extension points. - Given code that violates documented best practices, identify the issues and modify the code to conform with best practices including performance and scalability. - Given a business requirement, use OCAPI Shop and Data APIs to enable interoperability with an external system. - Given a business requirement to perform a scheduled task, develop jobs and code job scripts. Phew! Finally, some development in this Certificate Exam! Since it is for developers, more than 50% of your score depends on your development skills. But knowing how to write custom code will not be enough to pass this exam! So be sure to focus well on the above sections. - [PLC: B2C Commerce: Cartridges](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=lajSZ4fiG8B8B%2FjkSWQoNzhOxv1weswjGAii%2BP8tV7bNN0Lf2rWHAnzVzlZhKmhn) - [PLC: B2C Commerce: SFRA Controllers](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=EPljQI7EK5feAWFzr9U3y%2FJZmNvdo4kpInCltbsawSLko6FCdVff2iHe1TG6geU2) - [PLC: B2C Commerce: SFRA Models](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=qbfeTrQ8RIQLOy5N0xpxovLrJSI33WqnaV0JgW%2Fjac7CH38VqLsUnZfcAFyJfhjx) - [PLC: B2C Commerce: ISML Usage in SFRA](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=bDrCI7DOnzZCp00UyqSo2zq7PM1TENdE9fT7ruwjvMrX52IbFXLEkeKhQgHPNA65) - [PLC: B2C Commerce: Client-Side JavaScript in SFRA](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=Mwg71bDyRwrq99B0N8d6VUpqsNQGccwYBV24BZjAqWRAvo8dLfdGSG%2Bg90Uxd39b) - [PLC: B2C Commerce: Forms](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=DgFShni2w8Buh7MkbcCdotA52mik2liPsbFDeMsAz1T7ZKxPx5s2uuA%2FmTQ1X0c2) - [PLC: B2C Commerce: Transactions and SFRA Middleware Events](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=IH7XdPjsKPn6e6%2BQln8tGoE4EL0aB8iuWZykif0p%2FLg9qkzA3PR6XcZcbImHFCH%2B) - [PLC: B2C Commerce: Job Framework](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=2wfoRalvi7mbngGhngsjVwURQ3FCluVKiuJTkHKSf%2FvbrnJWO3UwZukggQ3i2oCC) - [PLC: B2C Commerce: Salesforce Commerce API](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=Apc5I7Qk7MryruJytFcxjomroADeukWJnCkZ2stSh0mxFjevE7qqX3BUWwRHRD2o) - [Webinar: SFRA - Architecture Deep Dive](https://salesforce.vidyard.com/watch/fVzzSXddHXwvcCfeRVvcoX) - [Webinar: Cartridges & Controllers](https://share.vidyard.com/watch/ASVVEWfhkJ2uPDeoxbosL3?) - [Webinar: Models, ISML, and Client-Side Javascript](https://share.vidyard.com/watch/zwNXrskJgzysXJZo7CNaC5?) - [Webinar: Forms, Transactions, and Middleware Events](https://share.vidyard.com/watch/XdAJam3xCAMQ7UYrAVxSwW) - [Webinar: Page Designer and Job Framework](https://share.vidyard.com/watch/j29VTc9BbqpyH7kkrubW2k?) - [Webinar: Developer Academy](https://salesforce.vidyard.com/watch/G1wTJXz7DESCFXoiGcBvv4) - [Test: Knowledge Check (Unknown who made this)](https://docs.google.com/forms/d/e/1FAIpQLScl1iakgeaRCP9KfO0iNFpQ0Y12DfZJqiHW16O49N9rA03bXw/viewform) ## What if I fail the exam Failing a certification exam is not the end of the world! Let’s make it clear. You can do successful implementations within Salesforce B2C Commerce Cloud but still fail this certification. You might not have touched all of the different areas of Salesforce B2C Commerce Cloud and SFRA within that project. Be sure to remember the questions you had trouble with; those are “gaps” in your knowledge that you want to fill. Go back and revise those topics, do some experiments on a Sandbox and get back on that horse! ## What if self-study isn’t my thing Not to worry, there are instructor-led courses available at [Trailhead Academy](https://trailheadacademy.salesforce.com/)! - [B2C Commerce Developer with SFRA ( CCD102 )](https://trailheadacademy.salesforce.com/classes/ccd102-b2c-commerce-developer-with-sfra) - [Manage and Merchandise a B2C Commerce Cloud Store ( CCM101 )](https://trailheadacademy.salesforce.com/classes/ccm101-manage-and-merchandise-a-b2c-commerce-cloud-store---extended) ## I’m not a partner. Can I access PLC Unfortunately, the PLC (Partner Learning Camp) is only available to registered partners of Salesforce. It is a platform to empower partners to learn Salesforce products and make sure they succeed with their customer implementations. ## Can I wing it Of course! This certificate should be a cinch if you have been doing Salesforce B2C Commerce Cloud (and SFRA) development for multiple years/projects. Bit of warning, this is only true if you also did configuration work in the Business Manager (Set up the search, categories management, Jobs, OCAPI, and so forth) After 2-3 projects (2 years), I did the certificate myself without much preparation and passed on the first try. I even had the handicap that it was still a SiteGenesis exam, and I only had experience with SFRA. Just don’t assume that it is going to be easy! This is a certification exam, not a Trailhead module. --- ## Get connected at Salesforce Connections 2022 Canonical URL: https://rhino-inquisitor.com/get-connected-at-salesforce-connections-2022/ Markdown URL: https://rhino-inquisitor.com/get-connected-at-salesforce-connections-2022/index.md Content type: article Published: 2022-05-30T12:21:30Z Updated: 2022-07-23T21:49:51Z Summary: Preview Salesforce Connections 2022 with a commerce-focused view of the event, key themes, and what attendees should watch for. Categories: Community Tags: ohana, sfcc, trailhead ## Key Takeaways - Previews Connections 2022 through a commerce-focused agenda and networking lens - Highlights key sessions on headless, multi-cloud, social commerce, and unified commerce - Emphasizes that the event is as much about meeting people as attending sessions It seems like only yesterday that [TrailblazerDX](/trailblazerdx-2022-for-b2c-commerce/) happened, and here we are again. But this time in Chicago! Unlike TrailblazerDX, Connections is focused on creating connections between customers, partners, and Salesforce. Although you will still find some developer-centered presentations, they will be far less common. The goal is to get inspired by commerce leaders and Trailblazers in Commerce to help brands grow! What does it have in store for Salesforce B2C Commerce Cloud? Let’s have a look! ## Get Connected It wouldn’t be a Salesforce event if you don’t meet up with other people you have been “slacking” with for the past years. **And it is called Connections for a reason!** There is already a channel on the Salesforce B2C Commerce Cloud Unofficial Slack to connect! [Join the SFCC Unofficial Slack](https://join.slack.com/t/sfcc-unofficial/shared_invite/zt-18rw25yb4-kfiHdw~TvWldb8o~k8bG_Q) or [open the existing channel](https://sfcc-unofficial.slack.com/archives/CAUTX1V5Z). And I will be there this year! I wasn’t planning on it at first, but I got an offer I could not refuse! I will be taking part in the Main Keynote of the event. [![Invitation graphic for speaking in the Connections 2022 keynote.](/get-connected-at-salesforce-connections-2022/offer-8124183637_hu_e634d7afcc236492.webp)](offer-8124183637.jpg) ## Can’t attend The keynotes can be viewed through [Salesforce+](https://www.salesforce.com/connections/register/) for free! ## Building your agenda Connections 2022 is no small event, and there are many sessions to choose from! The venue itself is also huge, and I can promise that you will easily get distracted 😀. And there is nothing wrong with that; you need to find **your way** in this event and do what you want to do to get the most out of it! Below I have created my “potential” agenda of the event, but I already know some of these will be missed or swapped out. You will bump into people and lose track of time, but there is no need to stress about missing a session. As mentioned before, it is called **Connections**! So meet up and have fun! Salesforce provides a handy tool to [build your agenda on the Connections website](https://reg.salesforce.com/flow/plus/cnx22/connections22agendabuilder/page/calendar). ## Wednesday, June 8 ### [Grow Your Business in China with Social Commerce](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1652742108983001EUXx) - [Xintong Zhang](https://www.linkedin.com/in/xintongzhang/) - 09:00 AM - 9:20 AM - 20 minutes > China is the world’s largest online retail market. Learn about China’s unique ecommerce ecosystem and how Salesforce and Alibaba are working together to drive customer success in the region. If you look at the possibilities in the [Session Catalog](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog), Alibaba has a good presence with their offerings for the Chinese market. This provides an excellent opportunity for partners and customers who are expanding their markets now or in the future. ### [Wow Your Customers](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1648704751762001RwxN) - [Lidiane Jones](https://www.linkedin.com/in/lidianejones/) - [Shannon Duffy](https://www.linkedin.com/in/shannonduffy/) - [Jessica Cobarras](https://www.linkedin.com/in/jmaechan/) - [Sarah Franklin](https://www.linkedin.com/in/sarahfranklin/) - [Adam Michaels](https://www.linkedin.com/in/adambmichaels/) - [Thomas Theunen](https://www.linkedin.com/in/thomas-theunen-%E2%98%81%EF%B8%8F-10905680/) - 10:00 AM - 11:00 AM - 60 minutes > To grow relationships and revenue, brands must wow customers with personalized moments that build trust and loyalty. Learn how Trailblazers are doing this with the latest innovations from Salesforce. There are not many reasons to miss the Main Keynote of Connections. And I believe this one will contain a lot of exciting news for the Commerce Cloud Community. As I am part of the speakers (even if it is only for 4 minutes), I urge everyone in the Commerce Cloud community to attend! ### [6 Steps to Headless Commerce Success](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1648704753800001RqJa) - [Karly Cyr](https://www.linkedin.com/in/karly-cyr-a6512a20/) - [James Semple](https://www.linkedin.com/in/james-semple-8884093b/) - [Matt Bradbeer](https://www.linkedin.com/in/mattbradbeer/) - 11:30 AM - 11:50 AM - 20 minutes > Not all headless architectures are created equal. Learn 6 steps every headless implementation should follow to unlock control over the UX layer, operational agility, and improved performance. As Headless and API First development has become a lot more prominent, this is one not to miss. ### [Insights from the 2022 State of Commerce Report](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1648704753897001RxK1) - [Erin Emery](https://www.linkedin.com/in/eemery/) - [Caila Schwartz](https://www.linkedin.com/in/caila-schwartz/) - 12:00 PM - 12:20 PM - 20 minutes > What do 4,000 commerce leaders representing 1 billion shoppers think is next for commerce? Be the first to hear the insights from the 2022 State of Commerce Report in this session. If you get the chance, this session might pique your interest in looking at what the State of Commerce is in 2022. ### [B2C Commerce Data Strategies for Cross Cloud Success](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1649356404772001qF88) - 01:00 PM - 01:40 PM - 40 minutes > Circle of Success: Join this small group discussion on why data strategy is important for cross-cloud success. Explore how to exceed customer expectations and learn cross-cloud best practices. Oh, noes! Decisions! This one clashes with the next one on the list. A discussion about multi-cloud vs. a presentation about Unified Commerce (multi-channel). This will always happen when building a plan; you can’t catch them all! ### [Removing Friction with Unified Commerce](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1648704756584001RESD) - [Jan Beke](https://www.linkedin.com/in/janbeke/) - 01:00 PM - 01:20 PM - 20 minutes > Customers expect consistent brand experiences across all channels. So how can you modernize without adding complexity? Learn how unified commerce helps retailers become faster and more agile. The shopper journey has diversified quite a lot over the past decade. More and more options have become available for shoppers to connect with brands. But how do you unify that experience? In my opinion, a good one to do after lunch! ### [5 Tips to Perfecting the Connected Shopper Experience](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1649097429527001yA9t) - [Derek Lindblom](https://www.linkedin.com/in/derek-lindblom/) - 02:00 PM - 02:20 PM - 20 minutes > Discover how VSP leveraged Commerce Cloud, Marketing Cloud, Order Management, and Service Cloud to provide connected customer journeys for their eyewear brand, Eyeconic. Are you interested in multi-cloud solutions? Want to see what you can do if you combine multiple clouds to create the perfect customer journey/experience? Then this is the session for you! ### [Next-Gen Commerce Cloud: Grow Revenue Your Way](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1648704753999001R2vf) - [Kemberly Gong](https://www.linkedin.com/in/kemberlygong/) - [Luke Ball](https://www.linkedin.com/in/lukeball/) - [Amanda Hatker](https://www.linkedin.com/in/amandahatker/) - [Kelly Thacker](https://www.linkedin.com/in/kellyhautjames/) - 02:30 PM - 03:15 PM - 45 minutes > Join the main event for commerce professionals. Learn how we help commerce leaders grow revenue their way with the latest innovations from Salesforce. This is the Keynote for everything Commerce related, so be there or be square! ### [Dropshipping and You: A Commerce Cloud Success Story](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1649097490947001QxYA) - [Brecht Morrhey](https://www.linkedin.com/in/brecht-morrhey-b88547106/) - [Kevin Box](https://www.linkedin.com/in/kevin-box-b0462612/) - 04:00 PM - 04:20 PM - 20 minutes > Dropshipping offers retailers an opportunity to increase its reach with third-party sellers. Learn how VidaXL achieved success with 15,000+ dropshippers, and to get the most of your implementation. Dropshipping and marketplaces are becoming more prominent within the retail market. Learn how you can use Commerce Cloud to allow others to sell your products on their platform by connecting to B2C Commerce Cloud. One to certainly join! Doing a shameless plug for my colleagues! ### [Innovation in the Partner Ecosystem Beyond the Buy Button](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1648704753602001RD7R) - [Paula Griffin](https://www.linkedin.com/in/paula-griffin/) - [Lindsey Avchen](https://www.linkedin.com/in/lindsey-avchen-mba-3013a559/) - [Brady Marchione](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1648704753602001RD7R) - 04:30 PM - 04:50 PM - 20 minutes > Join us to learn how the Salesforce Fulfillment Network can help you increase profits, optimize delivery, and drive revenue back to your business. I feel like this is the presentation about the [new FedEx partnership](https://newsroom.fedex.com/newsroom/fedex-and-salesforce-partner-to-deliver-fast-and-easy-shipping-end-to-end-e-commerce-and-supply-chain-management/) for delivery, built straight into the platform. So a very interesting one to end the day with. ## Thursday, June 9 On to day two! Even though there is not much room between the sessions to explore, keep in mind that this is just a guideline. Wander! Connect! ### [Developer Not Required: Content w/o Constraint on PWAKit](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1648704756882001RrmT) - [Alison Williams](https://www.linkedin.com/in/alisonlwilliams26/) - 09:00 AM - 09:20 AM - 20 minutes > Want to create engaging campaigns without relying on a developer? We’ll provide a quick overview of SFCC’s new headless solution, PWA Kit, and do a live demo where you choose the content we create. An interesting presentation where Amplience provides all the content through their Headless APIs to the PWA Kit. It is also the only session that explicitly mentions the PWA Kit, which is a bit of a shame. I was hoping to see a lot more about API First and Headless! ### [Top China Ecommerce Trends to Know Now](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1652742370613001EK2j) - [Lauren Hallanan](https://www.linkedin.com/in/lauren-hallanan/) - 09:30 AM - 09:50 AM - 20 minutes > From live streaming and social commerce, to gamified loyalty and immersive retail, join us to discover some of the innovative commerce experiences that have taken off in China. Another session on how to approach the Chinese market! A good opportunity to see how social commerce and streaming are used to approach Chinese shoppers! ### [How Leatherman Powers Retail Growth With Commerce Cloud](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1649097528577001twQa) - [Adam Snyder](https://www.linkedin.com/in/adam-snyder-130b647/) - 10:00 AM - 10:20 AM - 20 minutes > Learn how Trailblazer Leatherman drives faster growth with effective AI-personalization tools, flexible omni-channel and optimized onsite branded experiences, and fine-tuned commerce fundamentals. I love seeing customer cases, especially when they use multiple offerings from Salesforce. It is also apparent that customer journeys are becoming more complex over the years, and hearing about other approaches and experiences will help us grow together. ### [Creating a Seamless and Cohesive Customer 360 Experience](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1648704757194001R2qI) - [Mark Bartlett](https://www.linkedin.com/in/mabartlett/) - [Suzanne Dominick](https://www.linkedin.com/in/suzanne-dominick-2b087b5/) - 10:30 AM - 10:50 AM - 20 minutes > Learn how Salesforce and Fenom Digital helped David Yurman put the customer at the center of their digital transformation with Commerce Cloud, Marketing Cloud, Service Cloud, and Order Management. Another multi-cloud customer case! ### [How to Boost Ecommerce Sales with Commerce for Social](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1651685978751001H1LQ) - [Francesca Liu](https://www.linkedin.com/in/francesca-liu-b5757797) - [Bhagath Ganga](https://www.linkedin.com/in/bhagathganga) - 11:00 AM - 11:20 AM - 20 minutes > Shopping at the edge is expected to grow exponentially over the next five years. Learn how to improve product discoverability and boost sales on today’s leading social channels using Commerce Cloud. The final one in a spree of 20-minute sessions before lunch! And a good one to end with on integrating social channels into the customer journey using Salesforce Commerce Cloud. As social channels are ever-changing, looking at what the next five years will bring is not a bad idea. ### [Get Ready for Holiday 2022](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1651685978751001H1LQ) - [Daniel Shim](https://www.linkedin.com/in/danshim/) - 12:30 PM - 12:50 PM - 20 minutes > Learn from the behaviors of billions of shoppers to inform insights and predictions for holiday 2022 and drive readiness across marketing, commerce, customer service, and the store and associates. If you have been doing Salesforce B2C Commerce Cloud for a while, [holiday readiness](https://help.salesforce.com/s/articleView?id=rn_b2c_21_10_get_holiday_ready_je.htm&type=5&language=en_US) should be a term you have heard before. If not? Then this is the session for you! ### [Explore API-Only (Headless) ISV Solutions for Commerce](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1650253853526001ZAxT) - [Ramasree Pitla](https://www.linkedin.com/in/rpitla/) - 01:00 PM - 01:20 PM - 20 minutes > Explore API-only (headless) ISV opportunities on the Commerce Cloud platform and learn about the existing headless ISV solutions in our marketplace. As mentioned before, Headless has gotten a more prominent part in Commerce Cloud. And it’s share is going to grow in the years to come. But what does that mean for third party integrations? Let’s see if this session answers a few questions! ### [MuleSoft for C360: Connected, Automated Commerce Experiences](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1648704755706001RNnd) - [Desmond Wong](https://www.linkedin.com/in/desmond-wong-81267025/) - [Mishika Narula](https://www.linkedin.com/in/mishikanarula/) - 01:30 PM - 02:10 PM - 40 minutes > MuleSoft and Salesforce built the only unified platform that combines the power of integration, API management, and automation to support retailers’ digital transformation journey. I don’t think it is a big secret that I focus on multi-cloud solutions, and Mulesoft plays a big part in connecting the different products that Salesforce offers! ### [A Conversation with Dwyane Wade](https://reg.salesforce.com/flow/plus/cnx22/connections2022contentcatalog/page/sessioncatalog/session/1648704752066001RcLZ) - Dwyane Wade - [Lori Castillo Martinez](https://www.linkedin.com/in/loricmartinez/) - 03:00 PM - 04:00 PM - 60 minutes > Former pro basketball player Dwyane Wade will receive the first #TeamEarth Impact Award for Equality and discuss his work in inclusive marketing and supporting the LGBTQ+ community. The ending Main Keynote to finish off 2 days of learning and meeting people! ## Party Time ![Connections party announcement featuring OneRepublic.](/get-connected-at-salesforce-connections-2022/cnx-hp-band-one-republic-23e3012477_hu_96e6867c4d8fb5c0.webp) It wouldn’t be a Salesforce event if there weren’t a big party at the end of day one! Connections is no different; a fantastic night of entertainment has been planned out. ~~For now, it is still unknown “who” will be there~~, but at least there is a [Spotify playlist](https://open.spotify.com/playlist/1QBj09JZOgEMAKyKl0e5St?si=VmHxOKldSumehDcPmgDUkQ&nd=1) to get your groove on! It turns out it is OneRepublic! ## OneRepublic ### OneRepublic - Apologize (Official Music Video) Play video ### OneRepublic - Counting Stars (Official Music Video) Play video ### OneRepublic - Good Life (Official Music Video) Play video ### OneRepublic - Love Runs Out (Official Music Video) Play video --- ## Submit multipart/form-data in SFCC Canonical URL: https://rhino-inquisitor.com/submit-multipart-form-data-to-a-third-party-service-in-sfcc/ Markdown URL: https://rhino-inquisitor.com/submit-multipart-form-data-to-a-third-party-service-in-sfcc/index.md Content type: article Published: 2022-05-23T16:17:58Z Updated: 2022-07-23T22:01:29Z Summary: A use case you will not run into often is submitting a file to a third-party service. And it is not easy to find documentation or examples on how to do it. Categories: Technical Tags: sfcc, technical ## Key Takeaways - Provides a practical example of sending multipart form-data from SFCC using the Service Framework and HTTPRequestPart - Explains the required Business Manager service setup and the request-building details for file-based payloads - Acts as a quick implementation guide for the uncommon case where an external service expects multipart uploads A use case you will not run into often is submitting a file to a third-party service. And it is not easy to find documentation or examples on how to do it. For that reason, I decided to write a quick guide on implementing it! It turns out it is not hard to do once you have all the puzzle pieces! But isn’t that the case with many things? ## TLDR; Solution For the people who want a quick solution to their file upload problem without much reading work, here you go! And before you start commenting that I put everything in a controller, it is just an example. Please use helper classes and the works, and don’t put everything in a controller. ```js 'use strict'; var server = require('server'); server.get('SubmitFile', function (req, res, next) { var LocalServiceRegistry = require('dw/svc/LocalServiceRegistry'); var HTTPRequestPart = require('dw/net/HTTPRequestPart'); var File = require('dw/io/File'); var myFormSubmissionService = LocalServiceRegistry.createService("FormService", { createRequest: function(svc, params) { var zipFile = new File(new File(File.TEMP), 'myFile.zip.gz'); return [ new HTTPRequestPart('zipFile', zipFile, 'application/gzip', 'UTF-8'), new HTTPRequestPart('zipFile-two', zipFile, 'application/gzip', 'UTF-8'), ]; }, parseResponse : function(svc, response) { return response; } }); res.print(myFormSubmissionService.call().object.text) next(); }); module.exports = server.exports(); ``` ## Pieces of the puzzle ### Files In this example, we use a file on the Webdav located in the TEMP directory: “/on/demandware.servlet/webdav/Sites/Temp”. There are multiple ways to submit files, like a base64 encoded file string stored in different ways within Salesforce B2C Commerce Cloud. But we will not be covering these alternatives. The example should be enough to get you started. ### LocalServiceRegistry As with any third-party integration, please use the built-in [LocalServiceRegistry](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_svc_LocalServiceRegistry.html). But how do you configure it in the Business Manager? Let’s have a look! [![Third-party form service screen used in the multipart submission example.](/submit-multipart-form-data-to-a-third-party-service-in-sfcc/form-service-1-e901798db6_hu_91567939ce7fc761.webp)](/submit-multipart-form-data-to-a-third-party-service-in-sfcc/form-service-1-e901798db6.png) Select the type “HTTP”; otherwise, the LocalServiceRegistry code might not behave as expected. As for the profile and credentials linked to your service, they will depend on your implementation. ### Building the request ```js var zipFile = new File(new File(File.TEMP), 'myFile.zip.gz'); return [ new HTTPRequestPart('zipFile', zipFile, 'application/gzip', 'UTF-8'), new HTTPRequestPart('zipFile-two', zipFile, 'application/gzip', 'UTF-8'), ]; ``` To build up the multipart request, we need to ensure that we return an Array of [HTTPRequestParts](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_net_HTTPRequestPart.html). We submit the same file twice; they can, of course, be different. In this example, we pass multiple [files](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_io_File.html). But it can also be other types: - [File](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_io_File.html) - [String](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_TopLevel_String.html) - [Bytes](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_util_Bytes.html) ### Encoding ```text new HTTPRequestPart('zipFile', zipFile, 'application/gzip', 'UTF-8'); ``` When working with files, you must [send extra information](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_net_HTTPRequestPart.html#dw_net_HTTPRequestPart_HTTPRequestPart_String_Bytes_String_String_String_DetailAnchor) along the way: - **Content-Type:** The type of file, in this case, a zipped file (application/gzip) - **Encoding:** The type of encoding of the file; if it is incorrect, it will be unreadable at the other end. Or it might open but show unreadable content. - **File Name:** You can also send the file name along if needed. ## The Response ```text res.print(myFormSubmissionService.call().object.text) ``` Nothing special to mention here. You will be able to handle the response like any service call and check whether or not the call was successful. --- ## Salesforce B2C Commerce: The 22.6 Release Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-the-22-6-release/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-the-22-6-release/index.md Content type: article Published: 2022-05-16T13:52:22Z Updated: 2022-07-23T21:54:27Z Summary: Are you interested in what is new in each Salesforce B2C Commerce Cloud release? Then this is the article for you! Let us look at 22.6 Categories: Release Notes, Salesforce Commerce Cloud Tags: sfcc, technical ## Key Takeaways - Highlights the main 22.6 changes around Einstein dashboards, OCAPI access-key management, and Log Center filtering - Explains the smaller but useful Salesforce Payments and Business Manager updates that affect local payment support and operations - Calls out the related PWA Kit release and resolved platform issues that were worth testing in this cycle Again, here we are with the latest [release notes](/category/release-notes/) of Salesforce B2C Commerce Cloud; time flies by fast, doesn’t it? Let us go over the [June 2022 (22.6) release](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_22_6_release.htm&type=5)! ## Einstein Dashboards In this release, Einstein is getting a bit of love with better insights into the performance of your recommenders! ### Drill down to a single recommender [![Einstein dashboard view for drilling into a single recommender.](/salesforce-b2c-commerce-the-22-6-release/22-6-release-einstein-dashboards-722f4cbace_hu_ca077a203170e111.webp)](22-6-release-einstein-dashboards-722f4cbace.png) The new dashboard makes it easier to understand one recommender instead of the whole program. It will now be possible to drill down to a single recommender in the dashboards to see how they perform over a selected period of time. This will give merchants a better understanding of performance trends. These metrics include: - Click-through Rate (CTR) - Add to Cart - Cart Conversion Rate - Attributed Revenue. ### View top purchased and top viewed products [![Einstein dashboard showing product-level recommendation statistics.](/salesforce-b2c-commerce-the-22-6-release/einstein-dashoards-addtocarts-sfcc-9c9a2f3595_hu_1cead7b5f2a760c9.webp)](einstein-dashoards-addtocarts-sfcc-9c9a2f3595.png) Product-level metrics are what make the Einstein dashboard useful to merchandisers. With this addition to these dashboards, you will be able to see more information about the performance of a recommender. Reports now show how specific products perform, by being recommended in a particular recommender. ## PWA Kit v1.5.2 [A minor release](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v1.5.2) has been made for the PWA Kit, containing a few bugfixes: - Fix invalid refresh token by [@kevinxh](https://github.com/kevinxh) in [#527](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/527) - Webpack config: no longer assumes that `config` dir exists by [@vmarta](https://github.com/vmarta) in [#522](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/522) - Fix minor typos in readme and jsdoc by [@alexvuong](https://github.com/alexvuong) in [#531](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/531) ## OCAPI ### Access Key Management [![User Data OCAPI endpoints for access key management.](/salesforce-b2c-commerce-the-22-6-release/access-key-management-ocapi-726096138d_hu_f895737c1dee1b7.webp)](access-key-management-ocapi-726096138d.png) Access key management adds more control around who can call User Data endpoints. New endpoints have been made available to manage access keys from an external application. Although this addition is mainly for in-store agents, according to the documentation, the addition will sound like music to the ears of people in charge of DevOps and CI solutions. To access these APIs, ensure the user has the “[Manage\_Users\_Access\_Key](https://documentation.b2c.commercecloud.salesforce.com/DOC3/topic/com.demandware.dochelp/ReleaseNotes/22_6/OCAPI_acess_keys_data_API_mc.html)” permission. ## Business Manager ### EPS added to Salesforce Payments [![EPS payment method logo for Austrian bank transfers.](/salesforce-b2c-commerce-the-22-6-release/eps-logo-austria-8764a70156_hu_b0196cff6a1f0546.webp)](eps-logo-austria-8764a70156.png) EPS matters because regional payment methods still drive adoption in specific markets. EPS is an Austria-based payment method supported by all Austrian banks. You can add the EPS option to your storefront in Business Manager Payment Settings. ### Avoid Chargebacks with Salesforce Payments Use a site-specific descriptor to help shoppers identify the source of an account charge on their credit card statements to reduce payment disputes and chargeback requests. You set the customer statement descriptor in [Business Manager Payment Settings](https://documentation.b2c.commercecloud.salesforce.com/DOC3/topic/com.demandware.dochelp/content/b2c_commerce/topics/salesforce_payments/b2c_payment_statement_descriptor.html?resultof=%22%64%65%73%63%72%69%70%74%6f%72%22%20). The setting overrides the value specified in your Stripe merchant account. ## Development ### Log Center [![Log Center filter for storefront implementation errors.](/salesforce-b2c-commerce-the-22-6-release/troubleshoot-storefront-errors-logcenter-66dfbbe9b6_hu_2a89fccef4195859.webp)](troubleshoot-storefront-errors-logcenter-66dfbbe9b6.png) The new Log Center filters make storefront implementation failures easier to isolate. Filter and find storefront implementation errors, such as broken includes, significant header errors, and large request errors with a new filter option below the “Service Type.” **How:** To find storefront implementation errors with Log Center, set the Service Type filter to “jwa” (see screenshot above). ### Bugfixes #### Unnecessary Product Update Index Task is performed after the Full Index Rebuild An unnecessary Product Update Index Task was performed after the Full Index Rebuild, which publishes a new index even if 0 documents have changed. This happened only if Incremental Index was enabled, even if NO product change had been performed after the Full Index Rebuild. Now, after a full search index update in done and no documents have changed, the platform is not doing an Incremental Index afterward. #### Rule Based Product Categorization - UI Changes to Include SiteContext when Saving/Fetching Rules When creating/editing a ruleset, a dropdown is now provided (similar to the Locale dropdown). The dropdown will be auto-selected to “default” and include all valid active Sites for that instance. When the merchandiser saves the ruleset, the API to PUT/POST rules will consist of a new field to persist the SiteContext selected. #### Dynamic Categorization - Value selection for String attributes with the “is one of” selector isn’t working - [Issue](https://trailblazer.salesforce.com/issues_view?id=a1p4V0000012YmiQAE&title=dynamic-categorization-value-selection-for-string-attributes-with-the-is-one-of-selector-isn-t-working) > Value selection for String attributes with the “is one of” selector isn’t working. When the “is one of” selector is chosen, the user should be able to select multiple values. For String attributes, this isn’t possible because you only get a normal input field for entering the value, with no possibility of adding various values. Expected Products should be shown in the preview tab based on the categorization rule. Actual Products are not categorized when multiple comma-separated values are used. Although the status has recently changed to “fixed,” no version/release was linked. So it might be in the next or this release. --- ## Salesforce B2C Commerce Cloud Documentation Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-documentation/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-cloud-documentation/index.md Content type: article Published: 2022-05-09T18:58:37Z Updated: 2025-08-06T20:01:22Z Summary: Finding the documentation for a specific topic in Salesforce B2C Commerce Cloud can be a challenge sometimes. These are the options! Categories: Salesforce Commerce Cloud Tags: documentation, sfcc ## Key Takeaways - Maps the post-Infocenter Salesforce B2C Commerce documentation landscape across Help, Developer Center, and GitHub-hosted references - Explains how official docs, Trailhead, Partner Learning Camp, and community channels each serve different technical needs - Acts as a field guide for navigating fragmented SFCC documentation more efficiently Let’s be direct. Navigating the Salesforce B2C Commerce Cloud documentation landscape has become a tactical challenge. For those of us who cut our teeth on platforms like Intershop, the sheer volume of official documentation Salesforce provides initially felt like a godsend. We had a central repository, the Infocenter, and while it had its quirks, it was our north star. That star has gone supernova. In mid-2023, the Infocenter was retired, its contents scattered across a constellation of new sites. This move, while intended to modernise, has left many seasoned developers and architects adrift in a fragmented ecosystem. Finding a simple API method or a configuration guide now often feels like a digital scavenger hunt. This isn’t just an inconvenience; it’s a drag on productivity. This article is not another list of stale links. It is a field manual, a strategic guide crafted for technical professionals in the trenches. Its purpose is to cut through the chaos, provide a precise and current map to the resources that matter, and offer an opinionated take on how to use them effectively. The current state of documentation is a direct reflection of the B2C Commerce platform’s evolution—a pull between its monolithic past and its API-first, composable future. Understanding this strategic context is the key to navigating the resources. This guide will provide that key. ## The Great Documentation Shuffle: Decommissioning the Infocenter The single source of truth, `documentation.b2c.commercecloud.salesforce.com`, is officially a relic. On July 15, 2023, Salesforce retired the B2C Commerce Infocenter, a move that caused considerable friction within the developer community. The content wasn’t deleted, but rather atomised and redistributed across three distinct platforms, each serving a different purpose and audience. The three new homes for B2C Commerce documentation are: 1. **Salesforce Help:** This is the new hub for content aimed at administrators and merchandisers. It covers topics like site administration, merchandising, and using Business Manager tools. It aligns B2C Commerce with the standard support and documentation model used across the broader Salesforce ecosystem. 2. **Commerce Cloud Developer Center:** This is the primary destination for most developer-focused content, especially materials related to modern, headless development. This is where you will find documentation for SCAPI, PWA Kit, and composable storefronts. 3. **Salesforce B2C Developer Documentation Resources:** Hosted on GitHub Pages, this site is a repository for deep technical references. It houses the B2C Commerce Script API documentation (`dw.*` packages), import/export schemas, and legacy developer documents that were preserved in [PDF](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/LegacyDeveloperDocumentation.pdf) format. This migration wasn’t a simple one-to-one mapping. Some outdated documentation, particularly for deprecated features, was archived into a single PDF to preserve the information without cluttering the new platforms. For developers with years of muscle memory tied to the Infocenter’s structure, the following map is an essential tool for reorienting to the new landscape. ### The Infocenter Relocation Map | Old Infocenter Section | Audience | New Location & Direct Link | | --- | --- | --- | | B2C Commerce Release Notes | Administrator & Developer | [https://help.salesforce.com/s/articleView?id=sf.b2c\_rn\_release\_notes.htm&type=5](https://help.salesforce.com/s/articleView?id=sf.b2c_rn_release_notes.htm&type=5) | | Developing Your Site | Developer | [https://developer.salesforce.com/docs/commerce/b2c-commerce/overview](https://developer.salesforce.com/docs/commerce/b2c-commerce/overview) | | Open Commerce API (OCAPI) | Developer | [https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/api-doc.html](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/api-doc.html) | | B2C Commerce API (Script API) | Developer | [https://salesforcecommercecloud.github.io/b2c-dev-doc/](https://salesforcecommercecloud.github.io/b2c-dev-doc/) | | Merchandising Your Site | Administrator & Merchandiser | [https://help.salesforce.com/s/articleView?id=cc.b2c\_merchandising.htm&type=5](https://help.salesforce.com/s/articleView?id=cc.b2c_merchandising.htm&type=5) | | Administering Your Organization | Administrator & Merchandiser | [https://help.salesforce.com/s/articleView?id=cc.b2c\_administering.htm&type=5](https://help.salesforce.com/s/articleView?id=cc.b2c_administering.htm&type=5) | | B2C Commerce Security Guide | Administrator & Developer | [https://help.salesforce.com/s/articleView?id=sf.b2c\_security\_guide.htm&type=5](https://help.salesforce.com/s/articleView?id=sf.b2c_security_guide.htm&type=5) | | Legacy Developer Documentation | Developer | [https://salesforcecommercecloud.github.io/b2c-dev-doc/](https://salesforcecommercecloud.github.io/b2c-dev-doc/) | ## In the Trenches: The Unofficial SFCC Community (CommerceCrew) Official documentation can tell you how a feature is _supposed_ to work. The community tells you how it _actually_ works in the wild. In a complex and rapidly evolving ecosystem like B2C Commerce, active participation in community channels is no longer a “nice to have”—it is a required competency for any top-tier professional. For real-time problem-solving, debugging complex issues, and getting feedback on architectural patterns, the **Unofficial SFCC Slack community (CommerceCrew)** is an indispensable, primary resource. It is often faster and more practical than logging an official support ticket. - **How to Join:** The correct and direct way to join is via the community’s official website: [https://unofficialsfcc.com/](https://unofficialsfcc.com/). - **What’s Inside:** This hub provides access to several key resources : - The **Slack workspace**, with over 12,000 members, includes developers, architects, and even Salesforce employees who actively help answer questions. - **Open Source Projects** on GitHub, offering shared tools and resources. - The **Podcasts** provide news and deep dives into relevant topics. The existence and vibrancy of communities like CommerceCrew and the official Trailblazer Community Groups underscore a critical shift in professional practice. The platform’s complexity and the pace of change mean that relying solely on static documentation is an inefficient strategy. The modern SFCC expert’s toolkit includes not only their code and official docs but also their network and their active engagement with peers. This collaborative ecosystem is where the toughest problems are solved and where true mastery is forged. ## Your Trailhead Compass: Strategic Learning for Technical Experts ![Astro cheering](/salesforce-b2c-commerce-cloud-documentation/trailhead-commerce-29dc66c342_hu_9d9029297856cda3.webp) - [https://trailhead.salesforce.com/](https://trailhead.salesforce.com/trails?products=commercecloud&sort=NEWEST) Trailhead is Salesforce’s free, online learning platform, and it’s an ocean of content. For an experienced developer or architect, the challenge isn’t a lack of information, but finding the advanced, relevant modules without wading through introductory material. This curated compass points directly to the trails and modules that provide the most value for technical experts. ### Your Trailhead Compass: Essential Learning Paths | Learning Goal | Recommended Trail/Module | | --- | --- | | **Mastering the Dev Environment** | [https://trailhead.salesforce.com/content/learn/modules/cc-digital-for-developers](https://trailhead.salesforce.com/content/learn/modules/cc-digital-for-developers) | | **Architectural Foundation** | [https://trailhead.salesforce.com/en/content/learn/trails/build-your-career-as-a-salesforce-b2c-commerce-technical-architect](https://trailhead.salesforce.com/content/learn/modules/architecture-of-sf-b2c-commerce) | | **Headless Development** | [https://trailhead.salesforce.com/en/content/learn/modules/b2c-headless-commerce-basics](https://trailhead.salesforce.com/content/learn/modules/headless-commerce-basics) | | **On-Demand Sandboxes** | [https://trailhead.salesforce.com/content/learn/modules/b2c-on-demand-sandbox](https://trailhead.salesforce.com/content/learn/modules/b2c-on-demand-sandbox) | | **Functional Implementation** | [https://trailhead.salesforce.com/content/learn/modules/b2c-implement-functional-solution](https://trailhead.salesforce.com/content/learn/modules/b2c-implement-functional-solution) | ## Partner Learning Camp: The Insider’s Track ![Partner Learning Camp dashboard used to introduce the partner-only training track.](/salesforce-b2c-commerce-cloud-documentation/5b7a39ea-b9bc-486b-9ca3-c77ab5a306b1-e1653998526739-e73418c862_hu_965448b6533bdda7.webp) - [https://partnerlearningcamp.salesforce.com/s/learner-dashboard](https://partnerlearningcamp.salesforce.com/s/learner-dashboard) While Trailhead is the public square for Salesforce knowledge, the Partner Learning Camp (PLC) is the exclusive, members-only club for Salesforce partners and employees. This is not just a rebranded Trailhead; it is a distinct learning destination designed to give partners the specialised knowledge needed to meet complex customer demands. The PLC offers curricula on topics like SFRA, Headless development, PWA Kit, and Architect Success, along with formal accreditations that go beyond standard Trailhead badges. Access is gated through the Salesforce Partner Community, ensuring the content, some of which was previously available only to internal Salesforce employees, remains a strategic asset for the partner ecosystem. For any partner organisation, engaging with the PLC is a critical step in levelling up their team’s capabilities. ## Salesforce Architects: The Multi-Cloud Command Center ![The Solution Architect certification diagram.](/salesforce-b2c-commerce-cloud-documentation/solution-architect-33ece62704_hu_df3a0db73effd077.webp) - [https://architect.salesforce.com/](https://architect.salesforce.com/) While the Developer Centre is for hands-on coding, architect.salesforce.com is the strategic command centre for those designing the blueprints. This is the home base for Salesforce Architects but with a critical distinction: its lens is wide, focusing on multi-cloud architecture and the core Salesforce platform, not just B2C Commerce. Here, you’ll find high-level resources essential for system design: architect decision guides, diagram templates, operating models, and even product roadmaps that give a glimpse into the future. While you won’t find a deep dive on a specific `dw.*` package, you will find the patterns and best practices for integrating B2C Commerce into a larger Salesforce ecosystem. For the B2C architect, this site is less about the ‘how’ of a single platform and more about the ‘what’ and ‘why’ of a connected, multi-cloud solution. ## The Map in Your Hands The Salesforce B2C Commerce documentation landscape has undeniably become more complex. The days of a single, centralised Infocenter are over, replaced by a distributed system that mirrors the platform’s own architectural evolution. This fragmentation presents a challenge, but not an insurmountable one. This field manual has provided a clear map to this new territory. It has charted the new locations of critical resources, provided a strategic framework for choosing between OCAPI and SCAPI, and curated the essential toolkits for coding, configuration, and continuous learning. It has been highlighted that the path to expertise now runs not only through official documentation but also through active participation in the vibrant community of professionals who build on this platform every day. The landscape has changed, but the tools to master it are all here. The map is now in your hands. Go build something incredible. --- ## Community Repositories Canonical URL: https://rhino-inquisitor.com/community-repositories/ Markdown URL: https://rhino-inquisitor.com/community-repositories/index.md Content type: page Published: 2022-04-27T06:33:05Z Updated: 2023-02-15T14:08:10Z Summary: Besides the official repositories, many community contributions to Salesforce B2C Commerce Cloud exist! Here is the list! Categories: Community Below you will find a list of many different contributions the [community](/the-state-of-ohana-for-salesforce-commerce-cloud/) has made to Salesforce B2C Commerce Cloud! This extends the platform and increases the developer experience overall! Feel like something is missing? Let me know on [X](https://x.com/theunenth) or the [Unofficial Slack](https://sfcc-unofficial.slack.com)! ## Browser Extensions ### DWithEase The extension is created to ease SFCC developers with their daily tasks by giving them quick access to pages in Business Manager, automatic log-in, tools for enhancing their working experience, and a lot more. **Author:** ForkPoint [Download & Install](https://dwithease.com/) ### Automaton An extension to simplify life by logging into Salesforce Account Manager using 2FA (TOTP only - Generator APP). **Author:** Thomas Theunen [Download & Install](https://chrome.google.com/webstore/detail/automaton-account-manager/clbadmmkinhmiblhkkiiabbbcpljohob) ## IDE Extensions / Plugins ### Cartridge Overrides VS Code Extension to Display SFCC Cartridge Overrides **Author:** Peter Schmalfeldt [Go to repository](https://github.com/redvanworkshop/sfcc-cartridge-overrides-vscode-extension) ### SFCC Docs Browse the SFCC documentation directly from VSCode. **Author:** Mihai Ionut Vilcu [Go to repository](https://github.com/ionutvmi/sfcc-docs-vscode) ### SFCC Jobs Executor Run SFCC jobs from VSCode and view the job logs in the output panel. **Author:** Mihai Ionut Vilcu [Go to repository](https://github.com/ionutvmi/sfcc-jobs-executor) ### Prophet A VS Code extension to work with Demandware/Salesforce Cloud code on Sandbox that support the Script Debugger API (SDAPI) 2.0 **Author:** Anatolii Obitskyi [Go to repository](https://github.com/SqrTT/prophet) ### SFCC Studio Salesforce Commerce Cloud (SFCC) Studio Plugin for Jetbrains IDEs. **Author:** Charlie Choiniere [Go to repository](https://github.com/nek4life/sfcc-studio) ### sfcc-dts High quality Salesforce Commerce Cloud type definitions. A dw-api-types “done right”**Author:** Fabrizio Giustina [Go to repository](https://github.com/openmindlab/sfcc-dts) ## Cartridges ### Apple Web Sign-In This cartridge adds support for Apple Web Sign-In in SFRA. Note: This cartridge includes extra functionality to verify the identity of the user by validating the id\_token received from apple servers. This is implemented to follow apple’s guidelines on security. **Author:** Ranveer Raghuwanshi [Go to repository](https://github.com/ranveer5289/sfcc_apple_web_signin) ### Commerce Cloud Libraries This repository contains libraries converted and tested to work with the latest version of Salesforce Commerce Cloud B2C (Rhino Engine). **Author:** Thomas Theunen [Go to repository](https://github.com/taurgis/salesforce-commerce-cloud-libraries) ### Commerce Storefront POCs This repo is a composable storefront implementation with various proof of concepts baked in. It otherwise closely tracks pwa-kit **Author:** Charles Lavery, Sandra Golden and Johnny Green [Go to repository](https://github.com/SalesforceCommerceCloud/composable-storefront-pocs) ### Catalog Reducer Extension The Catalog Reducer Extension is a Business Manager Extension that was created to provide a simple, easy way to export smaller version of Production catalogs, for use on sandboxes on the Salesforce B2C Commerce Platform. **Author:** Jordane Bachelet [Go to repository](https://github.com/SalesforceCommerceCloud/catalog-reducer-extension) ### Datalayer Concept to add data tracking into SFRA. This plugin provides an implementation blueprint on website data tracking (server side data and client events) and creates a sfra datalayer which could be used when connecting to other tracking providers like GTM and Tealium. **Author:** Andreas Seyfarth [Go to repository](https://github.com/SalesforceCommerceCloud/plugin_datalayer) ### Developers Core A Salesforce Commerce Cloud (Demandware) Cartridge for Developers. **Author:** Peter Schmalfeldt [Go to repository](https://github.com/redvanworkshop/rvw_developers_core) ### Dynamic Caching This plugin adds dynamic page caching based on sales velocity and inventory. **Author:** Thomas Theunen [Go to repository](https://github.com/taurgis/lib_dynamiccaching) ### Einstein API (SCAPI) This is the repository for the plugin\_einstein\_ api plugin. This plugin enhances the app\_storefront\_ base cartridge by adding the Einstein API capabilities. **Author:** Jordane Bachelet [Go to repository](https://github.com/SalesforceCommerceCloud/plugin_einstein_api) ### EU Price Indication This repository provides a set of tools with which merchants may build ecommerce storefront compliant with eu directive 2019/2161 (referred as omnibus directive) **Author:** Holger Nestmann & Daniel Mersiowsky [Go to repository](https://github.com/SalesforceCommerceCloud/eu-price-indication) ### Email Previewer This plugin introduces a new controller that allows you to preview email templates right from your browser. This plugin is natively disabled from the production instance, and is intended to be used on testing instances only (sandboxes / development / staging). **Author:** Jordane Bachelet [Go to repository](https://github.com/jbachelet/plugin_emailpreviewer) ### Filter Navigation his plugin enhances the SFRA by keeping track of search navigation through asynchronous actions, including the following capabilities: Moving back and forth between filter changes and going back to the PLP from a PDP without losing your location **Author:** Thomas Theunen [Go to repository](https://github.com/taurgis/plugin_filternavigation) ### Google Tag Manager An easy to use Google Tag Manager plugin for Salesforce Commerce Cloud, specifically SFRA. This plugin is almost entirely plug and play. **Author:** Red Van Workshop [Go to repository](https://github.com/redvanworkshop/sfcc-plugin-gtm) ### Hooks Collection This repository contains common or complex OCAPI hooks required to run headless projects with commerce cloud b2c. It is meant as guideline and sample code, but not to use as is. **Author:** Holger Nestmann [Go to repository](https://github.com/SalesforceCommerceCloud/sfcc-hooks-collection) ### JWT An implementation of JSON Web Tokens for Salesforce Commerce Cloud SFRA. **Author:** Ranveer Raghuwanshi [Go to repository](https://github.com/ranveer5289/sfcc_jwt) ### Passwordless Login Passwordless login is a way to verify a user’s identity without using a password. It offers protection against the most prevalent cyberattacks, such as phishing and brute-force password cracking. Passwordless login systems use authentication methods that are more secure than regular passwords, including magic links, one-time codes, registered devices or tokens, and biometrics. **Author:** Sandra Golden [Go to repository](https://github.com/SalesforceCommerceCloud/plugin_passwordlesslogin) ### Resource Manager This cartridge contains a Business Manager module that allows editing and publishing of resource bundles. **Author:** Sander Felius [Go to repository](https://github.com/SalesforceCommerceCloud/resource-manager) ### Sentry This is the repository for the link\_sentry plugin. This plugin adds Sentry Monitoring, including Client Side error reporting, Server-Side error reporting and more **Author:** Thomas Theunen [Go to repository](https://github.com/taurgis/link_sentry) ### SEO This is the repository for the plugin\_seo plugin. This plugin enhances the app\_ storefront\_base cartridge by adding more SEO capabilities to the existing SFRA layer. **Author:** Jordane Bachelet [Go to repository](https://github.com/SalesforceCommerceCloud/plugin_seo) ### Turnstile Link cartridge for Cloudflare Turnstile. **Author:** Thomas Theunen [Go to repository](https://github.com/taurgis/link_turnstile) ### Webauthn This cartridge is designed for passwordless authentication with Web Authentication API (WebAuthn). **Author:** Epam [Go to repository](https://github.com/SalesforceCommerceCloud/link_epampasswordlesslogin) ## CLI Tools ### Accessibility Tester A CLI tool that tests client websites for Accessibility Issues and generates reports that can be assigned to Developers. **Author:** Peter Schmalfeldt [Go to repository](https://github.com/redvanworkshop/accessibility-tester) ### b2c-tools b2c-tools is a CLI tool and library for data migrations, import/export, scripting, and other tasks with SFCC B2C instances. It is intended to be complementary to other tools such as sfcc-ci for development and CI/CD scenarios. **Author:** Charles Lavery [Go to repository](https://github.com/SalesforceCommerceCloud/b2c-tools) ### Build Suite Use the Build Suite to automate and customize your build processes. Configure your build and deployment process and hit a single button to package a build, deploy it to your environment, and activate the new code version. **Author:** Salesforce + Community (Too many to mention) [Go to repository](https://github.com/SalesforceCommerceCloud/build-suite) ### Cartridge Diff Command Line Tool for Salesforce Commerce Cloud Cartridge Compare. Working with SFCC Cartridge overrides just got easier: Compare client cartridge against other cartridges, Generate diffs between override files & Filter using local git changes. **Author:** Peter Schmalfeldt [Go to repository](https://github.com/redvanworkshop/sfcc-cartridge-diff) ### Catalog Reducer This node tool allows you to take a large catalog and shrink it to a smaller catalog by using selection criteria. **Author:** Danny Gehl [Go to repository](https://github.com/SalesforceCommerceCloud/catalog-reducer) ### Catalog Reducer for SFCC Usually production catalog is huge and SFCC sandboxes cannot handle a big amount of catalog data without performance degradation. On the other hand, a sandbox is an instance for developing a site and it does not require an entire catalog to be present on it. Will be enough to have few properly configured categories and all types of products. **Author:** Vladyslav Hryhola [Go to repository](https://github.com/acibilous/sfcc-catalog-reducer) ### cctail Remote tail Salesforce Commerce Cloud logs via WebDAV. Allow monitoring more logs at once, merging the content of all the files in a single stream—reports to the console or a FluentD collector. **Author:** Fabrizio Giustina [Go to repository](https://github.com/openmindlab/cctail) ### eCDN Log Transformer Tool for converting Salesforce Commerce Cloud Cloudflare eCDN-WAF log to standard log formats like W3C. **Author:** Ranveer Raghuwanshi [Go to repository](https://github.com/ranveer5289/sfcc_ecdn_logs_transformer) ### Salesforce Commerce Cloud API A CLI tool for making Open Commerce API and Salesforce Commerce API calls. **Author:** wjmelendez [Go to repository](https://github.com/SalesforceCommerceCloud/sfcc-api-cli) ### SFCC Catalog Pricebook Create Salesforce Commerce Cloud Pricebook XML from Catalog XML. **Author:** Red Van Workshop [Go to repository](https://github.com/redvanworkshop/sfcc-catalog-pricebook) ### SFCC-CI The Salesforce Commerce Cloud CLI is a command line interface (CLI) for Salesforce Commerce Cloud. It can be used to facilitate deployment and continuous integration practices using Salesforce B2C Commerce. **Author:** Tobias Lohr [Go to repository](https://github.com/SalesforceCommerceCloud/sfcc-ci) ### SFCC CLI Make developing for Salesforce Commerce Cloud work with any IDE on MacOS, Windows, and Linux. **Author:** Peter Schmalfeldt [Go to repository](https://github.com/redvanworkshop/sfcc-cli) ### SFCC Schemas Salesforce Commerce Cloud import and export schemas validator. **Author:** Fabrizio Giustina [Go to repository](https://github.com/openmindlab/sfcc-schemas) ### SFCCDX Salesforce Commerce Cloud Developer Experience is a command-line interface (CLI) for Salesforce Commerce Cloud. It can be used to quickly move metadata from and to your environment easily. **Author:** Thomas Theunen [Go to repository](https://github.com/taurgis/sfccdx) ### Unused Resource Keys Find unused resource keys in properties files in a Salesforce Commerce Cloud project and get rid of them. **Author:** Noël Ströhmer-Lohfink [Go to repository](https://github.com/Strongground/SFCC_Find-unused-resource-keys) ### WebDAV Bulk Transfer This tool is designed to bulk download and upload files through WebDAV. This tool can also transfer files from a WebDAV server to another (mixing download and upload methods) in one command. By the way, the tool is designed to \*handle files recursively (recursive option) \*upload only files that does not exists on the target server (onlynewfiles option) **Author:** Jordane Bachelet [Go to repository](https://bitbucket.org/jordanebachelet/webdav-bulk-transfer/src/master/) ### XML Split Split a large XML file into smaller chunks based on the given options. **Author:** Jordane Bachelet [Go to repository](https://bitbucket.org/jordanebachelet/xml-split/src/master/) ## CI / CD ### Jenkins Builder Suite: Deploy Deploy your build to a Salesforce Commerce Cloud instance. **Author:** Daniel Anechitoaie [Go to repository](https://github.com/jenkinsci/osf-builder-suite-for-sfcc-deploy-plugin) ### Jenkins Builder Suite: Data Import Import your site data to a Salesforce Commerce Cloud instance. **Author:** Daniel Anechitoaie [Go to repository](https://github.com/jenkinsci/osf-builder-suite-for-sfcc-data-import-plugin) ### Jenkins Builder Suite: Run Job Import your site data to a Salesforce Commerce Cloud instance. **Author:** Daniel Anechitoaie [Go to repository](https://github.com/jenkinsci/osf-builder-suite-for-sfcc-run-job-plugin) ## Other ### Community Docs The purpose of this repository is to store supplemental information for developers in a versioned fashion that encourages collaborative editing and contributions from the SF B2C Commerce developer community. **Author:** Salesforce + Community [Go to repository](https://github.com/SalesforceCommerceCloud/community-docs) ### DW Mock API This is a mock API or an API stub for the Demandware Script API, the main goal is to make unit testing easier so that not every single Class/Object needs to be stubbed out. **Author:** Salesforce + Community [Go to repository](https://github.com/SalesforceCommerceCloud/dw-api-mock) ### Export Page Designer Page A handy tool to extract a single Page Designer page from a library XML file. **Author:** Aleksandr Isaienko [Go to the tool](https://s0t2r.csb.app/) ### Live Catalog Edit Edit SFCC catalog in a Google Sheet and sync easily with any instance. **Author:** ZaUtre [Go to the tool](https://docs.google.com/spreadsheets/d/1MO8eOQXClVpdDeUYWUe8Gvd-E_VCn0llFWqJNNaC_lI/edit?usp=sharing) ### OCAPI Proxy This project will serve as a local NodeJS based Proxy server that will forward requests to an Salesforce Commerce Cloud OCAPI instance. **Author:** John Facey [Go to repository](https://github.com/johnfacey/ocapi-proxy) ### OCAPI Settings With Ease An online project on Heroku to make it a lot easier to set permissions for a specific API Key. **Author:** Jordane Bachelet [Go to the tool](https://ocapi-settings-with-ease.herokuapp.com/) ### One Page Preferences It is used to build a one-page view of all the site preferences within an SFCC instance. **Author:** Ketan Gupta [Go to the tool](https://github.com/ketan9190/sfcc-1page-preferences) ### Splunk Connector This scripted input reads one or more logs from Salesforce Commerce Cloud (SFCC) into Splunk. This script can be configured to pull many different log types from SFCC into other indexes or source types. **Author:** Amir [Go to the tool](https://github.com/Pier1/sfcc-splunk-connector) --- ## Secure Coding in Salesforce B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/secure-coding-in-salesforce-b2c-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/secure-coding-in-salesforce-b2c-commerce-cloud/index.md Content type: article Published: 2022-04-26T12:09:00Z Updated: 2022-07-23T21:36:32Z Summary: Security within Salesforce B2C Commerce might not be a concern because of out-of-the-box features. There are a few things to keep in mind! Categories: Salesforce Commerce Cloud, Technical Tags: security, sfcc, technical ## Key Takeaways - Explains the secure-coding responsibilities that remain even though SFCC provides strong platform-level protections - Covers practical security topics like Account Manager hardening, shared-account risks, secure headers, and npm supply-chain concerns - Points developers toward Salesforce's built-in security guidance and the specific areas that require ongoing discipline Salesforce B2C Commerce Cloud provides many security features out of the box. And because it is a [SaaS](https://en.wikipedia.org/wiki/Software_as_a_service) solution, the security of the servers is handled by the technical teams at Salesforce. That doesn’t mean that you can just lay back and do your thing without worrying about security. So let’s look at what you need to keep in mind when developing for B2C Commerce Cloud. ## Account Manager Security One of the most significant changes in Salesforce B2C Commerce Cloud is removing “local users” from the environments. Access to sandboxes and PIG (Primary Instance Group) instances passes through Account Manager and its security features. This has brought up many discussions about sharing accounts over the past year (more on the core platform than on SFCC). You might think it strange that the first topic is securing your account. But if someone has access, they can upload malicious code or download sensitive data with little effort. ### Single account to rule them all The main advantage (from my perspective) is that you now have one account to log in to many different environments (and across realms). But this comes at a price. If an account becomes compromised, especially Account Managers, someone can get access to many different environments in one swing. 2FA has been made mandatory to mitigate this threat and has been the recommendation for more than a year. ### 2FA (Two-Factor-Authentication) ![Account Manager multi-factor authentication setup screen.](/secure-coding-in-salesforce-b2c-commerce-cloud/mfa-1-6649345f2c_hu_9f6379083507418d.webp) Account Manager MFA setup With Account Manager, it is possible to add 2FA to your account to secure it. Even if someone manages to figure out your account password, they still need to be able to provide the secondary authentication method. For many people having to put [Salesforce Authenticator](https://play.google.com/store/apps/details?id=com.salesforce.authenticator&hl=nl&gl=US) into the log-in procedure was not the best experience (but it has improved a lot in the last months). There are different options possible with Account Manager: - Salesforce Authenticator (Application) - [Security Key](https://www.yubico.com/) (Physical Device) - [TOTP](https://en.wikipedia.org/wiki/Time-based_one-time_password) (Time-based one-time password) application - [Salesforce Identity](https://help.salesforce.com/s/articleView?id=sf.who_is_salesforce_identity_for.htm&type=5) ([Documentation](https://documentation.b2c.commercecloud.salesforce.com/DOC2/topic/com.demandware.dochelp/content/b2c_commerce/topics/account_manager/b2c_account_manager_link_account_to_salesforce_identity_sso.html)) I decided to make it a tad more manageable to log in by creating “[Automaton](https://chrome.google.com/webstore/detail/automaton-account-manager/clbadmmkinhmiblhkkiiabbbcpljohob).” A browser (chromium) plugin that acts as a TOTP mobile application. As a bonus, it also automatically fills in all fields. It is, of course, secured by a “Vault Password,” so not everyone that has access to your laptop can log in. It may seem like an inconvenience that costs you time over the day. But think of what could happen if someone takes over your account and can access all of the Salesforce B2C Commerce Cloud environments linked to your account. ### Shared Accounts Sharing accounts is something that Salesforce does not advise (for a good reason), but there are still use-cases where this necessary evil is needed. Some use-cases where this might be necessary: - An integration user - … no, that is about it for SFCC You do not have to log in to the business manager as an integration user in most cases. But if it happens, usually more than one person needs to be able to do this (leave, sickness, … ) So think of secure ways to share your 2FA (usually TOTP for shared accounts). A good solution I found so far is [1password](https://support.1password.com/one-time-passwords/) which supports TOTP. ## Cloudflare You might think that all of the provided services of Salesforce will keep you safe from bad actors. While it does block a lot of traffic that does not have the best intentions, it can’t stop everything and everyone that means to do harm. You can find more information about what the eCDN (Cloudflare) can do in the [Infocenter](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/admin/b2c_embedded_cdn.html). ## Security Best Practices Lucky for me (and you), Salesforce has already written quite a few guidelines on Security Best Practices for Developers. On the [Salesforce Commerce Cloud Infocenter](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_security_best_practices_for_developers.html), there is a lot of information already documented about different types of attacks and how to mitigate them: - [Encryption and Cryptography](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_encryption_and_cryptography.html) - [Cross-Site Scripting](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_cross_site_scripting.html) - [Declarative Security via HTTP Headers](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_declarative_security_via_http_headers.html) - [Commerce Script Injection](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_commerce_script_injection.html) - [Cross-Site Request Forgery](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_cross_site_request_forgery.html) - [Secret Storage](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_secret_storage.html) - [Using Hooks Securely](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_using_hooks_securely.html) - [Data Validation](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_data_validation.html) - [Open Redirect Attacks](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_open_redirect_attacks.html) - [Authentication and Authorization](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_developer_authentication_and_authorization.html) - [Supply Chain Security](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_supply_chain_security.html) - [Secure Logging](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_secure_logging.html) - [General Secure Coding Practices](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_general_secure_coding_practices.html) - [AppExchange Security Reviews](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/b2c_security_best_practices/b2c_app_exchange_security_reviews.html) Quite the list, isn’t it! Even though Salesforce takes care of quite a few things, you still need to keep yourself in check. Follow the provided guidelines not to compromise the channels you implement on Salesforce B2C Commerce Cloud. ## Security Headers in SFRA To increase the channel’s security, Salesforce allows developers to set specific headers in the responses to tell browsers and applications what is permitted and what is not. A [config file](https://github.com/SalesforceCommerceCloud/storefront-reference-architecture/blob/master/cartridges/app_storefront_base/cartridge/config/httpHeadersConf.json) was introduced into the SFRA to easily set headers for all responses, rather than having to do it for each endpoint separately. ```json [ { "id": "Content-Security-Policy", "value": "frame-ancestors 'self'" }, { "id": "X-Content-Type-Options", "value": "nosniff" } ] ``` The standard file (httpHeadersConf.json) only sets two security headers, but it is possible to develop more. It is important to note that Salesforce limits the headers you can set to [a list of constants in the Response class](https://documentation.b2c.commercecloud.salesforce.com/DOC1/index.jsp?topic=%2Fcom.demandware.dochelp%2FDWAPI%2Fscriptapi%2Fhtml%2Fapi%2Fclass_dw_system_Response.html). I have compiled a list and their descriptions below to make things easier. ### [Access-Control-Allow-Credentials](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials) The Access-Control-Allow-Credentials response header tells browsers whether to expose the response to the frontend JavaScript code when the request’s credentials mode (Request.credentials) is include. When a request’s credentials mode (Request.credentials) is include, browsers will only expose the response to the frontend JavaScript code if the Access-Control-Allow-Credentials value is true. ### [Access-Control-Allow-Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers) The Access-Control-Allow-Headers response header is used in response to a preflight request which includes the Access-Control-Request-Headers to indicate which HTTP headers can be used during the actual request. ### [Access-Control-Allow-Methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers) The Access-Control-Allow-Methods response header specifies one or more methods allowed when accessing a resource in response to a preflight request. ### [Access-Control-Allow-Origin](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers) The Access-Control-Allow-Origin response header indicates whether the response can be shared with requesting code from the given origin. ### [Access-Control-Expose-Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers) The Access-Control-Expose-Headers response header allows a server to indicate which response headers should be made available to scripts running in the browser, in response to a cross-origin request. ### [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers) The HTTP Content-Security-Policy response header allows web site administrators to control resources the user agent is allowed to load for a given page. With a few exceptions, policies mostly involve specifying server origins and script endpoints. This helps guard against cross-site scripting attacks (Cross-site\_scripting). **Note:** The Commerce Cloud platform can override this header for tools like the Storefront Toolkit. ### [Content-Security-Policy-Report-Only](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only) The HTTP Content-Security-Policy-Report-Only response header allows web developers to experiment with policies by monitoring (but not enforcing) their effects. These violation reports consist of JSON documents sent via an HTTP POST request to the specified URI. **Note:** You can set this response header only for storefront requests. Report recipient can’t be a B2C Commerce system. ### [Cross-Origin-Embedder-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy) The HTTP Cross-Origin-Embedder-Policy (COEP) response header prevents a document from loading any cross-origin resources that don’t explicitly grant the document permission (using CORP or CORS). ### [Cross-Origin-Opener-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy) The HTTP Cross-Origin-Opener-Policy (COOP) response header allows you to ensure a top-level document does not share a browsing context group with cross-origin documents. ### [Cross-Origin-Resource-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy) The HTTP Cross-Origin-Resource-Policy response header conveys a desire that the browser blocks no-cors cross-origin/cross-site requests to the given resource. ### Permissions-Policy Permissions Policy Header is an added layer of security that helps to restrict from unauthorized access or usage of browser/client features by web resources. This policy ensures the user privacy by limiting or specifying the features of the browsers can be used by the web resources. ### [Referrer-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) The Referrer-Policy HTTP header controls how much referrer information (sent with the Referer header) should be included with requests. Aside from the HTTP header, you can set this policy in HTML. ### [X-Content-Type-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options) The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised in the Content-Type headers should be followed and not be changed. The header allows you to avoid MIME type sniffing by saying that the MIME types are deliberately configured. ### [X-FRAME-OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a , `<iframe>`, `<embed />` or `<object>`. Sites can use this to avoid click-jacking attacks, by ensuring that their content is not embedded into other sites. **Note:** The Commerce Cloud platform can override this header for tools like the Storefront Toolkit. **Note:** The values of this header are restricted to: “ALLOW-FROM”, “DENY”, “SAMEORIGIN”. ## PWA Kit As the PWA Kit is “relatively” new, there is no real documentation on PWA-specific security best practices. But the amount of information being added to the [Developer Portal](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/skills-for-success.html) is constantly growing. ### Malicious Modules One of the gripes developers have had is that the Rhino Engine does take too kindly to NPM packages. Finding compatible packages is a challenge, and in many cases, they [need to be converted](https://github.com/taurgis/salesforce-commerce-cloud-libraries) to work correctly. With the PWA Kit, all of that changes; you get a lot more freedom with the third-party packages you can install. But with that freedom comes a lot of responsibility. Granted, this is already something you need to keep in mind with SiteGenesis and SFRA, as the storefront JavaScript does not have the Rhino limitations. You have undoubtedly already installed a few packages to expand the capabilities in the storefront. You shouldn’t forget that npm is an open ecosystem where anyone can contribute to a module or repository. And in return, anyone can use a simple command to download that code into their project. But what if the person behind that repository does not have the best intentions? They could put malicious code into it. Or maybe the repository itself does not contain the malicious code; it could be in a dependency that they have on another package! I can go on about this topic, but the following blog post by Liran Tal tells the whole story: [https://lirantal.medium.com/malicious-modules-what-you-need-to-know-when-installing-npm-packages-12b2f56d3685](https://lirantal.medium.com/malicious-modules-what-you-need-to-know-when-installing-npm-packages-12b2f56d3685) ## npm-audit [![npm audit output showing dependency vulnerability results.](/secure-coding-in-salesforce-b2c-commerce-cloud/npm-audit-ab1e401b03_hu_57ffae2242d9fde.webp)](npm-audit-ab1e401b03.png) npm audit vulnerability summary As SFRA and PWA Kit use npm for their third-party libraries, it makes sense to use the out-of-the-box feature of npm to do a security audit of all of your packages. The audit command submits a description of the dependencies configured in your project to your default registry and asks for a report of known vulnerabilities. **Note:** Always test thoroughly after updating your packages (with or without using the npm audit function) to ensure all functionalities work as expected! --- ## TrailblazerDX 2022 for B2C Commerce Canonical URL: https://rhino-inquisitor.com/trailblazerdx-2022-for-b2c-commerce/ Markdown URL: https://rhino-inquisitor.com/trailblazerdx-2022-for-b2c-commerce/index.md Content type: article Published: 2022-04-21T06:49:37Z Updated: 2022-07-23T22:03:54Z Summary: Ready for TrailblazerDX, but not sure what sessions to put on your schedule? Find an overview here of all sessions related to B2C Commerce! Categories: Community Tags: event, ohana, sfcc, trailblazerdx ## Key Takeaways - Curates the B2C Commerce-relevant sessions from the TrailblazerDX 2022 agenda for developers planning their event schedule - Highlights where headless, CI/CD, hooks, and connected-commerce content appears within the broader conference lineup - Encourages community networking by pairing the session guide with Slack-based meetup coordination The pandemic is continuing its rounds worldwide, but luckily things are starting to return to normal. And with things returning to normal, in-person events are also back! First in line is [TrailblazerDX](https://www.salesforce.com/trailblazerdx), a developer-centered event in San Francisco. What does it have in store for the Salesforce B2C Commerce Cloud developers? Let’s have a look! As a side note, there are “holes” in the given schedule below. **So be sure to use [the provided tools](https://reg.salesforce.com/flow/plus/trailblazerdx22/tdx22agendabuilder/page/calendar) to plan your multi-cloud agenda!** ## Get Connected It won’t be a Salesforce event if you don’t meet up with other people you have been “slacking” with for the past years! I have created a channel on the Salesforce B2C Commerce Cloud Unofficial Slack to get connected! [Join the SFCC Unofficial Slack](https://join.slack.com/t/sfcc-unofficial/shared_invite/zt-165gkps41-KZW~gT5xB15REMSOXJ~CRQ) This year I will not be able to attend in person 🙁, but don’t let that stop you from connecting with your fellow B2C Trailblazers! ## Can’t attend The main shows can be viewed through [Salesforce+](https://www.salesforce.com/trailblazerdx/register/) for free! ## (No) Bootcamp It is customary that a “[Bootcamp](https://www.salesforce.com/trailblazerdx/bootcamp)” precedes some events. This is a four days expert-led learning track with two opportunities to get certified (for a price). But unfortunately, there is no track available for anyone wanting to get some Salesforce B2C Commerce Cloud certifications. Looking at the ecosystem’s growth within Salesforce B2C Commerce Cloud, I feel there could be room to add a Bootcamp for Salesforce B2C Commerce Cloud to this list. **Note:** Such a Bootcamp generally costs around $3000. But for a 4-day on-site training and two certification attempts, it is well worth it. ## Wednesday, April 27 ### [TrailblazerDX Keynote: Trailblazers Build the Future, Together](https://reg.salesforce.com/flow/plus/trailblazerdx22/sessioncatalog/page/sessioncatalog/session/1645560544572001nj5g) - [Parker Harris](https://www.linkedin.com/in/parker-harris-451040211/) - Kris Lande - 10:00 AM - 11:00 AM - 60 Minutes Join Parker Harris and guests to learn how Trailblazers can come together to use the latest innovations across the Customer 360 Platform, MuleSoft, Slack, and Tableau to build the future of work. **Note:** This session is not aimed at Salesforce B2C Commerce cloud but is an excellent opportunity to get to know other products in the ecosystem. And it’s the keynote, so be there or be square! ### [Build Fast Shopping Websites for Fun and Profit](https://reg.salesforce.com/flow/plus/trailblazerdx22/sessioncatalog/page/sessioncatalog/session/1644620463459001sLXn) - [John Boxall](https://www.linkedin.com/in/jboxall/) - 12:00 PM - 12:20 PM - 20 Minutes Studies show fast storefronts convert better than slow ones. Headless storefronts pose unique performance challenges. Learn how to make storefronts built with Salesforce B2C Commerce’s PWA Kit fly. ### [Get Started with Integration for New Architects](https://reg.salesforce.com/flow/plus/trailblazerdx22/sessioncatalog/page/sessioncatalog/session/1648498256499001A1ou) - [Amit Malik](https://www.linkedin.com/in/amitmalikus/) - 01:00 PM - 02:00 PM - 60 Minutes We will focus on integration from a beginner’s mind. If you want to learn about integration from the beginning to a point where you start understanding the big picture, this session is for you. **Note:** This session is not aimed at Salesforce B2C Commerce Cloud. ### [Ship a React Storefront on B2C Commerce APIs in 5 Minutes](https://reg.salesforce.com/flow/plus/trailblazerdx22/sessioncatalog/page/sessioncatalog/session/1643413378171001GApD) - [Drew Lau](https://www.linkedin.com/in/drewz/) - 03:00 PM - 03:20 PM - 20 Minutes Developing with B2C Commerce can be a daunting experience for new users. We’ll unveil our new quick-start flow that will make our React-based storefront accessible to any developer within minutes. ### [Ask Me Anything: Continuous Integration](https://reg.salesforce.com/flow/plus/trailblazerdx22/sessioncatalog/page/sessioncatalog/session/1646224425886001VCUN) - [Alba Rivas](https://www.linkedin.com/in/alba-rivas/) - [Christie Fidura](https://www.linkedin.com/in/christiefidura/) - [Shane McLaughlin](https://www.linkedin.com/in/mclaughlinshane/) - [Philippe Ozil](https://www.linkedin.com/in/philippeozil/) - 04:30 PM - 05:10 PM - 40 Minutes Join this Ask Me Anything session to connect with Salesforce developer advocates and engineers and get your questions about continuous integration answered. **Note:** This session is not aimed at Salesforce B2C Commerce Cloud. ## Thursday, April 28 ### [True to the Core](https://reg.salesforce.com/flow/plus/trailblazerdx22/sessioncatalog/page/sessioncatalog/session/1645743781742001tYjh) - [Parker Harris](https://www.linkedin.com/in/parker-harris-451040211/) - Kris Lande - 09:00 AM - 10:00 AM - 60 Minutes Join Parker Harris, the chief product officers from Salesforce, MuleSoft, Slack, and Tableau, and product managers for a one-of-a-kind question-and-answer forum about our product roadmap. Have a question or topic you’d like to see the executives address during True to the Core? Send them [through the Trailblazer Community thread](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000FUYl1SAH). **Note:** This session is not aimed at Salesforce B2C Commerce cloud but is an excellent opportunity to get to know other products in the ecosystem. And it’s the second day keynote, so be there or be square! ### [Apply DevOps Best Practices for B2C Commerce](https://reg.salesforce.com/flow/plus/trailblazerdx22/sessioncatalog/page/sessioncatalog/session/1643929899349001wODh) - [Charles Lavery](https://www.linkedin.com/in/charleslavery/) - 10:30 AM - 10:50 AM - 20 Minutes Unlock agility and efficiency by applying DevOps best practices for B2C commerce. Find out what tools are available to the community and see a walkthrough of a CI/CD pipeline. ### [Customize Commerce APIs with Hooks](https://reg.salesforce.com/flow/plus/trailblazerdx22/sessioncatalog/page/sessioncatalog/session/1644269552284001P3WJ) - [Andrew Lawrence](https://www.linkedin.com/in/andrew9990/) - [Dirk Bergemann](https://www.linkedin.com/in/dirk-bergemann-4430981/) - 12:00 PM - 12:20 PM - 20 Minutes Customization hooks for B2C commerce headless APIs is a new feature this year that gives developers enormous flexibility. Learn new headless use cases and a quick path to getting started. ### [Build Connected Commerce and Marketing with Flexibility and Ease](https://reg.salesforce.com/flow/plus/trailblazerdx22/sessioncatalog/page/sessioncatalog/session/1645744349183001gU27) - [Igor Faletski](https://www.linkedin.com/in/igorfaletski/) - 02:00 PM - 03:00 PM - 60 Minutes Develop connected digital experiences that attract and convert customers – and keep them coming back. Discover new tools purpose-built for developers, designed to make your work fun and easy. ## [Party with Weezer!](https://reg.salesforce.com/flow/plus/trailblazerdx22/sessioncatalog/page/sessioncatalog/session/164980295926300167e9) ![TrailblazerDX party announcement featuring Weezer.](/trailblazerdx-2022-for-b2c-commerce/weezer-66533fada7_hu_d27777d88e7f4d99.webp) It also wouldn’t be a Salesforce event if it didn’t have a celebration at the end of day one! Need a refresher? Here is a playlist! ## Weezer ### Weezer - Say It Ain’t So (Official Video) Play video ### Weezer - Island In The Sun (Spike Jonze Version) Play video ### Weezer - Buddy Holly (Official Music Video) Play video ### Weezer - Beverly Hills Play video ### Weezer - Pork And Beans (Closed Captioned) Play video --- ## Salesforce B2C Commerce: The 22.5 Release Canonical URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-the-22-5-release/ Markdown URL: https://rhino-inquisitor.com/salesforce-b2c-commerce-the-22-5-release/index.md Content type: article Published: 2022-04-18T07:31:52Z Updated: 2022-07-23T21:51:46Z Summary: Review the Salesforce B2C Commerce Cloud 22.5 release notes and the platform updates developers should test or plan for. Categories: Release Notes, Salesforce Commerce Cloud Tags: on demand sandbox, sfcc, technical ## Key Takeaways - Highlights the most relevant 22.5 changes around documentation migration, on-demand sandbox controls, and social-commerce pilots - Explains the new Shopper Context and passwordless SLAS APIs that expand personalization and login options for headless storefronts - Calls out business-manager and payments improvements that matter for category automation and stored-payment experiences A new month, a new release of Salesforce B2C Commerce Cloud. Let us dig a little deeper in the [release notes](https://help.salesforce.com/s/articleView?id=sf.rn_b2c_rn_22_5_release.htm&type=5) to see what is new! Are you interested in last month’s release notes? Read the [22.4 release overview](/b2c-commerce-whats-new-in-22-4/). ## Documentation and community move In May, a significant change is the decommissioning of the [CCDC](https://developer.commercecloud.com/) (Commerce Cloud Developer Center). But do not fear! All documentation has been safely migrated to the primary [Salesforce Developer Center](http://developer.salesforce.com/developer-centers/commerce-cloud)! The communities that were part of the CCDC have also been migrated into the existing [Trailblazer Community](https://trailhead.salesforce.com/trailblazer-community/groups/0F94S000000H1fESAS?tab=discussion&sort=LAST_MODIFIED_DATE_DESC), so all of that information (questions and answers) is not lost! This is, in my opinion, an excellent move to integrate the Commerce Cloud community more into the [Salesforce Ohana](/the-state-of-ohana-for-salesforce-commerce-cloud/). ## Platform ### Encryption at Rest To improve the platform’s security, a new **PILOT** program was started. This program aims to encrypt all customer data on the Salesforce B2C Commerce platform stored on the POD (servers). This is achieved using Host Disk Encryption offered by the OS and [Volume Encryption](https://docs.netapp.com/us-en/ontap/encryption-at-rest/configure-netapp-volume-encryption-concept.html) provided by NetApp. Another great move to ensure all sensitive data stored on Salesforce servers are protected from “prying eyes.” 2022 is undoubtedly a year with a significant focus on improving the platform’s (already solid) base. **Note:** Salesforce is actively looking for customers in the AMER region who deal with highly sensitive data (health information). If you are already an active customer, a realm move will be required. ### Control Center [![Control Center scheduler for planning on-demand sandbox uptime.](/salesforce-b2c-commerce-the-22-5-release/control-center-ods-scheduler-6e883d6157_hu_b935fbef50d91870.webp)](control-center-ods-scheduler-6e883d6157.png) The new Control Center UI replaces the REST-API-only scheduler, making it straightforward to plan on-demand sandbox uptime windows without custom scripting. As On-Demand Sandboxes have become the new standard for Salesforce B2C Commerce, the UI of the [Control Center](https://controlcenter.commercecloud.salesforce.com/index.html) is being revamped as well. We already had [the option to schedule our Sandboxes uptime through a REST API](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/sandboxes/b2c_sandbox_operation_scheduler.html), but a UI is now available to make life a little easier. ### Tiktok Integration [![TikTok for Business branding used for the beta integration announcement.](/salesforce-b2c-commerce-the-22-5-release/tiktok-for-business-e34f4d0876_hu_cfeb4955adaa812d.webp)](tiktok-for-business-e34f4d0876.jpeg) The TikTok beta connected B2C Commerce catalog and shopper data to another discovery channel. A beta program is available to test an integration between B2C Commerce Cloud and Tiktok. This Beta aims to create storefronts and advertise products on Tiktok using products and shopper activity data. Currently, recruiting for this feature is paused until further notice! Even though recruiting is currently on hold, it is good to see the Salesforce team is actively investigating integrating with social channels. ## PWA Kit v1.5.x As with SFRA, the first years will see quick releases with new features added. Besides the major “2.x” release currently in the developer preview, improvements are being made to the “1.x” version concurrently. In this release, these new features and improvements were added: - [Multiple Sites support](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/multiple-sites.html) - Forgot Password Flow ([Community Contribution](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/373)) - Support Hybrid Storefronts ([SFRA and PWA Kit](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/429)) - [Bug Fixes](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v1.5.0) ## SCAPI ### Shopper Context API The Shopper Context API will enable customers to build headless storefronts with personalization. This API is currently in the BETA stage, so you may opt in at your discretion. > The context information is evaluated against the customer group definitions to determine a customer group (shopper segment) and then used to activate the experiences associated with a particular segment, such as promotions. Want to make use of this API? The documentation is available [in the Shopper Context API reference](https://developer.salesforce.com/docs/commerce/commerce-api/references?meta=shopper-context:Summary)! ### SLAS Password-less Login This new addition to the SLAS APIs will allow registered customers to log in without using a password. Instead, it will allow you to log in using a private link sent to your email (and later through SMS or a TOTP application). The documentation is available here: - [Shopper](https://developer.salesforce.com/docs/commerce/commerce-api/references?meta=shopper-login:/organizations/%7BorganizationId%7D/oauth2/passwordless/login) - [Admin](https://developer.salesforce.com/docs/commerce/commerce-api/references?meta=slas-admin:/tenants/%7BtenantId%7D/clients/%7BclientId%7D/passwordless-templates) This change gives us more flexibility in providing login options to customers. **Note:** This API is only available for private clients, and the email login templates only support plain text. For now, styling the e-mail for the password-less login option is out of the question. **Update:** It turns out that HTML is supported; the API determines if it is plain text or not. **Be sure to validate your HTML on different email clients,** as the service does not do any validation of the template! ## Business Manager ### Rule-Based Categorization [![Rule-based categorization screen showing product exclusion rules.](/salesforce-b2c-commerce-the-22-5-release/product-exclusion-list-rule-based-0acada8ea8_hu_36e7df75e9029c0d.webp)](product-exclusion-list-rule-based-0acada8ea8.png) Rule-based categorization gains product exclusion lists and support for up to 20 conditions per rule, replacing the previous five-condition ceiling for dynamic category assignments. [Dynamic Categorization](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/categories/b2c_dynamic_categories.html) is a recent addition to the Salesforce B2C Commerce Cloud feature list, allowing the automatic (job-based) assignment of products to specific categories on configurable criteria. Over the past months, a lot of feedback has been provided on this feature. And in this release, two new updates are announced: - Ability to create exclusion rules for products - Maximum conditions for a rule have been increased from 5 to 20 Having the option to set more than five conditions will give merchandisers more flexibility when organizing their categories. ### Salesforce Payments Credentials Storage Salesforce Payments is getting some love in this release. The first addition is storing payment card credentials for: - **Future off-session use:** Support for recurring subscription payments or delayed payments (pay when order is fulfilled) - **Save for on-session use:** Store payment options for a quicker customer check-out (only available in a shopper session) It is good to see these features being added to the “native” payment option within Commerce Cloud. Storing payment methods will open the door for new use-cases and allow customers to place orders faster and have a better user experience! ### Klarna for Salesforce Payments [![Klarna availability within the Salesforce Payments and Stripe flow.](/salesforce-b2c-commerce-the-22-5-release/klarnastripe-6dabc3b122_hu_d8274f99dbee2910.webp)](klarnastripe-6dabc3b122.jpg) Klarna joins Salesforce Payments through the Stripe integration, giving shoppers installments, pay-later, and financing options without requiring a separate Klarna merchant agreement. For most, [Klarna](https://www.klarna.com/international/) is a well-known payment method. This option has now been added to Salesforce Payments giving shoppers the ability to use the three different pay-later options that Klarna provides: - Installments - Pay Later - Financing Another advantage for merchants is that no additional agreement needs to be signed with Klarna. But as always, with payment providers, check the costs per payment that are part of your [existing agreement](https://stripe.com/en-be/pricing?utm_campaign=paid_brand-BE_en_Search_Brand_Stripe-868855632&utm_medium=cpc&utm_source=google&ad_content=307877157763&utm_term=kwd-487920435973&utm_matchtype=e&utm_adposition=&utm_device=c) with Stripe. **Note:** The merchant receives payments [according to a payout schedule](https://www.klarna.com/uk/business/merchant-support/when-will-we-receive-payment-from-klarna/) even though customers pay the amount later. ## Development ### Custom Job Steps Context Jobs that store non-primitive data types of values in **dw.job.JobExecution.getContext()** now fail. Previously, the job logged a warning, ignored the invalid value, and continued. ### Known Issue Bugfixes I have looked at the recently updated issues but found that they are still “In Review,” and none have been updated to resolve for this release. --- ## Certifications for Salesforce B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/certifications-for-salesforce-b2c-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/certifications-for-salesforce-b2c-commerce-cloud/index.md Content type: article Published: 2022-04-13T07:07:52Z Updated: 2022-07-23T21:58:17Z Summary: Certifications are an essential part of the journey within Salesforce. But what certifications are available for B2C Commerce Cloud? Categories: Certification Tags: ohana, sfcc ## Key Takeaways - Maps the main Salesforce B2C Commerce Cloud certifications and partner accreditations - Explains how the developer and architect paths differ in depth and expected experience - Calls out the current certification gap for non-technical Commerce Cloud roles Certifications are a part of the Salesforce journey, and anyone who has looked into this knows that there are [many of them available](https://trailhead.salesforce.com/credentials/administratoroverview) to give a stab at. But what about Salesforce B2C Commerce Cloud? How many are available. And which ones are they? Let us have a look! ## Superbadges [Superbadges](https://trailhead.salesforce.com/superbadges) are something you will often come across while reading about preparing for your “Salesforce” certification exam. You have to solve questions and exercises in a sandbox environment. Trailhead will then verify if you have done the configuration or written the code correctly. Since this forces you to work with the platform and configure or code things yourself, it can be excellent preparation! Unfortunately (yup, I got you excited there, didn’t I), this is only available for the core platform, not B2C Commerce Cloud. And because SFCC runs on a completely different stack, don’t expect this to change anytime soon. ## Salesforce Credentials The first type we will have a look at is the Salesforce Credentials. You know, the ones you can achieve via [Webassessor](https://www.webassessor.com/). A little heads up already. You don’t have many options if you are not a technical profile. But we will get into that later! ### B2C Commerce Developer ![The Certified B2C Commerce Developer badge.](/certifications-for-salesforce-b2c-commerce-cloud/b2c-commerce-developer-72d9df9035_hu_e631389822383ebb.webp) The Developer exam still targets SFRA practitioners rather than legacy pipeline specialists. > The Salesforce B2C Commerce Developer credential is designed for those who have experience as full-stack developers for Salesforce Commerce Cloud Digital. The title and the description of this credential do not have any secrets; the main target is Salesforce [B2C Commerce Cloud developers](https://trailhead.salesforce.com/en/credentials/b2ccommercedeveloper). What does it take to grab this certificate? Looking at the past years, experience in one or two projects will give you a high chance of passing the exam. Now, let’s nuance this a little bit. If your past two projects were with pipelines / SiteGenesis, you have some studying to do. The exam expects you to know SFRA controllers and will not test your knowledge of pipelines anymore. If you still think you need some preparation, look at the [exam guide](https://trailhead.salesforce.com/help?article=Salesforce-Certified-B2C-Commerce-Developer-Exam-Guide). It will point you in the right direction! ### B2C Commerce Architect ![Salesforce Certified B2C Commerce Architect badge.](/certifications-for-salesforce-b2c-commerce-cloud/b2c-commerce-architect-3d1b1f2f1e_hu_81360fcce7c7856f.webp) The B2C Commerce Architect certification requires the Developer credential as a prerequisite and shifts focus from hands-on implementation to project-lifecycle and multi-site design pattern questions. > The Salesforce B2C Commerce Architect has experience designing global sites that support multiple brands and channels using standard design patterns. The next step in the journey of the Certified B2C Commerce Developer! Focussing more on the project lifecycle compared to development. Important to note that you can only achieve this certification if you are a Certified B2C Developer. It should not surprise that this certificate is on “another” level than the Developer certification. Do not expect questions like “how do you log a message to the error log” but more like “You have three domains that have to be linked to these two sites. Which of the following four answers is the correct [Hostname Alias](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/search_engine_optimization/b2c_hostname_aliases.html) configuration?”. Want to know more about what this certificate expects you to know? Have a look at the [exam guide](https://trailhead.salesforce.com/help?article=Salesforce-Certified-B2C-Commerce-Architect-Exam-Guide)! If you feel like an in-person or virtual training is more suited for you, the [ARC-300 course](https://trailheadacademy.salesforce.com/classes/arc300-architect-b2c-commerce-solutions) (which I am teaching in EMEA - a bit of self-promotion) is perfect for you. ## Accredited Professional Last year a new type of certification made its way into the Salesforce ecosystem: “Accreditations.” Before you read more about this, be warned that this is a certification only available for Salesforce Partners (and Salesforce employees looking at LinkedIn) You can look at these Accreditations as a “specialization” certification. While the other certifications will look at a broad spectrum of platform features, accreditations will test your knowledge of a specific feature or part. ### Headless API First > The Salesforce Headless API First Accredited Professional exam is designed for consultants who have experience implementing and consulting on B2C Commerce or headless projects in a customer-facing role. This exam is for individuals who want to demonstrate their skills and knowledge in configuring and using Salesforce Commerce APIs in the context of Sample Apps and real headless implementations. As Headless (API First) made its way more prominently into the Salesforce B2C Commerce Cloud world last year, it was expected that a certification was explicitly made for it. The exam will focus solely on the [SCAPI](https://developer.salesforce.com/docs/commerce/commerce-api/guide) (Salesforce Commerce APIs), testing your knowledge of this set of REST endpoints. But not to worry, there is [a course](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=ql98ga3ai8kA8o02yzJVDFG8XmW19tGoNUdRg55RgKsxWkPN9Kb%2BNqGkuz1tWcJ%2F) on the [PLC](https://partnerlearningcamp.salesforce.com/) (Partner Learning Camp) to guide you through preparing for it. ### Commerce Cloud Einstein ![Einstein Commerce Cloud Accredited Professional badge.](/certifications-for-salesforce-b2c-commerce-cloud/einstein-d7123b2738_hu_93f8760836ff86b1.webp) This partner-only accreditation covers Einstein implementation from data feeds to debugging. > The Einstein Commerce Cloud Accredited Professional exam is intended for individuals who have the knowledge, skills, and experience with data ingestion processes, security, and access implementations. One of the selling points of Salesforce B2C Commerce Cloud (and other Salesforce offerings) is the AI engine to give personalized product recommendations: Einstein. This accreditation tests all your knowledge of Einstein: - Development (Slots & Active Data) - Setting up the data feeds in the Business Manager - Configuring the recommender - Debugging Einstein As with the other Accreditation, [a course is available on the Partner Learning Camp](https://partnerlearningcamp.salesforce.com/s/browse-catalog?plc__recordId=AJ%2F%2F26%2FbM4WJjnIak4uXHwpstt68nZPqvIdhKT%2FnZEw9I%2FDpO60A4d8W08lxq8xT)! ## What if i’m not a developer A common question asked. Currently, only developers seem to get the “Certification love,” but not so much Business Analysts or merchandizers. If there is one I would recommend that non-technical profiles can pass, it’s the Commerce Cloud Einstein Accreditation. I feel that this is a gap within the ecosystem that should be filled; developing for SFCC is one thing. But it would be best if you also had profiles who are experts at configuring a channel and making the right choices to get it up and running. This non-technical certification would allow people to publicly show that they know how to get your company up and running on Salesforce B2C Commerce Cloud (using standard features or knowing when custom development is needed). If anyone at the Salesforce Credentials team is reading this, give me a shout to discuss this 😇. --- ## How to get a Salesforce B2C Commerce Cloud Sandbox Canonical URL: https://rhino-inquisitor.com/how-to-get-a-salesforce-b2c-commerce-cloud-sandbox/ Markdown URL: https://rhino-inquisitor.com/how-to-get-a-salesforce-b2c-commerce-cloud-sandbox/index.md Content type: article Published: 2022-04-05T05:36:43Z Updated: 2022-12-20T16:23:36Z Summary: Getting access to a sandbox in Salesforce B2C Commerce Cloud is not as easy as it is for the core platform. Find out here how to get it done! Categories: Salesforce Commerce Cloud Tags: sandbox, sfcc ## Key Takeaways - Explains why getting an SFCC sandbox differs sharply from the core Salesforce platform flow - Breaks down access paths for newcomers, partners, and existing B2C customers - Highlights fallback options like PWA Kit public sandboxes and Trailhead Academy access As a developer, you want to know what you are getting yourself into to make a conscious choice of what you will be doing for the years to come. And looking at the Salesforce core platform, [it is straightforward to spin up a sandbox](https://developer.salesforce.com/signup)! But does this also apply to Salesforce B2C Commerce Cloud? Long story short, no. There are three scenarios in play that might apply to you. ## You are new to Salesforce You have been into web development for a while now (or are new to it), and e-commerce is “your thing.” People told you about Salesforce and how easy it is to set up an environment for free. But much to your surprise, you can easily set up a Salesforce Developer Sandbox, but this has nothing to do with Salesforce B2C Commerce Cloud. You scour google and Trailhead, and you find information on spinning up an [On-Demand Sandbox.](https://trailhead.salesforce.com/en/content/learn/modules/b2c-on-demand-sandbox) It talks about an account on [Account Manager](https://account.demandware.com/) that you have to use to spin up a sandbox, but there are no details on how to access it. ### A bit of history Salesforce B2C Commerce Cloud wasn’t always named like that; it was called [Demandware](https://en.wikipedia.org/wiki/Demandware) until the end of 2016, when Salesforce acquired it. It is an entirely different “stack” and has no relation to the Salesforce Core Platform (but more and more integrations have been happening over the years). Because of this, getting access to this system is [an entirely different process](https://trailhead.salesforce.com/en/content/learn/trails/build-your-b2c-commerce-consulting-practice). I also wrote a post recently explaining the [difference in the community](/the-state-of-ohana-for-salesforce-commerce-cloud/). ### So then … how do I get access When this article was first published, community feedback suggested that a request sent to [sfcc-b2c-trial@salesforce.com](mailto:sfcc-b2c-trial@salesforce.com) could lead to a trial sandbox. That guidance is now outdated. Since then, I have been told that this address is only for internal (Salesforce) use by Account Executives or Partner Managers. The primary purpose is to provide a contact point for accounts that already have access to a trial sandbox for maintenance purposes. So, for now, the message is as follows: > To obtain a trial sandbox please reach out to either your Commerce Cloud Account Executive (customers) or your Partner Manager (partners). For details on the partner program look [at the partner program overview](https://partners.salesforce.com/pdx/s/learn/article/isv-b2c-commerce-MCDSZA63SNTNCRRBPDZX3PU7OGWI?language=en_US). ### PWA Kit If you, however, plan on working on the storefront with [PWA-Kit](http://pwa-kit.mobify-storefront.com/), that is an entirely different story. This headless storefront has been made entirely open-source and provides an install command that will automatically connect you to a public sandbox so you can learn how to work with the [APIs](https://developer.commercecloud.com/s/commerce-api). If you are a [React](https://reactjs.org/) developer, this is the playground for you! _Note: You can not access the Business Manager of this public sandbox; Salesforce manages it!_ ## You are a Salesforce partner Being a partner will make finding documentation a little easier and a lot more confusing, weird right! On the [partner community](https://partners.salesforce.com/pdx/s/), you will find two groups that contain helpful information on becoming a Salesforce B2C Commerce Cloud-enabled partner: - **[B2C Commerce](https://partners.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F93A0000009SFY):** A group that contains the documentation required to become “[enabled](https://partners.salesforce.com/0693A000006lGVl?retUrl=%2F_ui%2Fcore%2Fchatter%2Fcontent%2FGroupFileListPage).” - **[Partner On-Demand Sandboxes](https://partners.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F93A000000DQ6f):** A group containing all information about ODS, more specifically the ones used by partners Note: Depending on your journey towards B2C, your next step is usually to work through your Account Executive or Partner Manager rather than emailing the old trial address directly. ## You are a B2C partner or Client Well, now, you should be set! If you are a B2C-enabled partner or a client, you can spin up as many On-Demand sandboxes as you want! Watch out! If you go overboard, [extra charges will be added to your contract](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/sandboxes/b2c_purchase_sb_credits.html?resultof=%22%63%72%65%64%69%74%73%22%20%22%63%72%65%64%69%74%22%20)! Just read all of the available documentation, and you should be good to go: - [Documentation Site](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/sandboxes/b2c_developer_sandboxes.html) - [Trailhead](https://trailhead.salesforce.com/content/learn/modules/b2c-on-demand-sandbox) ## Trailhead Academy ![Trailhead Academy branding for the paid sandbox training option.](/how-to-get-a-salesforce-b2c-commerce-cloud-sandbox/trailhead-academy-77b0322d57_hu_aa7654be33da32b5.webp) Figure 1: Trailhead Academy branding for the paid sandbox training option If all else above is unavailable to you and no sandbox is within your reach, a paid training course is the final option with [Trailhead Academy](https://trailheadacademy.salesforce.com/overview). There is one course available that gives you access to a Sandbox for about three weeks: - [CCD102: B2C Commerce Developer (SFRA) Training](https://trailheadacademy.salesforce.com/classes/ccd102-b2c-commerce-developer-with-sfra?_ga=2.254667784.102261915.1666000067-1536331326.1643878545) The critical thing to note here is that this course is not the cheapest and will force you to dig deeper into your pockets. On the flip side, you immediately get training on how to develop for Salesforce B2C Commerce Cloud. --- ## Versioning of Content Assets Canonical URL: https://rhino-inquisitor.com/versioning-of-content-assets/ Markdown URL: https://rhino-inquisitor.com/versioning-of-content-assets/index.md Content type: page Published: 2022-03-27T06:29:47Z Updated: 2022-03-27T06:52:42Z Summary: Version content assets in SFCC so teams can review edits, compare revisions, and roll back safely when a publish change introduces risk. Everyone makes mistakes, big and small. There is no easy way to return within the Content Management system built into Salesforce B2C Commerce Cloud once you save a Content Asset. It is easy as pie to roll back changes to even months ago within many plugins and editors (including [Elementor](http://elementor.com), which I use for this blog.) This is most certainly a missing feature in Page Designer and Content Assets! ![Revision history illustration for versioning content assets in SFCC.](/versioning-of-content-assets/revision-blog-12e6fdce00_hu_a49efa971d36bf09.webp) Revisions in Elementor [Vote for this idea here](https://ideas.salesforce.com/s/idea/a0B8W00000GdVsJUAV/versioning-of-content-assets) --- ## B2C Commerce: What's New In 22.4 Canonical URL: https://rhino-inquisitor.com/b2c-commerce-whats-new-in-22-4/ Markdown URL: https://rhino-inquisitor.com/b2c-commerce-whats-new-in-22-4/index.md Content type: article Published: 2022-03-21T19:57:05Z Updated: 2022-07-23T21:46:22Z Summary: In this post we take a look at the release notes of Salesforce B2C Commerce Cloud for April 2022, and dig a bit deeper into them. Categories: Release Notes, Salesforce Commerce Cloud Tags: Business Manager, ocapi, sfcc, technical ## Key Takeaways - Highlights April 2022 changes across PWA Kit, SLAS, OCAPI caching, and Business Manager - Explains why the deprecated login flow should move to SLAS for storefront resilience - Calls out new caching and variation-group behavior worth testing before rollout In this post, we will be looking at the release notes of Salesforce B2C Commerce Cloud for April 2022. Since the release cycles for B2C Commerce are [a lot quicker than the other Salesforce platforms](https://medium.com/inside-the-salesforce-ecosystem/a-partners-guide-to-navigating-the-salesforce-release-cycle-efa36ed3c64), not every month will be as extensive a list as the other. Check out the original release notes [for April 2022](https://help.salesforce.com/s/articleView?id=rn_b2c_rn_22_4_release.htm&type=5&language=en_US). ## PWA Kit ### Managed Runtime logs To access the logs of the Managed Runtime, you had to request access to the AWS logging for everyone separately. It will now be possible to tail or download the logs via the Runtime Admin UI! This update will make it easier for developers to debug, analyze, and address issues on a deployed version of their PWA Kit! **Note:** Keep in mind that the Managed Runtime is on a different release cycle, so it will probably not match the “B2C core” release dates. ### v2.0 Developer Preview A new major release of PWA Kit is on the horizon! This release has a few new toys: - First steps towards Typescript support - The development server is updated to support hot-reloading of the server-side - An all-new CLI tool called “mrt” that combines Webpack, Jest, and Babel to support zero-config projects - Experimental support for non-React projects is added You can find more information about this release on [GitHub](https://github.com/SalesforceCommerceCloud/pwa-kit/discussions/395). ## SCAPI ### Deprecation of /login When using the login endpoint, if an outage happens in the Account Manager, customers will be unable to log in to the storefront. It goes without saying that this is a very strange “dependency” for storefront customers. To mitigate this dependency, the/login endpoint is deprecated and replaced by [SLAS](https://developer.commercecloud.com/s/api-details/a003k00000VWfNDAA1/commerce-cloud-developer-centershopperloginandapiaccessservice) (Shopper Login and API Access Service). ### Benefits of this change - Account Manager outages will no longer impact the ability to log in or checkout in the storefront applications - SLAS is more secure - SLAS supports more login mechanisms ## OCAPI ### GET Products Caching With this update, eCDN caching is enabled for the GET Products API! The update will improve the scalability and performance of Salesforce B2C Commerce Cloud. **But it is not enabled by default!** To take advantage of this update, you need to do the following: - Set “cache-control” headers - Ensure the client ID is included as a query parameter or in the “x-dw-client-id” and “cache-control” header. - Do not include an “Authorization” header with the request. Adding it will disable caching. If you still have questions about caching in the OCAPI, [you can find more information in the Infocenter](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/OCAPI/current/usage/Caching.html). ### General Improvements Over the years, some frustration with developers has been that some fields or functionalities were unavailable within the Open Commerce API. Salesforce has heard our concerns and has slowly closed these holes over the years. However, there are still some big ones (e.g., Price Books). With this update, the following changes have happened: - **Search and sort by creation and last modified date:** Now, more data APIs allow you to utilize the create and last-modified dates. This change will make it a lot easier to acquire **delta** information! The following [DATA APIs](https://documentation.b2c.commercecloud.salesforce.com/DOC3/topic/com.demandware.dochelp/OCAPI/current/usage/DataAPIResources.html?cp=0_16_4) have been extended: - Order Search - Product Search - Customer Search - Custom Object Search - Catalog Search - **[Guest Flag](https://documentation.b2c.commercecloud.salesforce.com/DOC3/index.jsp?topic=%2Fcom.demandware.dochelp%2FOCAPI%2Fcurrent%2Fshop%2FDocuments%2FOrder.html&anchor=id1520261250):** It is now easier to detect an order made by a guest checkout or a registered customer. ## Business Manager ### Product Management If you use Variation Groups, this feature will make the storefront search a little more flexible. A new [Feature Switch](https://documentation.b2c.commercecloud.salesforce.com/DOC1/index.jsp?topic=%2Fcom.demandware.dochelp%2Fcontent%2Fb2c_commerce%2Ftopics%2Fproducts%2Fb2c_configure_variation_groups_display_mode.html) will enable the option to merge all Variation Groups in the lister pages (category & search). Once enabled, merchandizers [will see extra options in the business manager](https://documentation.b2c.commercecloud.salesforce.com/DOC1/index.jsp?topic=%2Fcom.demandware.dochelp%2Fcontent%2Fb2c_commerce%2Ftopics%2Fproducts%2Fb2c_configure_variation_groups_display_mode.html). ![Catalog setting that switches variation groups to merged or individual display.](/b2c-commerce-whats-new-in-22-4/category-option-plzwjt3ux7rivo7o7mgc8xhnroisdxv69lzyysd3pa-a3eb0312c7_hu_7e571929c772ddb2.webp) This catalog setting is the switch that enables merged variation-group behavior. But once you enable this option, how does it translate in the storefront? Let’s have a look! ![Three variation-group products shown as separate pants tiles.](/b2c-commerce-whats-new-in-22-4/variation-groups-before-14c54a10bd_hu_26c79702fdeea7cf.webp) Before the change, each variation group surfaced as its own product tile. ![Merged variation-group storefront result with shared swatches.](/b2c-commerce-whats-new-in-22-4/variation-groups-after-513fc19983_hu_2d7f177f2c7608da.webp) After enabling the feature, shoppers see one tile with shared swatches instead. ![Category configuration panel for assigning variation-group display behavior.](/b2c-commerce-whats-new-in-22-4/configuration-variation-groups-32dec4386b_hu_309d16c2a780d328.webp) Category-level configuration decides where merged or individual variation-group display applies. But why use this option? Could you assign the master product to the category to get the same result? ~~The answer is no. When you assign the master, you include all of your Variation Groups (this shows all the swatches without custom development). With this option enabled, you can control which swatches show by assigning only the applicable Variation Groups.~~ The above is not valid. I got lucky with the products I assigned during my test to match the swatches exactly, and it acts the same as you would assign the master. Does that mean that there are no differences? Probably not. I feel there will be slight changes in how the [SearchModel](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_catalog_ProductSearchHit.htm) represents products, and a good place to start looking is the “[Represented Products](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_catalog_ProductSearchHit.html#dw_catalog_ProductSearchHit_getRepresentedProducts_DetailAnchor).” Have you experimented with this feature already and found differences? Share your findings in the comments! Is it necessary for everyone to turn the switch on? No, this depends on your situation and how you want to present your products to the customer. But this option gives us more flexibility, which is never a bad thing! **Note:** If you set the type to “merged” on the top level but “individual” on a sub-category, it will not work. The products do not display correctly anymore. ![Broken product lister page rendering null values after an invalid variation-group setup.](/b2c-commerce-whats-new-in-22-4/broken-category-08697befce_hu_a72e296101db2db1.webp) A mismatched configuration breaks the product lister instead of degrading gracefully. ### Prorated Discounts From now on, when you configure a “percentage discount promotion” on multiple items, this will be prorated automatically across all eligible items. Before, you had to select the “Prorate Discount” option on the promotion. ![Promotion setting that enables discount proration across line items.](/b2c-commerce-whats-new-in-22-4/prorate-discount-0a85da771a_hu_2423863cf0267057.webp) Discount proration only works once the promotion is configured explicitly. ### Source Code Groups Not much has changed here. A new limit is imposed on the ID field to 28 ASCII characters. Before this change, you could enter an ID that was longer, but it would be truncated after saving. ## Bugfixes Last but not least, we will have a look at if any of the bugs that customers and partners reported have been fixed in this release! - [Stored Basket returns already ordered basket](https://trailblazer.salesforce.com/issues_view?id=a1p4V000000pOrSQAU) - [Source Code Group export fails due to trailing white space in ID](https://trailblazer.salesforce.com/issues_view?id=a1p4V000001nT8NQAU&title=source-code-group-export-fails-due-to-trailing-white-space-in-id) --- ## Mail Attachments in B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/mail-attachments-in-b2c-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/mail-attachments-in-b2c-commerce-cloud/index.md Content type: article Published: 2022-03-15T06:04:04Z Updated: 2025-07-16T14:10:47Z Summary: Learn how to send emails with attachments from Salesforce B2C Commerce Cloud using ISML, including setup details and implementation pitfalls. Categories: Salesforce Commerce Cloud, Technical Tags: mail, pdf, sfcc ## Key Takeaways - Explains the low-level MIME and Base64 workaround required to send email attachments from native SFCC mail APIs - Provides a practical controller and ISML-template approach for building attachment-capable emails - Frames the feature as possible but intentionally outside the platform's simple transactional email comfort zone Sooner or later, a client will ask: “Can we attach the PDF invoice to the order confirmation email?” In the world of Salesforce B2C Commerce Cloud, a seemingly simple request sends a developer down a rabbit hole of undocumented features and hidden platform quirks. The standard dw.net.Mail API offers no ‘addAttachment’ method. The official documentation is silent. The developer is on their own. This report will deconstruct the MIME protocol, build a bulletproof, reusable service for generating attachments, navigate the treacherous gauntlet of platform quotas, and discuss the strategic choice between this native method and a third-party Email Service Provider (ESP). ## TLDR; Solution For those who want a quick solution to their attachment problem without extensive reading, here you go! An alternative example can also be found [in the jsPDF attachment controller example](https://github.com/taurgis/salesforce-commerce-cloud-libraries/blob/master/cartridges/plugin_testlibraries/cartridge/controllers/jsPDF.js)! ### Controller ```js 'use strict'; var server = require('server'); /** * Encodes a string into a base64 string with an email-safe line width * * @param {string} str String the string to encode * @param {string} characterEncoding String the character encoding (i.e. 'ISO-8859-1') * * @return {string} The encoded string */ function encodeBase64ForEmail(str, characterEncoding) { var StringUtils = require('dw/util/StringUtils'); var StringWriter = require('dw/io/StringWriter'); var strBase64 = StringUtils.encodeBase64(str, characterEncoding); var strBase64LB = ''; var stringWriter = new StringWriter(); var offset = 0; var length = 76; while (offset < strBase64.length) { var maxOffset = offset + length; if (strBase64.length >= maxOffset) { stringWriter.write(strBase64, offset, length); stringWriter.write('\n'); } else { stringWriter.write(strBase64, offset, length - (maxOffset - strBase64.length)); } offset += length; } stringWriter.flush(); strBase64LB = stringWriter.toString(); stringWriter.close(); return strBase64LB; } /** * Read a file to a String (encoded in IS0-8859-1) * * @param {string} filePath - The file path to read * * @return {string} - The file content */ function readPDFFile(filePath) { var File = require('dw/io/File'); var FileReader = require('dw/io/FileReader'); var testPDF = new File(filePath); var pdfReader = new FileReader(testPDF, 'ISO-8859-1'); var pdfContent = ''; var line = ''; /** * Warning: You can reach the maximum string length with this code! */ do { line = pdfReader.readN(1000); pdfContent += line; } while (line != null); return pdfContent; } /** * Add files to the attributes to render the mail template. * * @param {dw.util.Map} mailAttributes - The mail attributes */ function addFilesToMailAttributes(mailAttributes) { var Map = require('dw/util/HashMap'); var pdfContent = readPDFFile('IMPEX/jspdf/test_0.pdf'); var files = new Map(); files.put('test.pdf', encodeBase64ForEmail(pdfContent, 'ISO-8859-1')); mailAttributes.put('Base64FileMap', files); } /** * Just an example controller to test sending a mail with attachments */ server.get('Test', function (req, res, next) { var Map = require('dw/util/HashMap'); var Template = require('dw/util/Template'); var Mail = require('dw/net/Mail'); // Create the template that we will use to send the email. var template = new Template('mail/testMail.isml'); // Work with a HashMap to pass the data to the template. var mailAttributes = new Map(); mailAttributes.put('EmailMessage', 'Test Message'); addFilesToMailAttributes(mailAttributes); var mail = new Mail(); // Render the template with the data in the Hash var content = template.render(mailAttributes); mail.addTo('thomas.theunen@gmail.com'); mail.setFrom('info@forward.eu'); mail.setSubject('Example Email'); mail.setContent(content); res.json({ success: mail.send().message, content: content.getText() }); next(); }); module.exports = server.exports(); ``` ### Template ```text <iscontent type="multipart/mixed; boundary=001a113414f6401b8604f1451630" compact="false" charset="ISO-8859-1"> --001a113414f6401b8604f1451630 Content-Type: multipart/mixed; boundary=001a113414f6401b8604f1451630 --001a113414f6401b8604f1451630 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <isif condition="${!empty(pdict.EmailMessage)}"><isprint value="${pdict.EmailMessage}" /></isif> --001a113414f6401b8604f1451630 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <isif condition="${!empty(pdict.EmailMessage)}"><isprint value="${pdict.EmailMessage}" /></isif> <isif condition="${!empty(pdict.EmailTemplate)}"><isinclude template="${pdict.EmailTemplate}" /></isif> <isif condition="${ !empty(pdict.Base64FileMap) }"><isloop items="${ pdict.Base64FileMap.keySet() }" var="key"><isset name="fileContent" value="${ pdict.Base64FileMap.get(key) }" scope="page"/> --001a113414f6401b8604f1451630 Content-Type: application/pdf; name="${key}"; Content-Description: ${key} Content-Disposition: attachment; filename="${key}"; size=${fileContent.length}; creation-date="${(new Date()).toISOString()}"; modification-date="${(new Date()).toISOString()}" Content-Transfer-Encoding: base64 ${fileContent} </isloop> </isif> --001a113414f6401b8604f1451630-- ``` ## Deconstructing the Challenge: Why dw.net.Mail Plays Hard to Get ### The Root of the Problem: A Deliberate Abstraction The lack of a simple attachment feature in the `dw.net.Mail` class is not an oversight but a design choice. A review of the API documentation reveals methods for setting recipients, subjects, and content, but no methods are provided for files. The API is a high-level wrapper, engineered for a specific purpose: sending simple, transactional text or HTML emails with minimal fuss. It deliberately abstracts away the complexities of the underlying email protocols. This design philosophy reflects a broader platform strategy. Salesforce offers a comprehensive ecosystem of interconnected products, including the powerful Marketing Cloud for sophisticated email campaigns, and recommends third-party ESPs for bulk email sending. The fact that sending an attachment requires a developer to manually construct the email at a low level—a task akin to building a raw HTTP request by hand—while the rest of the platform offers high-level abstractions, is a strong signal. The platform is implicitly [guiding](https://help.salesforce.com/s/articleView?id=000391416&type=1) developers toward more robust, specialised, and often separately licensed solutions for complex requirements. The built-in mailer is for basic transactions. For anything more, the intended path is to integrate with a service _designed_ for that purpose. This guide, therefore, is about learning to operate skillfully and safely outside of that intended path when business needs demand it. ### Welcome to the MIME-Verse Because the `dw.net.Mail` API will not do the heavy lifting, the developer must do it. This means manually constructing a `multipart/alternative` or `multipart/mixed` email. This is the world of Multipurpose Internet Mail Extensions ([MIME](https://en.wikipedia.org/wiki/MIME)). In layman’s terms, the process involves splitting the message into multiple, distinct pieces and separating them with a predetermined key or “boundary”. It’s a way of telling the recipient’s email client, “This message isn’t just one thing; it’s a collection of parts—some plain text for compatibility, some rich HTML for the main body, and one or more files.” The entire construction, including the headers and the multipart body, must be rendered into a single string and passed to the `mail.setContent()` method. ### The Role of Base64 Encoding Email is a fundamentally text-based protocol. The raw bytes of a PDF or a JPEG image cannot be simply dumped into the message body. Doing so would corrupt the file and likely cause the email to be rejected by mail servers. The solution is to encode the binary file data into a text-safe format. This is the role of [Base64](https://en.wikipedia.org/wiki/Base64) encoding. Base64 is the universal translator that converts any binary data into a long string of 64 common ASCII characters that can travel safely through any mail server on the internet. The process involves reading the file’s binary content, running it through a Base64 encoding algorithm, and then embedding that resulting string within the appropriate MIME part of the email structure. The email client then reads the `Content-Transfer-Encoding: base64` header, decodes the string back into its original binary form, and presents it to the user as a downloadable file. This encoding step is non-negotiable and is the technical cornerstone of sending attachments natively from SFCC. ## Breakdown of the solution “Give a man a fish, and he’ll eat for a day. Teach a man to fish, and he’ll eat for a lifetime.” We will be taking this approach to the code above. You can easily copy-paste the code from above and get it to work with your project, but it is also essential to understand each piece of the puzzle. If something goes wrong or an unexpected change is needed, you will know where to look. ### The controller Within the controller, we have multiple functions to help us get all the data to send that e-mail with an attachment. Note: It would be best to move these to a helper file for re-use! #### base64 To work with files (and emails), [base64 encoding](https://en.wikipedia.org/wiki/Email_attachment#:~:text=With%20MIME%2C%20a%20message%20and,support%20via%20the%208BITMIME%20extension.) is the way to go. We will be working with a [multipart](https://en.wikipedia.org/wiki/Multipart_message) message to get this to work. We have the following function in the controller to help us get the required string to use in the mail. ```js /** * Encodes a string into a base64 string with an email-safe line width * * @param {string} str String the string to encode * @param {string} characterEncoding String the character encoding (i.e. 'ISO-8859-1') * * @return {string} The encoded string */ function encodeBase64ForEmail(str, characterEncoding) { var StringUtils = require('dw/util/StringUtils'); var StringWriter = require('dw/io/StringWriter'); var strBase64 = StringUtils.encodeBase64(str, characterEncoding); var strBase64LB = ''; var stringWriter = new StringWriter(); var offset = 0; var length = 76; while (offset < strBase64.length) { var maxOffset = offset + length; if (strBase64.length >= maxOffset) { stringWriter.write(strBase64, offset, length); stringWriter.write('\n'); } else { stringWriter.write(strBase64, offset, length - (maxOffset - strBase64.length)); } offset += length; } stringWriter.flush(); strBase64LB = stringWriter.toString(); stringWriter.close(); return strBase64LB; } ``` And once we have that base64 encoded string, we can use it in our mail template. And inside that template, we are adding some metadata to give information about the file we are trying to send: - **Content-Type:** Here, we will mark which file type and what name the file has. - **Content-Description:** The description of the file - **Content-Disposition:** Here, we provide more information about the file like its filename, the size of the PDF, … - **Content-Transfer-Encoding:** Here, we tell the mail client that the attachment is encoded using base64 ```text --001a113414f6401b8604f1451630 Content-Type: application/pdf; name="${key}"; Content-Description: ${key} Content-Disposition: attachment; filename="${key}"; size=${fileContent.length}; creation-date="${(new Date()).toISOString()}"; modification-date="${(new Date()).toISOString()}" Content-Transfer-Encoding: base64 ${fileContent} ``` As you can see, base64 poses no real challenge for Salesforce Commerce Cloud, and we will be able to send attachments quite easily using it. #### ISO-8859-1 Within the controller, we have multiple options to work with: - [On-the-fly generation of a file](/pdf-and-salesforce-commerce-cloud-b2c/) - Reading a file from the WebDAV In this example, we will be using the second option. ```js /** * Read a file to a String (encoded in IS0-8859-1) * * @param {string} filePath - The file path to read * * @return {string} - The file content */ function readPDFFile(filePath) { var File = require('dw/io/File'); var FileReader = require('dw/io/FileReader'); var testPDF = new File(filePath); var pdfReader = new FileReader(testPDF, 'ISO-8859-1'); var pdfContent = ''; var line = ''; /** * Warning: You can reach the maximum string length with this code! */ do { line = pdfReader.readN(1000); pdfContent += line; } while (line != null); return pdfContent; } ``` While this solution relies on [ISO-8859-1](https://en.wikipedia.org/wiki/ISO/IEC_8859-1), the modern and recommended standard for all email development is **`UTF-8`**. For any new implementation in Salesforce B2C Commerce Cloud, you should attempt to use `UTF-8`. This encoding provides universal compatibility, correctly handling international characters, symbols (e.g., €, ©), and emojis that are common in today’s digital landscape and would otherwise fail or cause issues with a more limited character set. The principle of consistency, however, remains paramount. Whichever encoding you choose—and we strongly recommend it **`UTF-8`**—it must be applied uniformly at every single step of the process. This means specifying `UTF-8` when reading the file’s bytes into a string, when declaring the charset in your `<iscontent>` tag, and in every `Content-Type` header within the MIME structure. This discipline is not optional; it is the key to ensuring that the receiving email client can correctly reconstruct the file, preventing data corruption and guaranteeing a valid attachment for the end-user. ISO-8859-1 This encoding was chosen because the jsPDF library I used during testing relies on the ‘addImage’ plugin, which has ISO-8859-1 hard-coded for adding JPEG images to PDFS. When this encoding isn’t used consistently across the examples, the PDF renders correctly but the images do not display. Encoding Might Differ In my experience, ISO-8859-1 encoding works best for handling files. However, if you encounter unreadable files, experimenting with the encoding settings in the reader, template, or other levels could help resolve the problem. ### The template Within the template, we will be using a few tricks to get our solution to work. #### Content-Type: multipart/alternative For mails to work with multiple files and a text or HTML option, we must work with the [multipart](https://nl.wikipedia.org/wiki/Multipurpose_Internet_Mail_Extensions) content type and [boundaries](https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html). But what does this mean? In layman’s terms, we split our messages into multiple pieces separating them by a predetermined key. At the top of the file, we tell the system which key it is within the Content-Type (both to Commerce Cloud using the [`<iscontent>`](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/isml/b2c_iscontent.html) tag and the HTML itself for the e-mail reader). Boundary definition error On recent code compatibility modes, we have noticed an error to the likes of “No start boundary defined”. Removing the “Content-Type: multipart/mixed; boundary=001a113414f6401b8604f1451630” below the tag resolves this. ```text <iscontent type="multipart/mixed; boundary=001a113414f6401b8604f1451630" compact="false" charset="ISO-8859-1"> --001a113414f6401b8604f1451630 Content-Type: multipart/mixed; boundary=001a113414f6401b8604f1451630 ``` Once the key has been set, it can “split up” the mail into different parts. A good example is a separate part for the plain-text and HTML emails. Note: Do not forget the ‘–’ in front of the key as you see them in the examples. ```text --001a113414f6401b8604f1451630 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <isif condition="${!empty(pdict.EmailMessage)}"><isprint value="${pdict.EmailMessage}" /></isif> --001a113414f6401b8604f1451630 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <isif condition="${!empty(pdict.EmailMessage)}"><isprint value="${pdict.EmailMessage}" /></isif> <isif condition="${!empty(pdict.EmailTemplate)}"><isinclude template="${pdict.EmailTemplate}" /></isif> --001a113414f6401b8604f1451630-- ``` The same methodology is used for the files. Each attachment gets its own “section” separated by that same key. ```text <isif condition="${ !empty(pdict.Base64FileMap) }"> <isloop items="${ pdict.Base64FileMap.keySet() }" var="key"> <isset name="fileContent" value="${ pdict.Base64FileMap.get(key) }" scope="page"/> --001a113414f6401b8604f1451630 Content-Type: application/pdf; name="${key}"; Content-Description: ${key} Content-Disposition: attachment; filename="${key}"; size=${fileContent.length}; creation-date="${(new Date()).toISOString()}"; modification-date="${(new Date()).toISOString()}" Content-Transfer-Encoding: base64 ${fileContent} </isloop> </isif> ``` #### Watch out for spaces and new lines You will have undoubtedly noticed that the code within the template is quite compressed and not “pretty printed.” Multipart is extremely sensitive to empty lines, tabs, and spaces. So keep that in mind when making modifications to the template. ## Navigating the Gauntlet: Quotas, Sources, and Composable Strategy ### jsStringLength When working with files (especially in the storefront), you have to keep watch of the [Quota Limits](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/quota/html/index.html?resultof=%22%71%75%6f%74%61%22%20%22%6c%69%6d%69%74%22%20) - every developer’s friend in SFCC. In my example, one is especially one to keep an eye on. ![Quota documentation showing the JavaScript string-length limit in Salesforce Commerce Cloud.](/mail-attachments-in-b2c-commerce-cloud/api-jsstringlength-6ae1560d95_hu_d92756cd042c3cc1.webp) Figure 1: Quota documentation showing the JavaScript string-length limit in Salesforce Commerce Cloud There are multiple ways to work around this limit, but we will not be digging into that in this post. ### Template Size Now for the gotchas, because in the world of Commerce Cloud, there are always gotchas. Two critical and distinct size limits are waiting to trip you up, and confusing them can lead you straight into a debugging nightmare. The first is a 10 MB ceiling on the rendered template response. Think of this as a server-side guardrail within the application server itself. As the `ISMLRenderer` processes your template, it combines your email’s text and, more importantly, the Base64-encoded string of your attachments. This Base64 encoding is a key detail, as it inflates the file size by roughly 33%. If this combined, in-memory result surpasses 10 MB, the platform protects itself by throwing a server error and halting the process. You’ll see the failure in your logs; it’s a noisy, obvious problem. However, the more immediate and ruthless limit—the one that truly matters for delivery—is the **3 MB quota for the final, sent email**. This is not a template-rendering limit; it’s a [hard quota](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-dev-best-practices.html#email-support) imposed by the Salesforce mail gateway that physically transmits the message. This is where things get insidious. Your code can successfully render a 5 MB template (well under the 10 MB limit), and the `dw.net.Mail` script will execute without any errors, leading you to believe the email is on its way. However, when the 5 MB package reaches the mail server, it is silently dropped because it exceeds the 3 MB quota. There’s no error thrown back to your script, no explicit failure in the logs—the email simply vanishes into the void. To clarify, your attachment strategy should prioritise the smaller of the two limits. The 10 MB template limit is a technical constraint, but the 3 MB mail gateway limit is the real practical ceiling. You need to calculate the total payload size, including headers, HTML body, and all attachments, after Base64 encoding, to ensure it remains within that 3 MB limit. Ignoring this means your emails won’t be delivered; instead, you’ll be running code that sends your data nowhere. ## Not just PDF We have been working with PDF in this example, but you can also use this solution for other file types! You could send CSV reports, as an example, using this method. ## Sources It wouldn’t be fair to the authors if I did not provide links to the sources I used to get a working example. - [GitHub: dpavlikovskiy](https://github.com/dpavlikovskiy/mhe_enhancements/blob/f437062fd851d96c15c4f4366d48ddcdf8147c1f/cartridges/int_simplefeed_jfw/cartridge/templates/default/mail/emailTemplateAttachment.isml) - [Salesforce B2C Commerce Cloud Unofficial Slack](https://sfcc-unofficial.slack.com/archives/CAT794PC3/p1616592855270900) ## The Composable Storefront Consideration The architecture built thus far is entirely server-side logic. In a traditional SFRA world, it would be called from a controller as shown. In the modern landscape of the Composable Storefront (PWA Kit), the core service logic does not change, but the access pattern does. The code should be integrated into a custom API endpoint or a hook within a standard one that utilises the Commerce API (SCAPI). The PWA Kit front-end would then securely and authentically call this endpoint—such as after a successful checkout—to initiate the email creation and dispatch process on the server. The main task of building the MIME stream remains the same, but when the attachment is something a user submits via the front-end, it introduces a whole new set of concerns. However, that might be an idea for a future article. ## The Strategic Choice: Native Attachments vs. The ESP Alternative A powerful new tool now joins the developer’s toolkit. Yet, experienced developers understand that just because something can be created doesn’t mean it should be. This native attachment method acts like a scalpel, ideal for targeted, low-volume transactional tasks. For more complex or demanding situations, a different approach is necessary. The superior alternative for more complex requirements is to integrate a third-party Email Service Provider (ESP) or Marketing Automation Platform, such as [Marketing Cloud](https://www.salesforce.com/marketing/). Salesforce itself recommends this path for any form of bulk mailing. The integration is typically straightforward, involving a call to the a REST API from an SFCC service configured in the Business Manager. ### A Clear Decision Tree The choice becomes clear when framed by project needs. Use the **Native SFCC Method** when: - The use case is strictly for low-volume, transactional emails with attachments. - The attached files are consistently small (well under 1 MB to leave room for the email body) to avoid breaching the 3 MB limit. - Cost is the absolute primary driver, and leveraging the included platform functionality is a mandate. - There is no business requirement for email tracking, analytics, or advanced deliverability management. Use a **Third-Party ESP** when: - Emails need to be sent at any significant scale. - Deliverability and inbox placement are paramount for the business. - The business requires analytics on open rates, click-throughs, and user engagement. - Attachments regularly exceed 1-2 MB, making the native 3 MB limit a constant risk. - The development team’s time is better spent on core commerce features than on manually managing MIME complexities. --- ## B2C Commerce: What's new in the 22.3 release Canonical URL: https://rhino-inquisitor.com/b2c-commerce-whats-new-in-the-22-3-release/ Markdown URL: https://rhino-inquisitor.com/b2c-commerce-whats-new-in-the-22-3-release/index.md Content type: article Published: 2022-03-08T07:42:23Z Updated: 2022-07-23T21:43:46Z Summary: Get some insights in the latest updates to Salesforce B2C Commerce. We have a look at the release notes and provide some background. Categories: Release Notes, Salesforce Commerce Cloud Tags: cloudflare, pagedesigner, sfcc ## Key Takeaways - Highlights March 2022 updates like Lightning UX, Page Shield, and SKU-specific dynamic pages - Explains how Page Shield helps defend storefronts against compromised third-party scripts - Calls out new platform constraints such as the promotion bonus product limit In this post, we will be looking at the release notes of Salesforce B2C Commerce Cloud for March 2022. Let us dig deeper into any new and exciting features added to the platform. Check out the original release notes [for March 2022](https://help.salesforce.com/s/articleView?id=rn_b2c_rn_22_3_release.htm&type=5&language=en_US). ## Lightning UX ![SLDS showcase with example interface components.](/b2c-commerce-whats-new-in-the-22-3-release/slds-ba5571b0d8_hu_1b32c21dbccb2ca6.webp) The Lightning UX refresh makes Business Manager feel more consistent with the rest of Salesforce. As the prophecies have foretold, it would only be a matter of time before [Lightning Man](https://uk.news.yahoo.com/salesforce-lesser-known-cofounder-got-235259945.html?guccounter=1&guce_referrer=aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS8&guce_referrer_sig=AQAAAEMzlHPYg71G3BXTV_zJ9VshBEckh_EEHlmqkdH1OxmCNHV9yKdhBatLjGJGpb1G3rjRqzyqZpwlaajHcyv1UhBB9Db0zi7jHduoV27cQlunovcuvalnh1sABTPyFDtMcKR1nMdtJO0kBa_TfOQJXAj1nt1N9sjXs5VJ-ar5A32I) made its way into the global interface of Salesforce B2C Commerce Cloud. If we look at any of the new features added over the past years, it should come as no surprise: - Page Meta Tag Rules - Jobs - Page Designer - Reports & Dashboards - Storefront Toolkit - … These features already used the [SLDS](https://www.lightningdesignsystem.com/) (Salesforce Lightning Design System). Now slowly, the global items are getting a restyling as well. As this is a cosmetic change, Salesforce added no actual new functionality. From a multi-cloud perspective, having a generic style system across all platforms makes sense to give a “familiar” feel. But I can understand not everyone is a fan of this change. ## Page Shield As trust is the number one value at Salesforce, security is one of the “shields” that form that trust. Page Shield is part of the [eCDN](https://www.salesforce.com/products/commerce-cloud/resources/ecdn-for-commerce-cloud-digital-datasheet/), a Salesforce-managed Cloudflare to which we have “minimal” access. [Page Shield](https://www.cloudflare.com/page-shield/) is one of the Cloudflare features. But since we can not fully control that Cloudflare instance, we depend on the Salesforce team to activate/purchase these features. Between the 1st of march and the 14th of march, Page Shield will be enabled for all accounts and will start protecting against Magecart type attacks. ### But what is Magecart [Magecart](https://www.riskiq.com/what-is-magecart/) is a type of attack that compromises third-party JavaScript dependencies to gain control over the code served to the browser. Taking control of the code allows sensitive data to be stolen (like credit card info). ![A diagram explaining the Magecart attack. It shows a hacker taking over a dependency of a third party script to skim credit card data.](/b2c-commerce-whats-new-in-the-22-3-release/magecart-style-attack-flow-diagram-3x-2d5a5ce4e8_hu_b05fbc785d9035fe.webp) Page Shield watches JavaScript dependencies for suspicious changes through the eCDN layer. ### What does Page Shield do In simple terms: it keeps track of all of the JavaScript and its dependencies, monitoring them for changes. The Salesforce Commerce Cloud security teams constantly monitor and review Page Shield forensic data and immediately act on and notify customers when suspicious activity is discovered. So good news, no additional action is needed from the partner or customer side! I like those kinds of updates 😁. ## SKU Specific Page Designer Pages A small but substantial update to page designer [Dynamic Pages](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/page_designer/b2c_develop_dynamic_page.html)! The Dynamic Page feature allows you to use the Page Designer magic on lister and product detail pages, but only at a category level. That has changed for Product Detail Pages, and it is now possible at the SKU level! ## Promotion Bonus Products Limit With this new update, the Business Manager will now show an error if you assign more than 50 bonus products within a single promotion. Until this update, you could set more than 50 bonus products in the business manager, but the documentation mentioned otherwise. This inconsistency caused quite a bit of confusion with content managers who configured a promotion, but it was not working the way they were expecting. ![Documentation snippet showing the bonus product limit.](/b2c-commerce-whats-new-in-the-22-3-release/bonus-products-ed6b9e3074_hu_9e5ae695f174e1db.webp) Business Manager now enforces the documented 50-item cap for bonus product choices. ## Other updates - [Recursive Infite Copies no Longer Supported](https://help.salesforce.com/s/articleView?id=rn_b2c_web_dav_je.htm&type=5&language=en_US) - [Custom Caches return Immutable Objects](https://help.salesforce.com/s/articleView?id=rn_b2c_custom_cache_w10671394_je.htm&type=5&language=en_US) --- ## Page Designer: Dynamic Pages - Optional Subcategories Canonical URL: https://rhino-inquisitor.com/ideas/page-designer-dynamic-pages-optional-subcategories/ Markdown URL: https://rhino-inquisitor.com/ideas/page-designer-dynamic-pages-optional-subcategories/index.md Content type: page Published: 2022-03-01T16:56:04Z Updated: 2022-03-06T08:51:38Z Summary: Track the Salesforce idea for making Page Designer dynamic-category inheritance optional when subcategories should not share the same landing page. A year after Salesforce released [Page Designer](https://www.salesforce.com/video/3620472/), many of the needed features were added. One of these features was called “[Dynamic Pages](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/page_designer/b2c_develop_dynamic_page.html).” This feature allowed [Page Designer](https://www.salesforce.com/video/3620472/) pages to understand their context: a category, or a product. These pages allow for dynamic components that show [product or category](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/page_designer/b2c_aspect_types.html) information without much manual labor. Now, as with many things, no good deed comes unpunished. There is a “problem” with the dynamic category option. When you select a top-level category, it selects all subcategories as well. Whether you want this to happen or not. Maybe a use-case to explain this. Your catalog structure is as follows: - Pants - Shorts - Jeans - Blue Jeans - Black Jeans You decide to create a category landing page for Jeans to highlight all options. Page Designer is “the” tool to do this. You assign a page to “Jeans” and add all components to highlight some products and content. You are confident with what you have done and visit the page in the storefront (`<https://my-brand.com/pants/jeans>`), and it all looks **perfect**. The changes get replicated to production, and the next day you start getting calls from customers who can no longer visit the Blue and Black jeans categories. All they see is your category landing page (possibly linking to those subcategories), seemingly putting them in an infinite loop of clicking. This happened because your landing page also got assigned automatically to the Blue and Black Jeans subcategories, and there is no way to turn this off (besides custom development). ![Page Designer category assignment screen showing how a page is linked to a category.](/ideas/page-designer-dynamic-pages-optional-subcategories/page-designer-subcategories-8ed50d99ab_hu_9476d4771b0a1b7b.webp) Page Designer - Category Selection Do you also want this automatic selection removed and get more control of your assignments? [Vote for my idea here](https://ideas.salesforce.com/s/idea/a0B8W00000GdZcWUAV/page-designer-category-dynamic-pages-subcategories-should-be-optional) --- ## Page Designer: Add ability to copy/paste components Canonical URL: https://rhino-inquisitor.com/ideas/page-designer-add-ability-to-copy-paste-components/ Markdown URL: https://rhino-inquisitor.com/ideas/page-designer-add-ability-to-copy-paste-components/index.md Content type: page Published: 2022-02-28T17:37:46Z Updated: 2022-10-15T07:02:04Z Summary: Track the Salesforce idea for Page Designer copy and paste, why merchandisers need it, and how the missing workflow slows component-based content work. This feature was implemented!!!! Many years ago, the only way to manage content within Salesforce Commerce Cloud was [content assets](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/content/b2c_content_assets.html) and [slots](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/content/b2c_content_slots.html). They do their job, but it requires your content team to know HTML and CSS. Not only that, you had to save the content and publish it in the Business Manager before verifying how it looked in the storefront. Commerce Cloud needed a better way to manage content. Looking at the Core Platform, and specifically Experience Cloud (Community Cloud at the time), was the solution. ![Experience Cloud page editor shown as the conceptual reference for Page Designer.](/ideas/page-designer-add-ability-to-copy-paste-components/experience-cloud-9470ae566b_hu_5fc11e6ebe918394.webp) Experience Cloud Page Editor The screenshot above looks quite similar to Page Designer within Salesforce Commerce Cloud, though the system is fundamentally different and specific to the Commerce platform. Since Salesforce could not copy the feature, it had to be rebuilt from the ground up. [Experience Cloud](https://www.salesforce.com/nl/products/experience-cloud/overview/) was used as a “cheat sheet,” and some features were/are still missing because of this. One of those features is copy-pasting components. Now you have to create each component (even though it might be almost the same) from scratch. [Vote for my idea here](https://ideas.salesforce.com/s/idea/a0B8W00000GdYHjUAN/page-designer-add-ability-to-copypaste-components) --- ## Ideas Canonical URL: https://rhino-inquisitor.com/ideas/ Markdown URL: https://rhino-inquisitor.com/ideas/index.md Content type: page Published: 2022-02-28T17:24:02Z Updated: 2022-02-28T17:38:05Z Summary: The IdeaExchange was brought into life by Salesforce to allow partners and clients to give input on want and need. Here are some of mine! Salesforce allows its clients and partners to guide the internal product teams to prioritize features in their favorite products. The platform to facilitate this is called the [IdeaExchange](https://ideas.salesforce.com/s/search#t=All&sort=relevancy). You can look at other people’s ideas or submit your own on this website. Using a “points” system, you can vote for specific ideas to give them more visibility. Over the years, I have created and voted for some of these ideas. On this page, I have made an overview of all these ideas! - [Versioning of Content Assets](/versioning-of-content-assets/) — There is no easy way to roll back content changes in SFCC. Version history for Content Assets and Page Designer would prevent costly publish mistakes. - [Page Designer: Dynamic Pages — Optional Subcategories](/ideas/page-designer-dynamic-pages-optional-subcategories/) — When you assign a Page Designer page to a category, all subcategories inherit it whether you want them to or not. - [Page Designer: Add ability to copy/paste components](/ideas/page-designer-add-ability-to-copy-paste-components/) — Merchandisers had to recreate near-identical components from scratch. This feature was implemented! --- ## Archive Canonical URL: https://rhino-inquisitor.com/archive/ Markdown URL: https://rhino-inquisitor.com/archive/index.md Content type: page Published: 2022-02-28T10:35:37Z Updated: 2026-04-05T09:00:00Z Summary: Browse the Rhino Inquisitor archive to find release notes, technical guides, and long-form Salesforce Commerce Cloud articles by date. Browse the Rhino Inquisitor archive to find release notes, technical guides, and long-form Salesforce Commerce Cloud articles by date. Showing 151 results ## Archive Coverage - 2026: 4 entries - 2025: 12 entries - 2024: 27 entries - 2023: 59 entries - 2022: 49 entries --- ## The state of Ohana for Salesforce Commerce Cloud Canonical URL: https://rhino-inquisitor.com/the-state-of-ohana-for-salesforce-commerce-cloud/ Markdown URL: https://rhino-inquisitor.com/the-state-of-ohana-for-salesforce-commerce-cloud/index.md Content type: article Published: 2022-02-27T14:02:53Z Updated: 2022-07-23T22:08:05Z Summary: The Ohana culture within Salesforce is pretty well known, but how does this culture fair within the Salesforce Commerce Cloud community? Categories: Community Tags: ohana, sfcc, slack, trailhead, twitter ## Key Takeaways - Reflects on how the wider Salesforce Ohana culture differs from the smaller and historically more fragmented Commerce Cloud community - Explains the role of legacy community platforms, Trailblazer channels, and the unofficial Slack community in SFCC knowledge sharing - Argues that Slack became the practical center of gravity for B2C Commerce collaboration and mutual support Within Salesforce, the Ohana (Hawaiian for Family) has a pretty significant meaning. Over the past decade, people passionate about Salesforce have built up an enormous community around the platform. The number of people helping each other every day on [Trailblazer Communities](https://trailhead.salesforce.com/trailblazer-community/groups?tab=myGroups), [Twitter](https://twitter.com/hashtag/Ohana), [Stackexchange](https://salesforce.stackexchange.com/), [OhanaSlack](https://meighanrockssf.com/2019/04/02/salesforce-ohana-slack/), and more is just amazing. But then again, how does this reflect on the Salesforce Commerce Cloud B2C community? ## Demandware Let us start with a little bit of history. Salesforce Commerce Cloud B2C didn’t exist before 2016, and then it was still known as [Demandware](https://en.wikipedia.org/wiki/Demandware). It is no secret that Salesforce is known for buying companies to take under its wing, and Demandware was no different. A bit of rebranding later, and “boom,” it’s Salesforce! ![The older Demandware logo, from before the acquisition of Salesforce.](/the-state-of-ohana-for-salesforce-commerce-cloud/demandware-296437f0e6_hu_33e647e7954ea4fc.webp) The old Demandware branding is a reminder that this community grew up under a different identity. ## A big Difference in Ohana I listed a few places where the community was active within the #ohana of Salesforce, so how do the different platforms compare? Based on my personal experience, the used communication channels show a big difference. Note: This is a “personal feeling” pie chart as I did not use any scientific methodology by comparing numbers etc. So take it with a grain of salt! I also left out LinkedIn as it is more business than questions/answers than socializing on Twitter. ### Core Platform [![A pie chart showing the different places people use to communicate within Ohana for the Core platform.](/the-state-of-ohana-for-salesforce-commerce-cloud/ohana-core-7b4cd9574d_hu_122d4a80b77b43f1.webp)](ohana-core-7b4cd9574d.png) For the core platform, community conversations are spread across more official Salesforce channels. ### SFCC [![A pie chart showing the different places people use to communicate within Ohana for the SFCC platform.](/the-state-of-ohana-for-salesforce-commerce-cloud/ohana-sfcc-1d03fd0cb0_hu_6ade2c4adb02c0bf.webp)](ohana-sfcc-1d03fd0cb0.png) SFCC conversation still leans heavily on a smaller set of community-driven spaces. Looking at the above charts, it is pretty clear that there is a significant difference in the way people ask questions and communicate within the #Ohana. ### Twitter I became active on [X](https://x.com/theunenth) a little less than a year ago to get in contact with more people who have an interest in Salesforce. And boy, a lot is going on there: - [**Ohana Pears**](https://twitter.com/Secret_Ohana): Helping to grow & nurture friendships within Ohana - [**shirtforce**](https://twitter.com/shirtforceOrg): Giving through tees - [**SnailMailStickerSwap**](https://twitter.com/SMStickerSwap): Exchanging Salesforce related stickers through Snail Mail - And the list goes on and on… Of course, the main drivers of these are Salesforce CRM Administrators. But does it end at the Salesforce platform? No! All of the groups mentioned above have a target group containing all clouds! So don’t be afraid to mingle 😁. Maybe we should turn in a design for [#shirtforce](https://shirtforce.org/)? ## A second class citizen of Salesforce Ohana Over the years, a part of the community has felt they are not part of the “bigger” Ohana picture. Things like voting on the [feature prioritization](https://ideas.salesforce.com/s/prioritization) and [MVP](https://www.salesforce.com/blog/welcome-2022-mvps) seem like an impossible/pointless task as the smaller B2C community can not even make a dent in the “Salesforce CRM” vehicle. But is it also so surprising? The B2C community is also more isolated and not by its fault looking at the history. ### Xchange The first community within Demandware / SFCC is undoubtedly the Xchange, discontinued and all of its histories erased! It has left many people annoyed as it contained a vast amount of knowledge that people were willing to share with their peers. ![Account Manager roles and permissions page still listing the old Xchange integration.](/the-state-of-ohana-for-salesforce-commerce-cloud/xchange-c2290f06af_hu_281dddc92bbfd3a.webp) XChange lingering in the UI shows how much old community history is still baked into the platform. I found this community (even though it was not as active as the Trailblazer Community is) a beneficial tool to find my way in the world of Salesforce Commerce Cloud. I still find myself assigning the role to every account in Account Manager in nostalgia, even though it does not do anything anymore. ### Commerce Cloud Developer Site In replacement of the Xchange came [the communities on the developer site](https://developer.commercecloud.com/s/discussion-groups). A group of communities separated from the Trailblazer Communities, and it is far less active than the Trailblazer ones. But why is that? Is it because people don’t know it exists? It is pretty hidden. If people even know the site exists at all. If you are not actively working with the headless SCAPI/OCAPI options, you wouldn’t be searching on this site. Daily, people are asking questions, but not many people are answering (besides people from Salesforce) and a few others, including me. So maybe people get discouraged from asking more questions because it is always the same people answering? ### Salesforce Developer Portal ![The logo of the Trailblazer Community Groups](/the-state-of-ohana-for-salesforce-commerce-cloud/community-groups-de4eab826c_hu_e100ac5f2c7736c1.webp) Trailblazer Community Groups were the obvious next place for SFCC people to meet in public. And this year (2022), all of that information is [moving again](https://developer.commercecloud.com/s/salesforce-developer-center)! The Commerce Cloud Developer Site did not live a long life, but that might be for the best as it had its issues. And we will also be merging more and more into the “General Population” together with all of the other products, which might bring some more exposure within the main #Ohana! Also, some good news: this time, the Community Groups will not disappear and will also be migrated into the Trailblazer Community! Yeeey, all of the work I put in answering people’s questions is not going into the Garbage Bin! ## Slack to the rescue Looking back at this blog post, it all seems to have a “negative” tone. But all of this has had a tremendous impact on our primary communication channel: Slack! A large community of people active in the Salesforce Commerce Cloud world chatting away with each other and sharing their wins, challenges, and grievances. Questions are asked on an hourly basis on different topics and get answered quickly, or at least getting pointed in the right direction. In the past year, many people of the mothership have joined in as well—a big shout out to the Salesforce Commerce Cloud team for being active within the community (headless, PWA-kit, documentation, business manager, Page Designer, …). And not to forget our excellent admin team for bringing everyone together! All I want to say to the Slack community is ![A drawing of Salesforce mascots waving with a 'Thank You' message.](/the-state-of-ohana-for-salesforce-commerce-cloud/thank-you-trailblazers-aae5cae7b7_hu_3c5e13dc1d84f1cd.webp) The point is simple: this community works because people keep showing up for each other. ## **Join the Slack Community** Take this moment to join a growing community of Salesforce Commerce Cloud enthusiasts! [Join here](https://github.com/sfcc-unofficial/docs/blob/master/getting-started.md) --- ## About Canonical URL: https://rhino-inquisitor.com/about/ Markdown URL: https://rhino-inquisitor.com/about/index.md Content type: page Published: 2022-02-25T21:45:53Z Updated: 2026-03-24T07:27:00Z Summary: Rhino Inquisitor is Thomas Theunen's working notebook for Salesforce B2C Commerce Cloud architecture, delivery lessons, and practical field guidance. Rhino Inquisitor is the place where I document the technical side of Salesforce B2C Commerce Cloud work that usually gets compressed into architecture meetings, incident calls, migration plans, and release-readiness checklists. My name is Thomas Theunen. I am the Head of Commerce at [Forward](https://www.forward.eu), and I have spent more than a decade working across commerce implementation, platform strategy, architecture, and delivery. The common thread in that work has been translating business pressure into technical decisions that can survive production: decisions about storefront architecture, integration boundaries, rollout safety, performance budgets, SEO risk, and operational maintainability. I still enjoy the hands-on side of the work, especially when a problem moves from vague concern to something you can break apart, model properly, and make safer. I write this site for people who need more than general platform messaging. If you are trying to understand how SFCC behaves under real delivery conditions, this is the material I want to provide. ## What I Actually Work On Most of my day-to-day work is not about abstract transformation language. It is about making technical decisions in environments where the trade-offs matter, the timelines are real, and the cost of being wrong is high. That usually includes: - storefront direction across SFRA, headless, and composable approaches - API and integration design with SCAPI, OCAPI, hooks, middleware, and third-party platforms - performance-sensitive architecture decisions such as caching strategy, synchronous versus asynchronous flows, and backend dependency isolation - launch and migration planning, including redirect safety, canonical consistency, customer migration, and production rollback readiness - engineering quality concerns such as observability, security, accessibility, and release impact assessment The work itself changes from client to client, but the responsibility stays the same: make the solution understandable, operable, and safe enough that a team can live with it after launch. ![Thomas Theunen standing beside a wooden counter and plants in a Trailblazer hoodie.](/about/thomas-theunen-about-portrait-cropped_hu_26e3b64317323af4.webp) ## How I Think About Commerce Engineering I do not separate architecture from delivery. A design is only good if a team can implement it without creating hidden fragility, operate it under load, and extend it without rewriting the whole system six months later. That means I care a lot about the questions that often get deferred until too late: - Where does this customization increase upgrade risk? - What happens when a dependency slows down or fails? - Is this flow observable when something breaks in production? - Are we optimizing for a demo, or for sustained operation? - Is the team buying a capability, or buying a maintenance burden? In commerce, those questions show up everywhere. Real-time inventory checks can damage storefront latency. Search and SEO mistakes can turn a migration into a visibility problem. A release note that looks minor can carry real operational consequences. A launch plan without rollback discipline is not a serious launch plan. That is the level at which I prefer to write and think, and it is usually the level at which I am most useful on a project as well. ## Why Rhino Inquisitor Exists Rhino Inquisitor exists because too much commerce content stops at the overview level. It explains what a feature is, but not when it becomes dangerous, what constraints matter, or which implementation choices create long-term drag. I use this site to publish the kind of material I would want a senior developer, architect, or delivery lead to have before making a decision. That includes topics such as: - SFCC architecture and storefront direction - SCAPI, OCAPI, and integration patterns - performance, caching, and quota-sensitive design - release analysis and change impact - migration strategy, redirect risk, and SEO continuity - secure implementation and production-readiness practices Alongside the writing, I also spend time on public tooling and open source work around the Salesforce B2C Commerce ecosystem. That is part of the same goal: make the platform easier to reason about and easier to work with in practice. ## Who This Site Is For This site is primarily for: - Salesforce B2C Commerce developers who want concrete implementation guidance - architects and technical leads making platform and integration decisions - delivery leads who need to understand migration, release, and launch risk in technical terms - teams moving from broad platform familiarity toward disciplined production execution It is probably not the right place if you are looking for generic ecommerce thought leadership, vendor summaries, or high-level transformation language without implementation detail. ## Engineering Principles I Keep Returning To Some principles come up repeatedly in both my project work and the material I publish here. - Prefer maintainable architecture over clever customization. - Treat performance, SEO, accessibility, and security as system requirements, not afterthoughts. - Make failure modes visible early through observability, testing, and explicit rollout planning. - Keep release-readiness and rollback planning inside the engineering process rather than outside it. - Document trade-offs clearly enough that another team can understand why a decision was made. If a solution cannot be explained clearly, monitored in production, and changed without drama, it is not finished. ## Contact Rhino Inquisitor does not run a public contact form. If you want to reach me about a page, a technical topic, public tooling, or related work, use one of these public channels: - [LinkedIn](https://www.linkedin.com/in/thomas-theunen-10905680/) for direct professional contact about the site, speaking, or project work - [GitHub](https://github.com/taurgis/) for public tooling, experiments, and Salesforce Commerce Cloud developer work - [Trailblazer profile](https://www.salesforce.com/trailblazer/thomas-theunen) for Salesforce community contact and profile details If you are looking for published material first, the [blog](/posts/) and [topics](/category/) remain the quickest way to find the relevant article or resource. ## Start Here If you want to explore the technical side of the site, start with the [blog](/posts/) or browse [topics](/category/) to jump into a specific area. If you want the quick summary version: I work on Salesforce B2C Commerce problems where architecture quality, delivery discipline, and production safety all matter at the same time, and Rhino Inquisitor is where I write those lessons down. --- ## Privacy Policy Canonical URL: https://rhino-inquisitor.com/privacy-policy/ Markdown URL: https://rhino-inquisitor.com/privacy-policy/index.md Content type: page Published: 2022-02-25T21:16:19Z Updated: 2026-03-29T00:00:00Z Summary: Learn how Rhino Inquisitor handles basic request data, embedded media, and privacy questions on the current public Hugo site. Rhino Inquisitor is a public technical publishing site. The current Hugo site does not provide public user accounts, on-site comments, checkout flows, or newsletter sign-up forms. ## Who we are Our website address is [https://www.rhino-inquisitor.com/](/). ## Technical request data When you visit the site, the hosting platform and related infrastructure may process standard request data such as your IP address, browser or user-agent details, requested URL, referrer, and timestamp. This data is used to deliver the site, protect it, and troubleshoot operational issues. ## Public features on this site The public site does not currently offer: - visitor accounts - comment submission - author logins for public visitors - checkout, payment, or other transactional flows If those features are added later, this policy will be updated before they are published. ## Media Images published on the site are readable by any visitor. As with most websites, technical request data may still be processed by the hosting stack when images, stylesheets, scripts, or other assets are requested. ## Cookies The current public site does not intentionally set first-party login or comment cookies for visitors. Your browser, the hosting platform, or embedded third-party services may still use technical storage such as cookies or local storage when required to deliver content or when you interact with embedded media. For more detail about site-level cookie expectations, see the [Cookie Policy (EU)](/cookie-policy-eu/). ## Embedded and third-party content Some articles include embedded or linked third-party content such as YouTube videos, GitHub references, LinkedIn links, and external documentation. When you interact with those services, they may receive information such as your IP address, browser details, referrer, and interaction metadata under their own privacy policies. Where practical, Rhino Inquisitor uses privacy-friendlier embed patterns such as YouTube’s `youtube-nocookie.com` domain, but third-party providers may still process data once you start playback or leave this site. ## Analytics and consent tooling The current Hugo site does not publish the legacy Matomo opt-out widget that existed before migration, and it does not expose a public cookie-consent widget on the routes covered by this repository. If analytics, consent tooling, or additional visitor-facing tracking is added later, this policy and the cookie policy will be updated before rollout. ## Data retention and visitor rights This site does not maintain public visitor accounts or comment profiles. If you use one of the public contact links listed in the [About page contact section](/about/#contact), any personal data you choose to share is handled in that communication channel rather than through an on-site form. If you have a privacy question about content published here or want to raise a concern about a public page, use one of the public contact links listed in the [About page contact section](/about/#contact). ## Changes to this policy This page will be updated when the public site adds or removes visitor-facing features that change how personal data or browser storage is handled. --- ## PDF And Salesforce B2C Commerce Cloud Canonical URL: https://rhino-inquisitor.com/pdf-and-salesforce-commerce-cloud-b2c/ Markdown URL: https://rhino-inquisitor.com/pdf-and-salesforce-commerce-cloud-b2c/index.md Content type: article Published: 2022-02-24T13:18:00Z Updated: 2025-07-14T18:19:59Z Summary: Everyone knows PDF, right? It has been around for many years, and now we can use its full potential within Salesforce Commerce Cloud! Categories: Salesforce Commerce Cloud, Technical Tags: pdf, sfcc, technical ## Key Takeaways - Explains why server-side PDF generation is hard in SFCC because of the Rhino sandbox and restricted platform APIs - Shows jsPDF as a practical on-platform workaround for traditional SFRA-style implementations - Argues that composable storefronts should usually push PDF generation into external services or Node-based architecture So, you need to whip up some documents in Salesforce B2C Commerce (SFCC). Invoices, return labels, maybe a digital gift card that looks suspiciously like a treasure map. Sounds simple, right? _Wrong_. Welcome, brave developer, to one of SFCC’s most legendary challenges. For years, creating a simple PDF has felt like a Herculean task, not because of a flaw, but because of a core design philosophy that prioritises security above all else. Before you can claim your prize, you must first understand the battlefield. And today, that battlefield is split into two kingdoms: the traditional, monolithic-style Storefront Reference Architecture (SFRA) and the sleek, API-driven Composable Storefront. Your choice of kingdom will determine your path, your tools, and your strategy for victory. ## The Ghost in the Machine: Meet the Rhino Engine The heart of our challenge lies deep within the SFCC backend. This realm isn’t governed by Apex, the language of the core Salesforce empire, but by a special dialect of server-side JavaScript. This code is brought to life by the [Mozilla Rhino engine](https://en.wikipedia.org/wiki/Rhino_%5c%28JavaScript_engine%5c%29), a powerful translator that turns your JavaScript into Java bytecode. Now, you might think, “Java-based? Great! I’ll grab my favourite Java libraries and…"—hold it right there. That’s where the quest gets tricky. You see, developers are not given the keys to the whole Java kingdom. This isn’t an oversight; it’s a feature. To keep the multi-tenant SaaS environment safe and stable, SFCC puts your code in a “secure jail” or a sandboxed playground. This prevents custom code from running wild, accessing the server’s file system, or causing trouble for other tenants. It’s a cornerstone of the platform’s integrity, but it means that simple tasks like writing a file to disk or using a native PDF library are off-limits. You’re restricted to the official toolkit: the `dw.*` Script APIs. Even as the platform has learned new tricks, embracing modern JavaScript features, this fundamental rule remains. This is why creating anything more complex than a simple text file has historically been a headache. It’s a direct, intentional trade-off for a fortress-like, secure architecture. ## The solution As luck would have it, one of the “solutions” I had used until now was generating the PDF files client-side using [jsPDF](https://github.com/parallax/jsPDF) created by [Parallax](https://parall.ax/). Although the effort you have to make to create complex PDF files is relatively high, it gets the job done wonderfully. > **Thanks:** to [Oleg Sapishchuk](https://www.linkedin.com/in/osapishchuk/) for looking into this. It turns out that an older version of this plugin (with minor modifications) is compatible with the Rhino engine! After reading that message on the Unofficial Slack, I could not contain myself to try this out. And what do you know, only an hour later, I had a working prototype that would generate a PDF server-side and render it on the client-side on the fly! A few hours later, I found 15 minutes to spare and created a working job step using the same methodology to save it on the WebDAV rather than generate it on the fly. And not to worry, these examples, together with the library, are available [here to download](https://github.com/taurgis/salesforce-commerce-cloud-libraries) and try out yourself. ![An example of code using jsPDF and the resulting PDF preview on the right.](/pdf-and-salesforce-commerce-cloud-b2c/jspdf-example-c6dcb73e48_hu_dee8b5b45b806f13.webp) Figure 1: An example of code using jsPDF and the resulting PDF preview on the right ## With great power, comes great responsibility Now with all things, and especially when working with sensitive personal data, you need to think before you do. ### Legal In the digital marketplace, adherence to legal standards is not merely a suggestion but a strict requirement. For businesses operating in or selling to customers in France, for example, there is a legal obligation to retain all invoices for a period of **10 years**. This is a mandatory requirement that overrides other data deletion requests. You can find more information about this on the official French government website for businesses: [Factures : les règles à respecter](https://entreprendre.service-public.fr/vosdroits/F10029?lang=en). Just so you know, while this is a specific requirement for France, other countries and jurisdictions will have their own regulations regarding data and invoice retention. Therefore, any e-commerce business needs to consult with legal counsel to ensure full compliance with the laws of all regions in which they operate. This proactive approach to legal compliance will not only prevent potential fines and legal disputes but also build trust with your customers by demonstrating a commitment to lawful and ethical business practices. But what does this mean? - **On-The-Fly:** This is no longer an option since you are not persisting the generated invoice yourself. Therefore, it must be stored somewhere before being given to the consumer to comply with local legislation. - **Storing it on the WebDAV:** In the context of Commerce Cloud, this isn’t the ideal choice, as such information should be stored closer to your invoicing system. Retaining all generated invoices on B2C Commerce for ten years is excessive. The platform is made for commerce, not finance. Looking at the above statements, let something else take care of these invoices! But this will, again, depend on where you operate and what the rules of engagement are. ### Navigating the Privacy Maze (GDPR & Friends) The General Data Protection Regulation (GDPR) has fundamentally changed how businesses handle the personal data of EU citizens. A key component of GDPR is the “right to be forgotten,” which allows individuals to request the deletion of their personal data. However, this right is not absolute and must be balanced with other legal obligations. The legal requirement to retain invoices for 10 years, as mentioned in the previous section, presents a direct conflict with the right to be forgotten. In this scenario, the legal obligation to retain the invoice takes precedence over the individual’s request for data deletion. However, this does not mean that the personal data on the invoice can be kept indefinitely or used for other purposes. To navigate this, businesses should adopt the principle of **data minimisation** and consider **pseudonymization**. Here’s how this can be applied: - **Data Minimisation:** Only collect and retain the personal data that is strictly necessary for the transaction and for legal compliance. - **Pseudonymization:** After a certain period (for example, once the return window for an order has closed), you can pseudonymize the personal data on the invoice. This means replacing personally identifiable information (such as name, address, and contact details) with a non-identifiable token or code. The transactional data on the invoice (products purchased, price, etc.) remains, ensuring compliance with the 10-year retention law, while the customer’s personal data is protected. By implementing such a strategy, you can fulfil your legal obligations while still respecting the spirit of GDPR. It is also vital to be transparent with your customers. The privacy policy should clearly state your data retention policies, explaining why specific data is kept for extended periods and how you protect it. This transparency will not only ensure GDPR compliance but will also foster a relationship of trust and confidence with your customers. ## What about the Composable Storefront The [Composable Storefront](/the-move-from-sitegenesis-and-sfra-to-the-composable-storefront-as-a-developer/) is a whole new game. It’s less like a pre-built castle and more like an infinite set of high-tech Lego bricks. Your frontend is a slick, fast Progressive Web App (PWA), completely separate from the backend commerce engine. They talk to each other exclusively through APIs, like the Salesforce Commerce API (SCAPI) and OCAPI. This is a massive shift. Salesforce is betting big on this API-first, composable future. Trying to use an old-school, on-platform PDF hack in this new Lego world is like trying to glue your bricks together—it completely misses the point! For a Composable architecture, the PDF logic belongs _outside_ the core SFCC platform, living in your BFF or as its own microservice. It’s the modern, flexible, and correct way to build. And… now you have the complete power of Node.js at your fingertips in this headless environment! Third Party Service In a composable architecture, you don’t need to build the service yourself; opting for the best third-party solution is also a valid choice! ## Think before you do For PDF generation and all future quests, your success will be defined by your ability to find the best tool for the job and integrate it securely and efficiently. Sharpen your skills in Node.js, React, and API security. The challenge is no longer, “How can I force the platform to do this?” but rather, “What is the best service for this task, and how do I plug it into my architecture?” Master that, and you’ll be ready for any adventure that comes your way.