Improve security and user management with our Authentication API.

Product

Composable commerce with micro frontends.

December 23, 2022 Filippo Conforti

During the last few years, headless architectures have gained a lot of traction and are now becoming the new standard for brands looking to build exceptional customer experiences. By separating the frontend layer from the backend, headless commerce promises faster, more scalable, and more secure websites. However, headless backends are still monoliths, and monolithic architectures lack flexibility. Thus, headless commerce has evolved into composable commerce, a design pattern that breaks the backend into several specialized business capabilities. Each capability is provided by one or more microservices (MS), typically orchestrated by a Backend For Frontend (BFF).

Due to their specialization, microservices are more powerful than their monolithic counterparts and offer more flexibility to build new features, and as a result, the customer experience becomes more optimized. Even so, the frontend also remains monolithic, minimizing the benefits of microservices. At scale, making changes to a website and evolving the customer experience is not as easy as it should be. There is a tight coupling between everything, and every upgrade forces developers to re-deploy the entire application.

Enter micro frontends, an architecture style that extends the composable nature of microservices to the user interface. With micro frontends (MFEs), a website or web app is viewed as a collection of self-contained features that are owned by independent cross-functional teams. Each team develops the entire sub-product end-to-end, from the database to the user interface, with a product team putting everything together and composing the desired experience.

Benefits of micro frontends

Micro frontends represent the state of the art of modern web development. It's as if microservices and Jamstack met, creating the perfect match. This architectural style has many benefits (and some challenges) which are outlined below.

1. Faster time to market

Unlike monolithic websites, micro frontends are individually deployable applications that can be managed by autonomous teams. By eliminating team dependencies, the release management cycle is simplified. This makes shipping new features easier and faster. For example, the product discovery team can make changes to product listings without depending on the commerce team, which handles inventory, price lists, and promotions. With this level of flexibility, brands can deliver faster time to market and have a huge competitive advantage over those who stay stuck in their traditional workflows.

2. Simpler code bases

By definition, micro frontend code bases are smaller, which makes them easier to develop, maintain, and test. Since each micro frontend can be developed separately from the others, there is less chance of unintentional and inappropriate coupling between components, resulting in cleaner code and separation of concerns.

3. Better error isolation

Decoupled code bases and independent dev teams also make debugging much easier and faster. As an example, if a product image goes wrong, the media team is responsible for fixing that issue. Alternatively, if a promotion fails to trigger at the right time, it is clearly the commerce team's responsibility. Bug fixing on one functionality does not affect the rest of the website, which can keep being deployed independently.

4. Ease of implementation

Micro frontends are reusable apps that can be embedded in multiple websites, eliminating the need to reinvent the wheel time and again. You can think of micro frontends as a collection of reusable micro experiences that you can share across different projects. A great example would be embedding the same shopping cart app into multiple websites, which can be styled according to each site’s stylesheet while keeping the same behavior.

5. No framework lock-in

It is possible to develop micro frontends using a variety of technologies and frameworks and combine them into one digital product. Each team can pick the programming language they prefer. You can use React, Vue.js, and Svelte to build the same website. Even though minimizing the number of technologies and sharing common patterns is a good practice for organizations, this framework-agnostic approach future-proofs your stack and gives developers the freedom to always try new things without being tied to a specific vendor.

6. Incremental upgrades

It is common for brands to feel forced into complete overhauls, especially when it comes to legacy code that’s barely functional. Nevertheless, big-bang rewrites are rarely the best choice. We'd rather strangle the old application piece by piece, extracting micro frontends from it until either the monolith "dies" or becomes just another micro frontend with a specialized focus.

The possibility of progressing incrementally reduces the risk of modernization and guarantees the business continuity you need. Starting with one micro frontend will give you immediate results. When one team has successfully deployed a feature without any significant changes to the old world, other teams will want to do the same and join the new world. As described in the Ship of Theseus thought exercise, after some iterations the original platform will no longer be the same "ship".

How about the challenges?

As with any technology, micro frontend architecture has its own challenges, with cross-application communication being one of them. Generally, we suggest that micro frontends communicate as little as possible, since this often reintroduces the type of inappropriate coupling that we're hoping to prevent.

However, cross-app communication is often necessary when building any site. The thing to keep in mind is preserving independence between micro frontends; just as a shared database across microservices is a bad practice, micro frontends also shouldn’t share any state. Instead, they should communicate by exchanging messages or events with each other.

Another factor that needs to be considered is visual consistency. It's essential to develop a library of shared, reusable UI components so that everyone uses the same design system and the website looks consistent.

A few other pitfalls include performance optimization, testing, and the lack of best practices in the fields. Generally speaking, micro frontends require the same development discipline as monolithic code bases. Micro frontends are not foolproof and do not fix the issues of lax code, but they do set developers up for success by making it easier to make better, more sustainable decisions when building a site.

Micro frontends in action

To demonstrate how micro frontends work, we'll use Commerce Layer to turn this blog post into a shoppable page. Specifically, we will use our new drop-in library and micro frontends to embed shopping cart and checkout functionality with just some HTML markup.

Configuration

As the first step, we need to include our drop-in library and configure an API client. We'll connect an existing drop-in-js organization and put a market in scope, which will determine the current price list, active promotions, shipping options, payment gateways, and more. The returnUrl parameter will be used to populate the "back to cart" link in the checkout page.

<script type="module" src="https://cdn.jsdelivr.net/npm/@commercelayer/drop-in.js@2.1.0/dist/drop-in/drop-in.esm.js"></script>

<script>
	(function() {
    window.commercelayerConfig = {
      clientId: 'kuSKPbeKbU9LG9LjndzieKWRcfiXFuEfO0OYHXKH9J8',
      slug: 'drop-in-js',
      scope: 'market:11709',
      returnUrl: 'https://commercelayer.io/blog/composable-commerce-with-micro-frontends'
    }
  }());
</script>

Displaying a price

Imagine you are showcasing a product and would like to display its price. All you have to do is integrate the following HTML elements in your page:

<cl-price code="BACKPACKFFFFFF000000XXXX">
  <cl-price-amount type="price"></cl-price-amount>
</cl-price>

Using this SKU code, the drop-in library will fetch the current price from Commerce Layer, as defined in the current market's price list. The price will then be used to populate the HTML element as follows:

← This price comes from Commerce Layer!

Displaying an availability message

The following code snippet displays whether a SKU is available or not, along with its delivery lead time when available:

<cl-availability code="BACKPACKFFFFFF000000XXXX">
  <cl-availability-status type="available">
    <span style="color: green;">Available</span>
    &mdash; ready to be shipped in
		<cl-availability-info type="min-days"></cl-availability-info> to
		<cl-availability-info type="max-days"></cl-availability-info>
		days
  </cl-availability-status>
  <cl-availability-status type="unavailable" style="color: red;">
    Out of stock
  </cl-availability-status>
</cl-availability>

Using this element, the drop-in library will retrieve availability information for the related SKU code, based on the current market's inventory model:

Available — ready to be shipped in to days Out of stock

Embedding a shopping cart

A shopping cart can be embedded in several ways. One of those is to include a mini cart experience, such as a link that opens a preview of the cart with a nice slide-in effect. To enable this option, we can include a stylesheet that takes care of the required CSS animations:

<link href="https://cdn.jsdelivr.net/npm/@commercelayer/drop-in.js@2.1.0/dist/drop-in/minicart.css" rel="stylesheet" />

The next step is to embed a cart link and a counter that shows the number of items in the shopping cart:

<cl-cart-link>
	<span>Your shopping cart</span> (<cl-cart-count></cl-cart-count>)
  <cl-cart open-on-add="true"></cl-cart>
</cl-cart-link>

Here is what it looks like. To open the cart preview, click the cart link below. The counter (in brackets) will be updated as you add an item to the cart or change its quantity:

Your shopping cart ()

Adding a product to shopping cart

If the SKU is available, it is possible to add it to the shopping cart. The following element renders an add to cart link:

<cl-add-to-cart code="BACKPACKFFFFFF000000XXXX">
  Add to shopping cart
</cl-add-to-cart>

By clicking the link below, you'll add the SKU to the shopping cart. The minicart will open, showing the new line item, and the cart counter in the previous section will be incremented:

Add to shopping cart

Completing a purchase

The last step is to click the checkout button within the cart preview or by embedding a checkout link anywhere in your page with the simple snippet below:

<cl-checkout-link target="_blank">
  Proceed to checkout
</cl-checkout-link>

Clicking the checkout link opens our hosted checkout application, a fully customizable micro frontend allowing you to purchase the featured SKU in just a few clicks:

Proceed to checkout

It's easy to get started!

Commerce Layer micro frontends are standard web components that can be injected into any webpage, with no coding required.

If you are moving from a monolithic platform such as Shopify, Magento, Hybris, or Salesforce Commerce Cloud, you can progress incrementally, starting by replacing your platform's transactional engine. Due to the client-side nature of our micro frontends, you can integrate them directly into existing websites using tools such as Google Tag Manager, Google Optimize, or Optimizely, without even touching your platform's code.

Additionally, you can consider taking advantage of this new approach outside of your primary ecommerce site. A use case could be to add ecommerce functionality to your customer service app or any microsite. No matter where you start, you should experiment with this new architecture as soon as you can. As your partner, Commerce Layer will be there to offer assistance and support.