This is the early access documentation preview for Custom Views. This documentation might not be in sync with our official documentation.

Main development concepts

The commercetools Frontend approach

commercetools Frontend allows developers and business users (for example, marketing managers) to collaborate on creating, maintaining, and optimizing the frontend for their e-commerce website.

In commercetools Frontend, business users are responsible for creating and managing website pages and content. To do this, they use the Studio, which is the commercetools Frontend management interface.

On the other hand, developers are responsible for developing what business users need to create and manage the website pages and content. Developers are also responsible for optimizing the performance of the commercetools Frontend project.

This approach requires that business users and developers agree on a clear configuration for their commercetools Frontend project early in the development process. This way, developers can optimize the development based on use cases, and business users can autonomously create and manage the website pages and content.

Within commercetools Frontend, all page changes are independent from code deployments, including changes to the data displayed as well as to the structure of the page.

Furthermore, commercetools Frontend allows developers to choose the frontend development pattern, style, and approach they prefer. For further information, see the development constraints.

General concepts

API hub

The API hub is the backend for frontend in commercetools Frontend. It contains the extension runner, and also acts as the orchestration layer that relays the data your website requires, for example, the page layout information during server-side rendering or Data source response for your Frontend components.

Extension runner

The extension runner is a Node.js environment within the API hub that runs your Data sources, Actions, and Dynamic page handler extensions.

The hostname to contact the extension runner has the following structure:

  • For the development environment: PROJECT_NAME-CUSTOMER_NAME.frontastic.rocks
  • For the staging environment: PROJECT_NAME-CUSTOMER_NAME.frontastic.io

The requests to the extension runner must include the HTTP header Commercetools-Frontend-Extension-Version, where its value must be your Studio developer username.

To copy your Studio developer username, follow these steps:

  1. From the Studio home page, click the Account icon and select Profile: the User settings dialog opens.
  2. Copy the value in the Developer header username field.

Studio

The Studio is a commercetools Frontend management interface that lets business users and developers build, edit, and manage a commercetools Frontend website.

Build a website page

Components, Data Sources, and Actions are the required elements to build a website page with commercetools Frontend. Developers create them and business users use them in the Studio to build the website pages.

Components

Components are configurable and reusable elements used to build the structure of website pages, they are similar to presentational components or Web Components.

commercetools Frontend Components are React components that receive and display data as configured by business users in the Studio.

Each Component consists of the two following files, which developers write and maintain in their commercetools Frontend project GitHub repository:

  • JavaScript source code file. This is the entry point, it is a React component that receives some special props.
  • JSON configuration file. It defines the Component configuration options that are available in the Studio. In particular, it determines which aspects of the Component can be configured and how, and which Data Sources are connected to the Component.

An example of a Component is a product slider, for which it is possible to configure the title, the number of products displayed, and the Data Source from which product data is read.

A commercetools Frontend Component can be made up of multiple small React components, depending on developer preferences and on the size of the Component. To develop Components you can follow any frontend development pattern (for example, styled components, CSS, and presentational components).

Components are called tastics in the code base.

Data Sources

Data Sources return data that is then displayed on the website pages through Components. Data Sources are decoupled from Components, therefore no deployment is needed to manage the data displayed on a page and business users can autonomously do it.

Data Sources are JavaScript/TypeScript functions that:

  1. Fetch data from external APIs (for example, a headless e-commerce system).
  2. Simplify the fetched data to what is required by commercetools Frontend.
  3. Return data in a structure that Components can use.

Data Sources receive the user session, user configuration, and project configuration and then return data. Data Sources can optionally use the user context (user groups, flags, locale, etc.) and the context in which they are used (page, URL, locale, etc.). Therefore, there is great potential in optimizing the retrievable data for specific use cases.

Each Data Source has a configuration schema that defines what can be configured for the Data Source from the Studio.

An example of Data Source is a product list fetched from a headless e-commerce system, for which it is possible to configure search queries, categories, or price ranges.

Components and Data Sources decoupling

The decoupling of Components from Data Sources is meant to make business users independent in managing the website pages so that developers are not involved in daily frontend changes. This way, developers can focus on improving Components and Data Sources. The trade-off of this decoupling is that pages cannot be optimized by hand, since business users can edit any page without interacting with the development team.

Actions

Websites don’t only display data, they also perform actions. commercetools Frontend Actions perform actions on external APIs (for example, a headless e-commerce system) and return a response if needed.

Actions are JavaScript/TypeScript functions that retrieve data from the frontend and have access to the user context and project configuration.

An example of Action is adding a product to the cart.

How Components, Data Sources, and Actions work

The entry Component is often a basic Component retrieving data and calling other Components which implement the visuals, as in the following example of a product slider.

For further information on the product slider code, see the code on GitHub. You can implement a product slider following atomic design principles as we did, or you can follow different implementation patterns.

Product slider sample codeJavaScript
import { Product } from '@commercetools/frontend-domain-types/product/Product';
import ProductSlider, {
ProductSliderProps,
} from 'components/commercetools-ui/organisms/product/product-slider';
import { Tastic } from 'types/tastic';
function ProductSliderTastic({
data,
}: Tastic<{ items: Product[] }, ProductSliderProps>) {
if (!data?.data?.dataSource?.items) return <p>No products found.</p>;
return <ProductSlider {...data} products={data.data.dataSource.items} />;
}
export default ProductSliderTastic;

To ease the development of Data Sources, Actions, and their integration into your Components, we provide the commercetools Frontend SDK. With the SDK you can create Hooks exposing core functionality like fetching the current cart and executing common cart Actions. For example, calling the backend Action to add an item to the current user’s cart, as in the following example.

Call Action to add item to the user's cartaJavaScript
const addItem = useCallback(async (variant: Variant, quantity: number) => {
const extensions = SDK.getExtensions();
const payload = {
variant: {
sku: variant.sku,
count: quantity,
},
};
const res = await extensions.cart.addItem(payload);
mutate('/action/cart/getCart', res);
}, []);

Create and manage the website URL structure

As stated above, with Components, Data Sources, and Actions you build a website page. However, an e-commerce website consists of multiple pages.

The Site Builder and dynamic pages allow you to create and manage the URL structure of your commercetools Frontend website.

Site Builder and static pages

From the Site Builder in the Studio, it is possible to build static pages that live under a defined URL. In the Site Builder, these pages are called Page Folders, and they are used to create the structure of the website.

Some examples of Page Folders are:

  • The start page, for which the path is /.
  • A landing page for an advertisement campaign. For example, /holidays-season-2023.
  • Generic pages like cart or customer account. For example, /cart.
  • Static or special categories. For example, a static landing page like /women with dynamic pages below.

For content to be displayed on the website, each Page Folder must have at least one Page Version and can have multiple Page Versions. Page Versions are the actual pages displayed on the website. Page Versions may have different statuses, different layouts, and they can be displayed for specific locales only.

Developers use the Site Builder to test Components using the Page Folders and Page Versions in the staging environment. Business users use the Site Builder to build and manage Page Folders and Page Versions.

Dynamic pages

To manage dynamic pages, developers must define the concepts (or entity types) of the website, such as product, product details, wishlist, etc.

These concepts are exposed to the Studio so that business users can create dynamic pages. For example, a generic product detail page or specific pages for subsets of the concepts, like products in a specific price range.

Developers must create a JavaScript/TypeScript function that matches any URL not already matching the static pages defined in Site Builder and returns the matching concept and data for that URL. This is a single function, so you must also define the order of the matching concepts. An example of this could be:

  1. Match /p/.*/<productSlug> (for example, using regular expressions). This maps the product concept and fetches the product data for the given slug.
  2. Match /c/.*/<categorySlug>. This maps the category concept and fetches the product category data for the given slug.
  3. Any URL that has not yet been matched returns a search result for the words in the URL.

Depending on the number of concepts and the URLs you are searching, this could be simpler or more complex. You can find an example in this implementation. Since there are no limits to what this function can match, there are no limits to the URL structure.

How page rendering works

Your commercetools Frontend project comes with a generic Next.js entry page called pages/[[...slug]].tsx which acts as a catch-all page.

On this page, the API hub is asked what the page's structural elements (Components) and data (Data Source results) are. The API hub calls all Data Sources in parallel to fetch the required data. A function in the Next.js stack triggers the rendering of Components and checks that each Component receives the required data.

You can define custom pages next to the provided catch-all page. However, you would lose the purpose and value of the Studio by doing so.

Development constraints

For the development of your commercetools Frontend project, you are bound to the concepts described above. You should design Components, Data Sources, and Actions that best fit your business cases and you should plan an efficient management of dynamic pages according to the needs of your website. However, there are no constraints on how you develop these concepts.

The frontend of commercetools Frontend is plain Next.js with some simple helpers provided. To develop your frontend, you can follow any development pattern. All common optimizations for PWAs, SPAs, and Next.js apply and you can use any Next.js plugin. You can use either TypeScript or JavaScript, we provide you with all the type information you might need if you use TypeScript.

For backend functions of Data Sources, Actions, and dynamic page handling, you can use either TypeScript or JavaScript. Concerning APIs, the communication over HTTPS is the recommended approach. Therefore, we suggest using GraphQL, REST, RESTful, or XML-RPC. However, you can also use SMTP or anything else within specific runtime limits (time, CPU, and memory).

We provide opinionated examples for Components and Data Sources that you can use as templates or as a starting point. However, you can implement them in any way, based on the described constraints.

We recommend involving business users in the design and development phase of Components, Data Sources, and Actions and in the definition of the website URL structure.