Integrate Afosto Storefront into your Afosto CMS webshop

You can also use our new storefront in your existing Afosto webshop. This requires some modifications to your shop's template and the installation of a plugin. In this guide, we will walk you through the steps to connect your shop to the Afosto Storefront.

Creating a Storefront Sales Channel

The first step is to create a Storefront sales channel. Setting up a sales channel determines how your online store communicates with the Afosto Storefront. The configuration includes details such as the name of your storefront, branding, payment and shipping methods, and the default language.

In the next step, enter the required information and create your sales channel.

Creating Storefront Credentials

Now that you have a sales channel, we can generate API credentials. This can be done under “My Organization” in the Admin App under “API Settings”. Here, you will find an overview of your Storefront credentials and the option to create a new one.

Select the sales channel for which you want to create credentials and provide a clear description. Click Add to generate the credentials.

In the window that appears after creation, copy the key from the field. Note: This is the only time you will see the full key. Once you close the window, the key will no longer be fully visible. If you lose it, you will need to create a new one for the same sales channel and delete the existing one.

Configuring the Plugin

With the copied key, we can now connect the webshop. First, ensure that the correct plugin is installed. Search for ‘Afosto.app - ORM’ at https://app.afosto.com/plugins.
If the app is not installed, contact support@afosto.com.

  1. Open app.afosto.com and go to your webshop.
  2. Under "Apps", click on "afosto.app - ORM".
  3. You will now see the settings for connecting your webshop to the Afosto Storefront.
  4. Paste the copied key into the API Token field.
  5. Save the settings to proceed with configuring the template.

What’s Different?

In our example shop for the Afosto Storefront, we use Preact, a lightweight version of React, a widely popular JavaScript framework. This allows for fast updates to the shopping cart without requiring a full page reload.

As a result, we no longer write HTML in Twig but instead use Preact components. In the next steps, we will explain how this works.

To write JavaScript in a modern way, we also use JavaScript module syntax, which allows for importing modules like this:

1<script type="module">
2  import { h, render } from 'https://esm.sh/preact';
3  import { html } from 'https://esm.sh/htm/preact';
4
5  render(html`<h1>Hello World!</h1>`, document.getElementById('app'));
6</script>
7<div id="app"></div>

CopyEdit

<script type="module"> import { h, render } from 'https://esm.sh/preact'; import { html } from 'https://esm.sh/htm/preact'; render(html`<h1>Hello World!</h1>`, document.getElementById('app')); </script> <div id="app"></div>

This means we don’t work with JavaScript files from the assets folder but instead within a Twig file.

Storefront Logic

Implementing the storefront logic is a detailed task. The easiest approach is to use the script from our example shop.
You can find it here: Afosto Storefront Example Script.

Setting Up the Storefront Integration

Overview

This file sets up several key functionalities:

  • Initializing the Storefront client with the configured Storefront credentials and the shop’s language, ensuring error messages are returned in the correct language.
  • Setting the session ID for tracking the user via Server-Side Events.
  • Initializing the CartDrawer, which retrieves the current shopping cart if it exists.
  • Initializing the CartPage when visiting the /cart page.
  • Setting up a link to the account environment or the menu for logged-in users.

With this logic in place, we can now modify the existing shop to use the Afosto Storefront.

Loading Scripts

Open the file twig/layouts/index.twig and add the following line:

1twig
2
3{% include 'layouts/storefrontScripts.twig' %}

Checking Body Attributes

In the same file (twig/layouts/index.twig), check if the <body> element contains the attributes 'data-af-currency' and 'data-af-currency-iso'. It should look like this:

1twig
2
3<body class="type-{{type}}" data-af-currency="{{properties.currency_symbol}}" data-af-currency-iso="{{properties.currency}}">

Updating the Header

Adjusting the Cart Preview Button

The button that opens the shopping cart also needs to be updated. It is in the same section as the account menu. Modify the following code:

1diff
2
3<li class="text-center">
4    <a class="cart-toggle" data-toggle="drawer" data-target="#cart-drawer">
5        <i class="fa fa-shopping-cart"></i>
6-       <span class="badge">{{ cart.count }}</span><br>
7+       <span class="badge">-</span><br>
8        <span class="hidden-xs">{{ "Shopping Cart"|t }}</span>
9    </a>
10</li>

Updating the Cart Drawer

At the bottom of the header.twig file, replace the following include lines:

1twig
2
3{% include 'layouts/cartDrawer.twig' %}

or

1twig
2
3{% include 'layouts/cart-overview.twig' %}
4<div class="cart-overview-underlay"></div>

With:

1html
2
3<div id="cart-drawer-container"></div>

Updating the Account Menu

If your sales channel supports accounts, update the account menu in the header as follows. Afosto shops read the user’s cookie and store it in the pluginData of the Twig data, allowing server-side display of the user’s name and login status. Based on this data, you can implement additional features for logged-in users.

If your sales channel does not use accounts, simply remove the red-highlighted lines in the following code.

1diff
2
3<li class="text-center" id="account-display">
4    <a href="#" id="account-link">
5        <i class="fa fa-user{% if pluginData['af-sid'].given_name %}-check{% else %}-times{% endif %}"></i>
6        <br />
7        <span class="hidden-xs account-link-label">
8            {% if pluginData['af-sid'].given_name %}{{pluginData['af-sid'].given_name}}{% else %}{{'Login'|t}}{% endif %}
9        </span>
10    </a>
11</li>

Updating the Mobile Menu

The mobile menu also contains an account menu. The previously copied script does not update this item automatically. While it is possible to add this manually, this guide does not cover it, as an alternative solution is available.

Updating the Shopping Cart Page

  1. Create a new file in twig/cart/ named cart-storefront.twig.
  2. Paste the code from the following link into it:
    Afosto Storefront Cart Template
  3. Open index.twig in the same folder and update the following:
1twig
2
3{% set code = "storefront" %}
4
5{% include ['cart/'~ code ~ '.twig','cart/default.twig'] %}

Updating the Product Page

The product page requires an additional hidden field. In addition to product_id and price, we now also need the SKU for adding products to the cart.

Find the form with action="{{cart_url}}". This is the form that adds the product to the cart. Locate the product_id or price field and add the following line inside the form:

1diff
2
3<input type="hidden" value="{{ price }}" name="price"/>
4<input type="hidden" value="{{ id }}" name="product_id"/>
5+ <input type="hidden" value="{{ sku }}" name="sku"/>

Also, ensure that the form contains the following attributes so that the JavaScript can correctly reference it:

1twig
2
3<form
4    action="{{ cart_url }}"
5    method="post"
6    id="product-form"
7    data-cart-url="{{ home_url }}cart"
8    data-product-url="{{ url }}"
9>

Updating Quickview Content

If your shop has a quickview feature, apply the same modifications to the form inside twig/product/quickview.twig.

Updating the Wishlist

If your shop uses a wishlist feature, update it to support the Afosto Storefront by adding an SKU field:

1diff
2
3<input type="hidden" value="{{ product.id }}" name="product_id"/>
4<input type="hidden" value="{{ product.price }}" name="price"/>
5+ <input type="hidden" value="{{ product.sku }}" name="sku"/>
6<input type="hidden" value="1" name="quantity"/>

Ensure the form has the following attributes:

1twig
2
3<form
4    action="{{cart_url}}"
5    method="post"
6    id="add-product-{{product.id}}"
7    class="wishlist-product-form"
8    data-cart-url="{{home_url}}cart"
9    data-product-url="{{url}}"
10>

Updating the Product Grid

Many shops have an add to cart button in the product grid. Ensure that this form includes all three required fields and the correct attributes:

1diff
2
3<form
4    action="{{product.cart_url}}"
5    method="POST"
6    id="product-form-{{product.id}}"
7    data-cart-url="{{home_url}}cart"
8    class="grid-product-form"
9    data-product-url="{{product.url}}"
10    data-form-input="[{'product_id' : '{{product.id}}', 'quantity' : '1', 'price' : '{{product.price}}'}]"
11>
12<input type="hidden" value="{{ product.price }}" name="price"/>
13<input type="hidden" value="{{ product.id }}" name="product_id"/>
14<input type="hidden" value="{{ product.sku }}" name="sku"/>
15<button type="submit" class="btn btn-primary btn-sm">
16    <i class="fa fa-shopping-cart fa-lg"> </i> &nbsp;
17    <i class="fa fa-plus fa-lg"> </i>
18</button>
19</form>

Updating JavaScript Files

cart.js

Replace the contents of assets/js/cart.js with:

1js
2
3$('body').on('cart:updated', function(event, data) {
4    if (!!data) {
5        var count = ((data && data.items) || []).reduce(function(acc, item) {
6            return acc + item.quantity;
7        }, 0);
8        
9        $('.cart-toggle').find('.badge').text(count);
10    }
11});

product.js

Find the function retrieveFormInput in assets/js/product.js and modify:

1diff
2
3- var approvedAttributes = ['product_id', 'price', 'quantity'];
4+ var approvedAttributes = ['product_id', 'price', 'quantity', 'sku'];

Testing the Integration

With these changes, your webshop is now ready for the Afosto Storefront.
Test all forms, the shopping cart, and the full checkout flow.

Need help? Contact us at support@afosto.com.