An alternative to a large scale Content Management Systems, for smaller projects.
JAM stack is a Content Management System for smaller projects. It focuses on creating websites that make use of external API’s. It is fast, easily scalable, has better developer experience and is more secure. This is a concept that has recently been gaining momentum.
Let’s take a look at an example of someone who might benefit from using JAM Stack to develop their website.
John is a simple guy. He is an owner of a small, new age, tropical fruit smoothie business, has two kids, a loving wife and a Golden Retriever.
One thing John doesn’t have, is a reliable, fast and secure website, where he can manage content all by himself! Since he is a man of success, he finds Bob, a web developer, who will create such a website for him.
They get together and discuss how it should work. John wants to be able to add new products to his website and add updates about his shop. He also needs a page with a form, for people to be able to contact him.
John and Bob agree that Wordpress, as a Content Management System, would fulfill those needs.
Long story short, a month later, John had a website that was hacked by a Chinese Bot after two days. Also, his wife left him.
Bob has nightmares about choosing plugins till this day…
Okay…Maybe this story is a bit exaggerated, but we’ve all heard complaints about Wordpress. We can look at other popular CMS systems, such as Joomla or Drupal and all of them have flaws, and seem to complex for a small business website.
In a perfect world, John would have a website that isn’t a monolith with dynamically generated content backed by a CMS. It would be a light-weight, deployed once per necessary update, and could be easily edited with a tool that isn’t used for everything (just wait till they run a space-shuttle on Wordpress…).
The JAM Stack
Markup — Templated markup should be prebuilt at deploy time, usually using a site generator for content sites, or a build tool for web apps.
This is the theory. But what about implementation? Well, we are already surrounded by tools that implement the JAM stack. We know them as Static Site Generators e.g. Jekyll, Gatsby, Hexo, and many others. You can find a large amount of free and paid projects on staticgen.com website, kindly provided by the team at Netlify.
You can also create your own website that is generated from JSON or markdown files, or even use an existing service that provides you with a CMS that serves the content through an API. Those are called Headless Content Management Systems.
Having a website is fun and all, but how would a non-technical person edit content there? As always, there are multiple solutions available. One could manage it on the coders end, and charge a client $200 per button update. But that’s not too professional.
A better approach would be to choose one of the many available CMS systems, that are suited to go with a Static Site Generator of choice. There are two groups of Headless CMS-es.
API Driven CMS — this is the more popular one. It’s a CMS that allows you to create an API for your website, without coding. It doesn’t require a static site generator to work. With this approach, we will have to send asynchronous requests to our API on each website visit, to always serve fresh content. The most popular projects in this group are Contentful ($) or Strapi (FREE)
Git-Based CMS — they work as a Graphical User Interface for GIT. You can write posts through an admin panel, and under the hood, after saving, the CMS will commit your post to the code repository, and trigger a re-deploy of your website. Their advantage over API Driven CMS, is that you don’t have to spend additional time waiting for an AJAX response of your site’s main content. The most popular projects in this group are Netlify CMS (pair with any static site generator) and Prose (works only with Jekyll).
You can find many more headless CMS-es on headlesscms.org website.
There is a way to combine the two CMS types, and source the website data to a Static Site Generator, once, on build time. It would require some custom coding and API Driven CMS to have webhooks (e.g. Contentful. Strapi lacks this feature for now) that can trigger a rebuild of the website to our server (e.g. Netlify). There is an interesting article describing this implementation.
Congrats! Now you know the basics of Jam Stack!
Does it Work?
Only one way to find out! I decided to create a tropical smoothie business website for our imaginary friend John. I went with Netlify CMS, hosted it on their platform and later added Netlify Forms and lambda functions.
If you’re not interested in Netlify CMS, you can go straight to the comments, and leave recommendations for other awesome JAM stack based projects!
To better understand, and test its limits, I created a simple website for an imaginary smoothie shop, called “Smoothielicious”! It uses GatsbyJS as a static site generator. All the code is open source, and it might be useful, because I won’t go deep into details.
To view the project, you can visit the Smoothielicious Website, or check out the project’s GitHub repository.
It’s a typical website. There is a listing of smoothies, a few blog posts below and a contact form. The magic happens when we want to update info on the website. Admin panel is located on
/admin route, and log-in requires authentication. It can be set-up to use multiple popular services e.g. Gmail, GitHub or Netlify Identity. I went for the last one. It allows you to specify user roles and manage everything from the Netlify dashboard. If we access the admin panel we see something like this:
We can see multiple collections, such as “blog”, “pages” and “products”, that we are able to define in
config.yml. Netlify-CMS reads to get information about data structures on our pages (e.g. frontmatter). Below I attached a gist of my
config.yml file for this project. I have three collections: blog, products and pages. The first two have a
create flag set to
true which allows to add them. ”Pages” on the other hand are hard-coded, and only fields inside them are editable. I highly recommend the documentation, for more information about available widget (fields) types.
To edit the page of a single collection item (in this case, a “product”) is quite straightforward. All the fields widgets specified in our collection type are listed one under another. On the right, there is a preview of what the page will look like. In my case, I didn’t add any styling, but it’s possible to add it so that the preview will show the actual output of our post.
After we change something and save the page, the system triggers re-deploy, and after a few minutes we can see an updated version online. This is one of the downsides of this technology. But often, we don’t care if our product goes live instantly or after a minute, so we can still use it and be happy.
At this point you have a website that can be managed easily through the CMS but is way more secure than similar pages based on other systems. This is really great but it has a lot of limitations. What about managing forms or processing payments?
We can integrate some king of Software as a Service (SaaS) platform to help us with that, but since our forms are really simple, I will use a tool, that comes with Netlify, that’s called Netlify Forms. How does it work?
Unleash the Netlify Built in Forms
Let’s make use of Netlify built in forms! Since our website is small, we won’t need a ton of functionality. All we need to do is save a form submission, so that we can later contact our client.
Form handling is really simple. I recommend starting with the documentation and follow the steps, but for the lazy people, basically all you need to do is to add a
netlify attribute to the form on your webiste, e.g.
<form method="POST" name="contact" netlify>...</form>
On next site deploy, Netlify will detect a form, and listen for any new submissions.
Dynamically rendered websites, such as the one I made, need to have the form added as static html. To fix that, we need to add a hidden form that won’t be actually used, with the same fields as our real form. The only catch, is that the first (hidden form), needs to have name and Netlify parameters, and the second (rendered) one doesn’t have a name, but needs to have a hidden input field inside, that will tell Netlify, to save the submission to a detected form. To clarify, normally your form would look like this:
<form action="/success/" name="Contact" method="POST" netlify>
And when we render our form dynamically we will have one hidden form that looks just like the one above, and our dynamically rendered form will look as follows:
<form action="/success/" method="POST">
<input type="hidden" name="form-name" value="Contact">
It took me a couple of hours until I found out why my form was not submitting correctly, so I hope you won’t have the same problems as I did.
Contact Form Auto-Response
Auto-response to emails, is a great feature to have. It informs the user that his form submission was successful, and we will contact him in no time. Netlify doesn’t have any built-in support for that, but we can easily add it. There are two different routes we can take here. One is to use a SaaS platform, that allows sending e-mails and integrates easily with Netlify. The second one is to write a lambda function that will send the auto-response email. Recently Netlify added support for lambda functions, so it’s not a problem.
In both cases we will make use of contact form hooks. When somebody submits a contact form on the page, Netlify will send a POST request to all endpoints that listen for this event. We can add them in our websites Netlify panel, in
settings > forms > form notifications tab.
Integrating Zapier is really easy. It took me about 30 minutes, only because it was my first time using this tool. Everything worked perfectly, but there was one catch. Zapier doesn’t have a free plan, after the trial period.
Because I’m cheap, I thought, I will migrate to the second solution, lambda function. It wasn’t as easy as Zapier integration, but after a few hours of thinking I went crazy, I found all the bugs and the lambda function also works like a charm. The whole solution for lambda development environment set up is available in smoothielicious project repo. In the mailer lambda function I used the
nodemailer package, and created a simple html email template with MJML, to make it look a bit better.
And voila! No need for any backend mess here. A simple function will do.
Since it worked so well I wanted to go a bit further and see if it’s possible to create a lambda function that will communicate with a database. A good way to test it, would be to save the number of page visits.
So that’s exactly what I did. I created an account on mLab, a mongoDB Database-as-a-Service provider. I probably won’t exceed the free tier limit of 500mb of storage, since I literally save and increment a single number. Below is the lambda function code for connecting to the db and incrementing the counter. I created a single endpoint
add-page-visit that updates the database on mLab, and returns the current count of page visits.
After deploying the function is available at https://site.netlify.com/.netlify/add-page-visit, so the endpoint is same as the file name, but without the .js extension. I also added a display of current page visits on the top of the page, so that everybody can see it.
What About pricing?
In this project I heavily rely on Netlify forms and lambda functions. They are free up to a certain point. The general rule, is that you pay as you go, which means that the amount you pay can vary depending on your site usage, but you can also go for a monthly plan, that raises the limits and unlocks some additional features. The payments count per billing period, which is 1 month.
Netlify forms are free up to 100 form submissions and/or 10mb of file uploads per month. If you exceed this limit, you will pay $9 per package of 500 form submissions and 500mb storage. There is also a Forms PRO plan, that costs $20 per month, and allows for 1000 form submissions and 1GB of storage.
Functions are free up to 125,000 requests and/or 100 hours of runtime per month. If you exceed this limit, you will pay $19 per package of 500,000 requests and 500 hours of runtime. You can also upgrade to a Functions PRO plan, that costs $25 and allows for 2,000,000 requests per month and 1,000 hours of runtime per month.
It’s important to know that If any of those limits are exceeded, including the free ones, Netlify will auto scale your setup, and charge you, and there is no way to block it. The only way is to stop using a feature when close to a limit.
The pricing is quite reasonable, and you pay only for the amount of things you need, which is really neat, if you don’t really know what site traffic to expect.
Is JAM stack the future? Should we rebuild the whole web to use it? Or is it just another imperfect technology that will not be useful?
In my opinion it’s a tool that is extremely useful, but it has its own niche. It can’t be used everywhere, but its likely to be a better alternative to traditional Content Management Systems on many occasions. It’s up to us, the developers, to decide when should we use it.