Money, money, money. Some say it's the biggest problem of humanity, some say it's the solution to all our problems, but either way, even we frontend developers have to think about it once in a while.
Most devs would build features and be done with it. An excellent app people love to use without excessive code that doesn't add anything to the user experience.
Like so often, reality rejects a brilliant idea; and in the end, we have to make money.
What to do if you want to add payment features to sell your latest ebook or a subscription to your shiny new SaaS, but you don't know too much about backends?
When frontend devs need saving, Snipcart delivers!
Snipcart is an all-in-one stop shop for web devs to get a shop up and running in no-time.
They integrate with all the popular payment gateways, like Stripe, PayPal, and Square, and take 2% of your prices.
As I said before, Snipcart offers an HTML API. The idea is that you include CSS and JS into your HTML file, and this allows you to drop
data-* attributes and classes on your tags to make them interactive.
Want to create an "add to cart" button? Just give it the class
snipcart-add-item and set some
data-item-* attributes, and it's done!
Need a checkout button? Class
snippcart-checkout it is!
As if this isn't awesome enough already, Snipcart doesn't require you to run around their dashboard and create products beforehand!
You code everything in HTML, and when a user buys something, the Snipcart service will validate the user's request with the actual data from your website so that you won't get bamboozled. Yes, they use your website directly to validate, so no extra WebHooks API required!
With their WebHook support, you can extend the integration even further to add some custom backend logic.
For small FaaS scripts, I can recommend Cloudflare Workers, they don't require an extra API Gateway and have a JS API familiar to frontend devs. I wrote about them here
The only non-service thing I made money within my life was a book, so let's look at how we could build a simple book shop with Snipcart!
The first step is to go on the Snipcart site and create an account. It just takes a few clicks and only requires an E-Mail. They don't even want a credit card or something.
The Snipcart setup only takes three steps.
- Include CSS
- Include JS
- Set the API key
The setup code would look like that:
<!doctype html> <title>My E-Book Shop</title> <link rel="stylesheet" href="https://cdn.snipcart.com/themes/v3.0.16/default/snipcart.css"> <h1>My E-Book Shop</h1> <br hidden id="snipcart" data-api-key="<API_KEY>"> <script src="https://cdn.snipcart.com/themes/v3.0.16/default/snipcart.js"></script>
All of the interaction between HTML and the Snipcart SKD happens via HTML attributes. Classes, IDs, and data attributes.
Now you need to replace
<API_KEY> with your key, which you can find in the Snipcart dashboard, and you're ready to go.
To add some books, you need to add HTML elements that you want to act as an "add to cart" button and sprinkle them with a
snipcart-add-item class and some
No need to go to the Snipcart dashboard and create the product before you can add it.
The HTML for a book could look like this:
<h2>Learn Tech 1</h2> <img src="https://placeimg.com/200/300/tech" /> <p>$19.99</p> <button class="snipcart-add-item" data-item-id="learn-tech-1" data-item-price="19.99" data-item-url="/" data-item-image="https://placeimg.com/200/300/tech" data-item-name="Learn Tech 1" > Add to cart! </button>
<button> element, all other elements are visual only and thus optional.
The ID, price, name, and URL attributes are required.
The URL attribute is unique here; it's used for the validation done by the Snipcart service. This URL will be used to find the HTML on your site to check if it contains that price. In this case I used
/, because I will write everything in an
index.html file later, that will be hosted at the root of a domain.
The image attribute is optional and will be used to display a product image inside the actual cart view.
Other attributes can be found here.
To add a checkout, you have to add a
snipcart-checkout class to a button, that's it.
Let's look at the complete
index.html for our book shop:
<!DOCTYPE html> <title>My E-Book Shop</title> <link rel="stylesheet" href="https://cdn.snipcart.com/themes/v3.0.16/default/snipcart.css" /> <h1>My E-Book Shop</h1> <button class="snipcart-checkout">Click here to checkout</button> <h2>Learn Tech 1</h2> <img src="https://placeimg.com/200/300/tech" /> <p>$19.99</p> <button class="snipcart-add-item" data-item-id="learn-tech-1" data-item-price="19.99" data-item-url="/" data-item-image="https://placeimg.com/200/300/tech" data-item-name="Learn Tech 1" > Add to cart </button> <hr /> <h2>Learn Tech 2</h2> <img src="https://placeimg.com/200/300/arch" /> <p>$29.99</p> <button class="snipcart-add-item" data-item-id="learn-tech-2" data-item-price="29.99" data-item-url="/" data-item-image="https://placeimg.com/200/300/arch" data-item-name="Learn Tech 2" > Add to cart </button> <h2>Learn Tech 3</h2> <img src="https://placeimg.com/200/300/people" /> <p>$39.99</p> <button class="snipcart-add-item" data-item-id="learn-tech-3" data-item-price="39.99" data-item-url="/" data-item-image="https://placeimg.com/200/300/people" data-item-name="Learn Tech 3" > Add to cart </button> <br hidden id="snipcart" data-api-key="<API_KEY>"/> <script src="https://cdn.snipcart.com/themes/v3.0.16/default/snipcart.js"></script>
This is the whole code needed for a shop. That's it. It feels almost ridiculous. What is this? 60 LoC with line breaks, and most of them don't have anything to do with Snipcart. I'm awestruck.
The shop is just a HTML page, but it uses CORS to interact with the Snipcart API directly through the browser, so we need to access it through a webserver.
I prefer to use the
http-server package from NPM for this. Go into the directory that holds your
index.html and run the following command:
$ npx http-server --port=8888
Now you can access the file at http://localhost:8888/
I like the idea of an HTML SDK very much. You can generate the Snipcart HTML elements alongside your other HTML and don't have to think much about it. This way, it even works with JAMStack pages.