Choosing a CMS: Why Made People used Storyblok for Asket.com
Interview with Jonathan Selander from the digital agency Made People. Find out why e-commerce is moving away from suites like CommerceCloud, ShopifyPlus, EpiCommerce, Hybris and Magento, and why the editing experience is the most important part of a CMS.
Centra Implementation Case
Project: New global DTC website for slow fashion brand Asket
Centra Implementation Partner: Made People
Content Management System: Storyblok
In this interview, explore a cutting edge approach to e‑commerce that goes beyond static site generation, the mysteries of micro‑caching and handling bursts, and why all‑in‑one suites are becoming a thing of the past – all from Jonathan Selander, Co‑Founder and CTO from Made People, a brand‑focused e‑commerce agency. His team makes it look easy to build global e‑commerce sites like Asket.com.
Read on to find out:
How to do static sites without static site generators
Why JAMstack wasn’t the solution for Made People
How to properly motivate your team
Why e‑commerce is moving away from all‑in‑one suites like Magento
How to handle request bursts with advanced caching
Why the editing experience in a CMS is a crucial aspect of a good system
Why the fundamental rules of web development haven’t changed
Thanks for taking the time to talk to us, Jonathan. To start things off, may I ask what you personally do in your projects?
A little bit of everything except design, although sometimes I’m involved in that as well. I have a technical responsibility here, so I make sure that the choices devs make are the best for the client and the project.
There’s always a balance between making something for your own sake as a developer, and making a choice that’s best for the client. Sometimes you make smart cuts, sometimes you just prioritize the right way. I make sure that we have a good balance between building reusable, good, well‑performing things and delivering stuff that makes the client really happy.
And I still do a lot of hands‑on development, building anything from Kubernetes, DevOps stuff to frontend. I guess that’s what the term full‑stack was supposed to mean in the beginning.
I don’t want to just be a decision‑maker, because in order to help people understand you need to show what you mean. If you’re a chef, you can say how to make Béarnaise sauce and your team will do it. But it’s not until you do it your way, let them taste it, that they’ll go “ok, I know how it’s supposed to be”. It’s my way of showing by doing. All developers at Made People are very ambitious, and they deserve more than just words.
Words are famously ambiguous.
Yeah, it’s interesting, you have the world and all these influencers and opinion‑makers telling you stuff. But then you also have reality, which is what you actually need to conform to and work in. It’s like these two conflicting worlds, you have to face reality. Sometimes people find my approach a bit radical, but I’m just being realistic.
We live in a strange world, it’s radical to be realistic nowadays. But, let’s get into our CMS discussion. Made People is the first company I interviewed that does only e‑commerce projects, so I would love to talk about it in depth.
A lot of the old web agencies are shifting their focus to e‑commerce. We started Made People about 10 years ago. Before that, I went through different roads, anything from frontend development to managing server rooms. For example, I was once responsible for maintaining 100 servers, or doing Counter‑Strike server hosting - I built a cluster that could put the right server in the right place depending on the load and other conditions.
But then, I also did a lot of e‑commerce. At my first job, my test task was to build an entire e‑commerce site. It was so weird! But that was required to get the job, so I did it. I worked my ass off and built an entire e‑commerce site. I got the job, but I say it to show how immature the industry was at that time.
I worked there for a while, learned a lot, but had to quit after a while. In comes my old high school friend Anders. We started doing this web stuff together when we were 14. He was interested in programming but didn’t like doing it much. He worked a lot in Photoshop, and I got into programming. In high school we said that when we grow up, we’ll start a business together.
We kept in contact, had different jobs in the tech industry. About 10 years ago he started freelancing and kept convincing me to join him. He was a designer, but kept programming to meet the needs of his clients.
The first job we got was to build an e‑commerce site. At the time we weren’t specialists at it, we were doing traditional web development. We officially started Made People eight and a half years ago, and then we realized that e‑commerce was going to be our thing.
That’s what we love, the projects are fun, challenging, we can measure everything, we can see the effect of our own work, performance enhancements and whatnot.
Moving along that route we got more clients, and bigger clients. We always had control of the entire ecommerce tech stack, which got us a good reputation in terms of great performance. In those days, we did a lot of Magento projects. But we never considered ourselves a Magento agency. To be honest, we didn’t like Magento that much. But it kept giving us more work, so we said yes to the work.
Still, we never branded ourselves as a Magento agency, we knew there would be a day when people would stop using Magento. We knew that we can’t sit in their lap when that day comes, we can’t be narrow‑minded and disregard new technology.
With that in mind, some two years ago, we decided that we’ll consider Magento legacy, but also that we need to look wider and find new platforms. We changed our business and started working with a stack instead of a suite, and decided to learn everything possible about stacks.
Having worked with the Magento suite for so long, it was a bit difficult to get everybody on‑board at first. There was a transition period that still is kind of going on. Working with multiple services is a challenge – they all have different levels of API maturity, some are good, some not so good. We have to take that into consideration.
We like to say that the external system has to support us, instead us supporting the external system. And we also have our platform, the Dragon Slayer. If the old big suites are Dragons, our platform slays them with the help of microservices and APIs.
Dragon Slayer allows us to abstract the underlying platforms from the frontend, which is a huge part of streamlining development. We need to make sure that the API exposed to our frontends is supported by the different systems in our stack.
For example, if the e‑commerce platform doesn’t support discounts, then they don’t support us, because we support discounts.
As soon as we compromise our API we also compromise the frontend, which means we can’t streamline, we can’t grow, and in the end we get unhappy clients.
We’ve dealt with various shapes of tech on different markets over the years, which has given us extensive knowledge about the different types of bugs that APIs typically have. We've then solved them with our API that is exposed to the frontend.
We have to work that way, because I don’t want to sit in endless discussions talking about “how can I know if a color or label is translated or not”. There’s no time for that.
If we talk about “best of breed”, it’s a very wide concept. For me it means the best fit for your stack, and not “the best system on the market”. For example, if you have junior developers, choosing the most flexible and versatile API / system might not be best for you.
So we assume that if a system supports us, and our Dragon Slayer, then it can be part of “best of breed” for our client and their project. That’s how we try to work, we have Dragon Slayer as the back‑end, and we have to work API first.
The frontend doesn’t care if the back‑end is implemented or not. All it cares about is the right data format. Dragon Slayer handles the integration by tieing it together and transforming the data from all the systems in the stack.
Take the case of Centra. In Centra it’s great to do stuff on a display level, but if you zoom out one level above that, things become a bit difficult. We realized that clients need to enrich products with data from the CMS for every project. The back‑end needs to take data from Centra, from the CMS and put it into one chunk before sending it to the frontend.
We host this as an API client. When the API client gets an update, the frontend can do something new.
Is dragon slayer kind of like the operator in old American movies? “Operator, connect me with 27 Cherry Street”, but if the operator also translated the messages?
Kind of – if the operator took two messages, figured out how to translate them in a new and unique way, and then send it further.
Say that we use Yotpo for reviews. The operator needs to add that to the message so that the frontend can receive review data.
Image description: Yotpo is a tool not just for reviews, but a suite of solutions for DTC e‑commerce.
Then we can also make sure that we can cache our responses. When you put cache headers, for instance when you cache a GET request, then the query string has to be ordered. You’ll be polluting your cache If separate clients query with different parameters in a different order which gives you a new object for the same result.
With our client we can abstract that away, we can make sure that the site lives entirely on CDN. So even though the response is an aggregate of three or four systems, the aggregated result is cacheable, which is pretty cool. Then we can use micro‑caching to handle bursts, without needing a ‘clean cache’ button.
What does that mean?
It means that if you get 10,000 requests per second on your site, you can cache that result for 1 second. Every time the back‑end changes, everybody will get a new result after one second.
You can also handle 10,000 requests from the cache in one second. It’s a pretty cool way of managing bursts.
So, you want to make sure you can give clients updates without compromising the performance. Micro‑caching is a great way to achieve that.
If you have a second cache on all of your cacheable responses, then all of them support micro‑caching, and all of them will handle any bursts. Everything will be automatically served from cache, you don’t need a purge‑cache button as it’s only one second old, and it’s invalid after one second.
Then you also have stale‑while‑revalidate. The cache proxy will continue serving old cache, even though it’s invalid, and it will only send one request to the back‑end to fetch new data.
It acts like a big wall and sends the data to all 10,000 visitors. Then one little request goes out to get new data, and as soon as the new data is in the cache, all visitors will see the new stuff.
And if there’s no new data?
As far as the cache is concerned, it will have new data even though nothing changed in the back‑end. It’s a pretty cool way of solving it! Your site can live on CDN which gives you super offloaded servers, super high performance and you don’t need to worry about cleaning cache and all that.
What about your CMS?
It’s extremely important that it’s focused around the editor experience, and frontend development - making sure that it’s rapid. We looked at Prismic, Contentful, Storyblok.
Video description: Visual editor in Storyblok featuring the brand ASKET. You can sign up for a demo on the Storyblok website, it’s a quick sign‑up and you’ll be testing it in about 2 minutes.
We’ve been doing a lot with Storyblok because it has a great editor experience, you can work very rapidly in the frontend. We wanted a system where you can see what you’re doing while you’re doing it.
Another important thing is translations and publishing to different channels. This is where Storyblok falls short. It’s kind of a compromise between choosing a great editor experience, or having good support for different channels and languages. But even though it falls short, it can still be done.
The great part is that it’s extremely easy to build your own components that do whatever you want, get any custom data into it and build your content using any type of external information - it’s all very easy.
So it’s great for content‑driven brands, which… well, all brands are content‑driven now, right?
All brands are, but most of them are stuck with a limited experience. To go back to Magento, some say it’s difficult to use because it’s complex. To me, it’s difficult because it’s not that great, and built in a limiting way. For example, getting a discounted price requires modifying about 10 files - that’s not good design.
I think that this is what the market is realizing at this point in time. I don’t need a suite, I can build the kind of system I need from the ground up, using different services to speed up development time.
As long as I don’t need to worry about the really complicated backend parts in every project, everything will be great, which I think is also the reason for the “headless revolution”.
Were you an early adopter of headless, or were you skeptical?
I was skeptical. In retrospect, I’m a little ashamed of that. Now I’m thinking that I should be more adventurous. We’re starting to do this thing where we try things first, and then make decisions.
If you have a discussion, decision‑makers tend to say “no” to things prematurely. Now, instead of discussing, I want to try things. Then you can make informed decisions.
A good example of that is how it was with JAMstack, which ended up being statically generated data. I realized that my site can live on CDN, but it doesn’t benefit from being statically generated.
There’s just a long build time, and every deployment has old data. Then you need to do API calls anyways, because you don’t have it in your generated file. If I hadn't tried JAMstack, I wouldn’t have known. Now I know that I don’t want to put effort into Gatsby, it wouldn’t help our stack.
Interesting! Can you expand on this?
If my site has 100,000 users, all content comes from cache and API calls. Everything lives on CDN. Everything is returned within 10 milliseconds. How would I benefit from static generation?
Especially when the CDN always grabs new content after 10 minutes. That’s basically like generating a full Gatsby site every 10 minutes.
Well yeah, your site lives on the CDN, so it IS static.
Exactly! And I can decide how old the data will be, if I want it to be 10 seconds old, it’s fine, no problem. There’s always fresh data from the back‑end. And I can always deploy a new version of the app.
The data lives on CDN, the app lives on CDN. It’s always one minute old. I don’t have a need for Gatsby.
For me, the issue with doing only static generation is that you have to re‑render the site in every new link, everything gets jumpy and weird.
Also, how do you handle discounts in stock? Do you have to re‑generate the site? Do you need to generate every time that changes, or do you do API calls anyway to get the information?
Is that a crucial aspect?
I think so. If you’re doing static and API calls anyways, why are you doing static in the first place? I don’t see the benefit.
Instead, I'd rather make sure that the first call and the first response is fast. And make sure all other responses are cacheable. This way you get a super‑fast site.
I think the main problem with static is that it’s introducing a new layer of cache with no real purpose.
Does the fact that you do only e‑commerce influence your thinking?
Yeah. JAMstack might be good for other sites, although I probably wouldn’t use it in other projects either. Maybe something will evolve out of this that I will like.
I get the feeling that the fundamental rules of building sites have been the same for years, or maybe it’s not true?
I think it’s true. That’s what you realize when you stop using a suite. You realize that you’re a web developer first, and you’re good at that, so why hide it behind a suite like Magento?
My own reputation is that I’m great at Magento, and even I started saying that it’s not great. If it’s true that I’m so great at Magento, why was I completely incapable of estimating anything? After building with it for 10 years, why can’t I estimate stuff?
It was hard to meet client requirements, because a Magento project is kind of like navigating in the twilight zone - there are too many unknowns.
With every request from the client, you have to investigate. Developers get really stressed because they have to give an answer they can’t give, and they know it’s probably not going to be the right answer. How should you solve this? Find as much info as you can, even though it will never be enough?
Another issue with this is that developers are rarely trained in auditing systems. It’s a separate skill that you have to learn. So a lot of time, they just do something random, look in the code, and tell PMs that fixing an issue will take two weeks.
After they start working, it turns out they were wrong. It’s important to realize that auditing code is a separate skill that you have to learn, you won’t be great at it if you haven’t trained.
In e‑commerce projects, the main goal is to sell stuff fast, never have downtime, have a responsive site. Why not just use one tech stack for all projects?
Well, that’s exactly what Dragon Slayer is about! One stack, one set of terms, that’s exactly why we're building this thing.
Dragon Slayer means that the frontend developers only use one type of API, regardless of what’s behind. They don’t care what happens in the back‑end. It’s a very good way of streamlining.
In the back‑end, we have requirements for external systems, like I said before, so that the back‑end can work with one tech stack. The Dragon Slayer back‑end is built in Kotlin. The whole stack runs on Kubernetes. Then we have the frontend, which is freedom of choice – we're currently using a lot of VUE.
From our point of view, we have one stack. But we're more than happy to introduce a news system as long as it fits into the requirements which are that we have the port for it, and that it goes out to the frontend through the same API that all other systems go.
So Dragon Slayer contains all of the systems?
Yeah, kind of. Dragon Slayer runs in the cloud with all the things it needs. You could say it’s kind of a middleware thing.
For me, it’s about streamlining my organization. Making sure we can deliver really good stuff with great performance, and make clients happy. It’s not just about having a cool back‑end.
Do you plan on releasing Dragon Slayer?
We’re definitely figuring out how to sell it as a SaaS or in a similar model.
All of the different systems we use have their integrations, that’s how it is. The difference is that Dragon Slayer is entirely for an e‑commerce frontend.
It makes sure that anything that wants to be an e‑commerce frontend, independent of all other systems behind it, can be that. We can build entire frontends independent from the back‑end.
So if a new client comes to us, they can build a frontend using any other client’s QA data, stage data and mock data. Then, when everything is caught up, the migrations are done, we just point that Dragon Slayer instance to the correct Centra instance – and voila, we have real data and everything just works.
We wouldn’t be able to do it without thinking API‑first. API‑first is all about agreeing on the format and on data flows before you build anything. As long as you build API‑first, anybody can do this.
Were you early on the API revolution? I guess it started before you got into development, about the year 2000.
Well, the funny thing is that around eight years ago, me and Daniel (one of our first back‑end developers) said to each other - why not just build an e‑commerce API that’s just an API? That would be so cool!
But we didn’t, because we needed to stay profitable, and that meant doing Magento projects.
The market probably wasn’t ready for it then, anyways?
Yeah, but it would be extremely ready for it now, had we just stuck to it.
What would you say is the average level of tech knowledge with e‑commerce clients?
It varies a lot. Most people have an idea of how things work together, however, none of them are back‑end developers.
That’s one issue that happened in Magento projects. With Magento, there was a requirement of back‑end knowledge on the client‑side.
Why should it be like that? It’s just not right, they should be able to update their system without learning a bunch of complex things.
Most clients understand systems, understand that some things are difficult. But all in all, they want to grow their business and offer a great digital experience to their customers.
Ultimately, we’ve always been in it for the long run, and I think that’s why we’ve been growing so slowly. We always put happy clients and quality production first. We’ve only now added two salespeople to our team, and started rearranging the business a little bit.
We care, and always will care about the end result. We’re very picky about it. It’s easy to destroy a business by overselling and scaling too fast.