Benjamin Lewandowski

I design, develop and deliver frontend as well as print projects in theheart of europe. I also play music in front of people under the artist name kaozz.Modern, opinionated & dynamic.

Shopware Frontendsback

a framework for building custom storefronts with Shopware 6

Shopware Frontends is a framework for building custom storefronts with Shopware 6 using Vue. Basically, it’s a collection of packages that you can use to implement your custom storefront project consisting of various Vue components and helpers. It also uses server-side rendering wherever possible based on nuxt.

So while Vue Storefront is a standalone PWA storefront for your eCommerce-Application that can be connected to any eCommerce backend, Shopware Frontends is a framework for building custom storefronts especially for Shopware 6 using Vue.

Frontends is therefore more of a meta-framework than a “finished solution”, but uses some of the same building blocks. It aims to bridge the gap between a theme-based implementation and a fully custom headless implementation.

Note that it is currently in Early Access. This means that it is not yet ready for production.

It is divided into separate modules, some of which can be used on their own.

The modules include

  • API client
    • Abstraction to Shopware’s store API
    • Manages authentication state and request/response schemas
    • Can be used standalone in any JavaScript project
  • Types
    • TypeScript types for all Shopware objects and API endpoints
  • Composable package
    • A self-contained set of Vue.js composables that can be used in any Vue project and don’t rely on other parts of “frontends”.
    • They provide state management, UI logic, and data retrieval.
  • CMS Base Package
    • An implementation of all standard Shopware sections, blocks and elements as Nuxt modules. The provided styling is done in Tailwind.css / unocss. It is useful for projects that want to use the CMS components but design their own layout.
  • Helper Packages
    • A set of helper functions related to price formatting, translation handling, UI state or URL handling. They are not linked to other components.

As its a library of modules, it has different (empty) templates you can be used:

  • Nuxt based
  • Astro based
  • Vue and Vite based (which doesn’t use nuxt or astro)

There is also a fully configured “default” layout variant available as a starting point. <- more like vue storefront. It’s basically a demo implementation of the available modules.

While Shopware usually suggests using PHPstorm, they say that it is better to use Vscode for frontends.

In particular, they suggest using the following plugins:

  • Vue Language Features (Vue.volar)
  • Prettier - Code Formater (esbenp.prettier-vscode)
  • TS and JS Language Features (vscode.typescript-language-features)

The easiest way to get started is to clone one of these templates (I personally would suggest the nuxt-based variant) via tiged (a node package for cloning subsets of a git repository).

npx tiged shopware/frontends/templates/vue-blank vue-blank && cd vue-blank

Then install the dependencies (with npm, pnpm or yarn).

npm i && npm run dev

Next, set up your nuxt.config.ts file with the appropriate Shopware 6 API values so it does not use the public demo one.

/* ... */
export default defineNuxtConfig({
    /* ... */
    runtimeConfig: {
        public: {
            shopware: {
                shopwareEndpoint: "https://shopware-endpoint.tld",
                shopwareAccessToken: "shopware-access-token",
            },
        },
    },
});

Now you can start using the modules on a “blank” canvas.

For example, you could start building a navigation with the provided useNavigation composable.

<script setup lang="ts">
import { getCategoryUrl } from "@shopware-pwa/helpers-next";
const { loadNavigationElements, navigationElements } = useNavigation();
await loadNavigationElements({ depth: 2 });
</script>

<template>
    <ul>
        <li v-for="navigationElement in navigationElements" :key="navigationElement.id">
            <RouterLink :to="getCategoryUrl(navigationElement)" :target="navigationElement.externalLink || navigationElement.linkNewTab ? '_blank' : ''">
                {{ navigationElement.translated.name }}
            </RouterLink>
        </li>
    </ul>
</template>