Core concepts

The Storefront is based on the NextJS Framework. Due to this, we write our client-side code in React.
It is recommended to have a profound knowledge of Javascript and a basic understanding of both NextJS and React. The common React beginners guide 🎥 will help you to gain knowledge and understand the concepts.

Also, because the Storefront interacts with Makaira a lot, it is highly recommended to have a basic knowledge about Makaira as well. But no worries, we will introduce some key concepts in the following document.


Fetching data from Makaira

With the Storefront, we can render almost any kind of data from Makaira (products, product lists, landing pages, etc.) in the form of react components (also known as "patterns" here). Therefore, for a better understanding, it is recommended that you have a basic knowledge about how Makaira works and what the data structure of a Makaira document (such as products and landing pages) looks like.
For the start just imagine we have a document in Makaira with the URL /test-product.html and the pageType with the value makaira-productgroup - a product document.

The Storefront, respectively NextJS, provides a Node.js server. If we want to render that product by calling our Storefront domain with /test-product.html the following happens:

  1. Within server/index.js the Storefront takes the request URL and decides what to do with it.
  2. Our URL matches lines 95-100 within server/index.js. The page frontend/entry, located within the pages folder, will be rendered.
  3. In that file, before it is rendered, a request is sent to Makaira to fetch all necessary data for that document (fetchPageData()) with the URL /test-product.html
  4. Makaira looks into its data if it finds a document with the corresponding URL. It does!
  5. Makaira answers with a response code of 200. In the response body, we have a JSON object containing a lot of data, like the pageType.
  6. The Storefront takes the response body data and renders the page depending on the value of pageType (this happens within pages/frontend/entry.js line 100).

Pattern Library

One core feature of the Storefront is the Pattern Library (Pali). You can access the Pali by accessing the path /pali.

The Pali contains a summary of all components/patterns we use in our project, and a lot of important UX/design information like colors, icons, typography, and buttons.

We use the Pali as a "source of truth" while working on new patterns: A button must have a specific color? Check if this color is configured in the Pali. If so: Use it! If not: Ask the designer if he is sure about the color and whether you should add that to the color configuration. The text in your new pattern has to have three different font-sizes according to the screen size? Check the typography in the Pali if each configuration is available or not.
If not contact the designer that you found an inconsistency!

Our goal with this is to ensure consistency throughout the project following the convention: No colors, typographies, buttons, etc. should be used that aren't defined in the Pali. Further, we strongly recommend making use of the atomic design 📖 approach like that your storefront stays maintainable.

We'll cover the part on how to work with the Pali later in this document (see Workflows).


Content elements

A powerful feature is to render content that is configured in the Makaira Page EditorPage Editor - the central CMS module where you can create content pages or enrich categories, manufacturers ... with content. Imagine you create a Landing Page called Home Page with the URL /. Now you add content to that page, like a Text (mehrspaltig) element.
You add some content to that element, save the configuration, load the page in the Storefront, and you see: The content you just configured in the Makaira landing page is rendered in the storefront!

How does this work out? How does the Storefront know where it should render which component?

Remember the first part of this guide: Fetching data from Makaira?

We hit the / URL, the Storefront fetches the data from a Makaira document with the URL /. The pageType of this document is page, so the LandingPage react component is rendered.

Within the data from that page (which is accessible as pageData globally from the GlobalDataProvider), we have the information about the content elements for that page. Take a look at line 15 in frontend/LandingPage/index.js.

Here we render a ContentElements component and pass a property elements (which is an array of objects). Before we step further let's go to Makaira and open the Component Editor. Look for the component with the name "Text (mehrspaltig)" and check the value of the Identifier field. It should be multi-column-text. Now we come back to the ContentElements component. You see, we iterate over the elements array. For each
entry we check, if its component (which is the Identifier from the Component Editor) value matches a key within the components object (line 23). If yes, we know the react component that should be rendered for that component and pass all data from that element as properties to the react component.


Data driven approach

Most of our components/patterns don't fetch any data. They receive their properties according to the document in Makaira.

It is important to consider that while working with the Storefront and the Pattern Library. All components that you see in the Pali work with dummy data (check out the variants.js file within a pattern folder).

When a component is rendered for the client remember the part 2.3 Content elements. Within the ContentElements component the specific component is rendered in this way <Component {...entry.properties.content} />.
As you can see, we just destructure the content of the entry and pass all this data as properties.

To render a component within the Pali it works a bit differently. Because here we don't fetch any data from Makaira we work with dummy data. Take a look into the variants.js file from the MultiColumnText component.
It exports an array of objects. Each object represents a variant of that component. The name is just to give that variant a short explanation. More interesting is the props object. Everything that is written here will be passed
to the component as properties. So a variant basically means that there are other values for some properties.