The kohler.ch webshop is entirely built on a headless architecture. This means the storefront (presentation layer) is separated from the backend (data layer) so that those applications can be developed and maintained separately.
The core
The e-commerce core of the HANS KOHLER AG webshop is built with Vendure, an open-source headless e-commerce platform built on top of the NestJS framework. Vendure provides everything needed to store and maintain products and customers, define a checkout process, handle and process orders, and much more.
It is built in a way that only defines a webshop's basic concepts, like providing models for products and collections, handling carts and prices and defining the default order process. Everything can easily be extended or customised to the needs of the current use case. The main goal of this approach is that developers don't have to fight the framework when it comes to implementing a shop's specific business requirements.
Vendure already provides most of the features needed to build a basic webshop. But as you might know, every business has at least one special case in its business processes, which is completely different from all the other shops out there. This could be an additional customer verification step, price calculation, or promotion logic. The good thing about Vendure is that if it doesn't provide a feature in the core or in one of the many plugins, there's always the possibility to implement a complete custom feature on top of the very solid and mature NestJS framework and integrate it in the shop.
What we built
To give you an idea of what can be built using Vendure, here are just a few of the many custom requirements we built for the HANS KOHLER AG webshop:
- Possibility to request a quote for a given cart with a simplified checkout process.
- Custom pricing logic with volume discounts where the volume is based on different units depending on the product. In addition, it offers the possibility to have specific prices for customers or customer groups.
- Complex promotion logic with customer-specific volume discounts on groups of products of the same type, as well as promotions that should be applied based on other promotions.
- Cuttable products (e.g. pipes) can be added to the cart via a custom configurator in the frontend and its own pricing system for cuts.
- Automatic synchronisation of products, prices, customers and orders with the Microsoft Dynamics 365-based ERP system HANS KOHLER AG uses.
- Payrexx integration for electronic payment.
- Order-specific shipping costs depending on the selected shipping address and method.
- Customised checkout flow, which allows the customers to add special shipping requirements for the order during checkout (e.g. when they would like to be notified by phone as soon as the shipping arrives).
The CMS
As explained above, Vendure only comes with the basic features used in an e-commerce project which also means that there are no CMS features included. To fulfil those requirements, we're using DatoCMS to create and edit content needed for the webshop, such as pages or blog posts.
DatoCMS is a headless CMS which runs as a SaaS solution. All the content created in the backend is accessible via a GraphQL API. As we wanted to mix data from the CMS in Vendure and vice-versa (e.g. selecting a contact person defined in DatoCMS on a product defined in Vendure), we proxied all the needed API endpoints from DatoCMS through custom GraphQL-endpoints on Vendure side. With this mechanism in place, we could directly resolve the content needed from DatoCMS inside the response from Vendure. For this reason, the frontend only needs to make one request to get all the data needed to render the current page, which results in faster response times for the customers.
As the webshop is multilingual, it was essential that the content could be easily translated. To achieve this, we use a plugin that automatically creates a translated version of a given page or blog post based on Deepl Translate to provide the editor with a starting point when translating content.
The frontend
We built the frontend with Svelte and SvelteKit for server-side rendering. The HANS KOHLER AG webshop was by far the most extensive application we built with this stack so far, and we couldn't be happier with our choice. During the whole project, we never faced the problem of a specific requirement not being easily solved due to a framework limitation. Which we, at some point, always faced using other frameworks such as Vue or React.
For the styling, we're using Tailwind CSS, and for the requests to the GraphQL API, we use Houdini, which, as the name already implies, does real magic when working with GraphQL APIs. For all defined queries and mutations, it generates Svelte stores that keep their state updated whenever something changes on the data they are holding, even if the change happens as a side effect of a mutation not directly related to the entity. Everything you do with the GraphQL API is type-checked against the schema of the endpoint. This for example, means that it's not possible to use a particular field in the template, which is not selected yet in the query or use them with the wrong type. With Houdini and SvelteKit, our application is entirely type-safe, and there is little to no chance that something will break during runtime.
All in all, we are really happy with our architectural choice. Vendure gave us such a strong and reliable basis to build the requirements used in this shop. With DatoCMS, we could quickly and easily create a system where editors can publish all the information about the products offered by HANS KOHLER AG. And finally, with Svelte and SvelteKit we were able to build an extensive frontend application which is still simple to maintain and makes it easy to build new features.