Skip to content

shopware/frontends - cms-base

shopware/frontends - cms-base

Nuxt layer that provides an implementation of all CMS components in Shopware based on utility-classes using atomic css syntax (UnoCss / Tailwind).

It is useful for projects that want to use the CMS components but design their own layout.

Features

Setup

Install npm package:

sh
# ✨ Auto-detect
npx nypm install -D @shopware-pwa/cms-base

# npm
npm install -D @shopware-pwa/cms-base

# yarn
yarn add -D @shopware-pwa/cms-base

# pnpm
pnpm install -D @shopware-pwa/cms-base

# bun
bun install -D @shopware-pwa/cms-base

Then, register the Nuxt layer in nuxt.config.ts file:

ts
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
  extends: [
    "@shopware-pwa/composables-next/nuxt-layer",
    "@shopware-pwa/cms-base",
  ],
  shopware: {
    endpoint: "https://demo-frontends.shopware.store/store-api/",
    accessToken: "SWSCBHFSNTVMAWNZDNFKSHLAYW",
  },
  modules: ["@shopware-pwa/nuxt3-module"],
  /**
   * Commented because of the StackBlitz error
   * Issue: https://github.com/shopware/frontends/issues/88
   */
  typescript: {
    // typeCheck: true,
    strict: true,
  },
  telemetry: false,
});

Basic usage

Since all CMS components are registered in your Nuxt application, you can now start using them in your template (no imports needed):

js
/* Vue component */

// response object can be a Product|Category|Landing Page response from Shopware 6 store-api containing a layout (cmsPage object) built using  Shopping Experiences
<template>
    <CmsPage v-if="response.cmsPage" :content="response.cmsPage"/>
</template>

You can use default styling by installing/importing Tailwind CSS stylesheet in your project.

See a short guide how to use cms-base package in your project based on Nuxt v3.

📘 Available components

The list of available blocks and elements is here.

🔄 Overwriting components

The procedure is:

  • find a component in component's list, using a Vue devtools or browsing the github repository
  • take its name
  • create a file with the same name and place it into ~/components dir in your nuxt project (or wherever according your nuxt config)

✅ Thanks to this, nuxt will take the component registered in your app instead of the one registered by this nuxt layer.

Internal components

Internal components are not a part of public API. Once overwritten you need to track the changes on your own.

There is also a possibility to override the internal components, shared between public blocks and elements, the ones starting with Sw prefix, like SwSlider.vue or SwProductCard.vue.

An example: some components use SwSharedPrice.vue to show prices with corresponding currency for products in many places like product card, product details page and so on. In order to change the way how the price is displayed consistently - create a one component with a name SwSharedPrice.vue and that's it. The new component will be used everywhere where is "imported" (autoimported actually).

Some components use RouterLink component internally, available in Vue Router. In order to parse CMS components correctly and avoid missing component warning, it's highly recommended to have Vue Router installed or Nuxt router enabled in your application.

TypeScript support

All components are fully typed with TypeScript.

No additional packages needed to be installed.

Changelog

Full changelog for stable version is available here

Latest changes: 1.2.0

Minor Changes

  • #1501 9c84519 Thanks @mkucmus! - Ability to overwrite internal components

    For example:

    SwSharedPrice.vue is used for multiple times to display a price. Create a component with the same name to make cms-base start using your component internally.


    ⚠️ Internal components aren't part of public API so the related changes won't be published in the changelog. Try to overwrite and track the changes on your responsibility.

  • #1404 d4482d5 Thanks @mdanilowicz! - Add smooth scrolling for listing pagination

Patch Changes

Available components

CmsGenericBlock

source code

Renders a Block type structure

Example usage:

vue
<script setup lang="ts">
import type { CmsSectionDefault } from "@shopware-pwa/composables-next";
import { getCmsLayoutConfiguration } from "@shopware-pwa/helpers-next";

const props = defineProps<{
  content: CmsSectionDefault;
}>();

const { cssClasses, layoutStyles } = getCmsLayoutConfiguration(props.content);
</script>

<template>
  <div class="cms-section-default" :class="cssClasses" :styles="layoutStyles">
    <CmsGenericBlock
      v-for="cmsBlock in content.blocks"
      class="overflow-auto"
      :key="cmsBlock.id"
      :content="cmsBlock"
    />
  </div>
</template>

CmsGenericElement

source code

Renders an Element type structure

Example usage:

vue
<script setup lang="ts">
import type { CmsBlockGalleryBuybox } from "@shopware-pwa/composables-next";
import { useCmsBlock } from "#imports";

const props = defineProps<{
  content: CmsBlockGalleryBuybox;
}>();

const { getSlotContent } = useCmsBlock(props.content);
const rightContent = getSlotContent("right");
const leftContent = getSlotContent("left");
</script>

<template>
  <div
    class="lg:container mx-auto flex flex-col lg:flex-row gap-10 justify-center"
  >
    <div class="overflow-hidden basis-4/6">
      <CmsGenericElement :content="leftContent" />
    </div>
    <div class="basis-2/6">
      <CmsGenericElement :content="rightContent" />
    </div>
  </div>
</template>

CmsNoComponent

source code


CmsPage

source code

An entrypoint to render the whole CMS object

Example usage:

vue
<script setup lang="ts">
import { useLandingSearch } from "#imports";
import type { Schemas } from "#shopware";

const props = defineProps<{
  navigationId: string;
}>();

const { search } = useLandingSearch();

const { data: landingResponse } = await useAsyncData(
  "cmsLanding" + props.navigationId,
  async () => {
    const landingPage = await search(props.navigationId, {
      withCmsAssociations: true,
    });
    return landingPage;
  },
);

if (typeof landingResponse?.value !== null) {
  const landingPage = landingResponse as Ref<Schemas["LandingPage"]>;
  useCmsHead(landingPage, { mainShopTitle: "Shopware Frontends Demo Store" });
}
</script>

<template>
  <LayoutBreadcrumbs />
  <CmsPage v-if="landingResponse?.cmsPage" :content="landingResponse.cmsPage" />
</template>

CmsBlockCategoryNavigation

source code


CmsBlockCenterText

source code


CmsBlockCrossSelling

source code


CmsBlockCustomForm

source code


CmsBlockDefault

source code


CmsBlockForm

source code


CmsBlockGalleryBuybox

source code


CmsBlockImage

source code


CmsBlockImageBubbleRow

source code


CmsBlockImageCover

source code


CmsBlockImageFourColumn

source code


CmsBlockImageGallery

source code


CmsBlockImageHighlightRow

source code


CmsBlockImageSimpleGrid

source code


CmsBlockImageSlider

source code


CmsBlockImageText

source code


CmsBlockImageTextBubble

source code


CmsBlockImageTextCover

source code


CmsBlockImageTextGallery

source code


CmsBlockImageTextRow

source code


CmsBlockImageThreeColumn

source code


CmsBlockImageThreeCover

source code


CmsBlockImageTwoColumn

source code


CmsBlockProductDescriptionReviews

source code


CmsBlockProductHeading

source code


CmsBlockProductListing

source code


CmsBlockProductSlider

source code


CmsBlockProductThreeColumn

source code


CmsBlockSidebarFilter

source code


CmsBlockText

source code


CmsBlockTextHero

source code


CmsBlockTextOnImage

source code


CmsBlockTextTeaser

source code


CmsBlockTextTeaserSection

source code


CmsBlockTextThreeColumn

source code


CmsBlockTextTwoColumn

source code


CmsBlockVimeoVideo

source code


CmsBlockYoutubeVideo

source code


CmsElementBuyBox

source code

Render a product including prices, basic information and add to cart button


CmsElementCategoryNavigation

source code

Load a navigation menu for current category


CmsElementCrossSelling

source code

Render slider of the products from cross-selling setting of a product


CmsElementCustomForm

source code

Display a contact or newsletter sign up form


CmsElementForm

source code

Display a contact or newsletter sign up form


CmsElementImage

source code

Display an image for provided media content. Including extra attributes like srcset and alt


CmsElementImageGallery

source code

Display a gallery for provided media. Handles a plain image and the spatial (3d) images.


CmsElementImageGallery3dPlaceholder

source code


CmsElementImageSlider

source code

Display a slider of images


source code

Display a logo of manufacturer of a product


CmsElementProductBox

source code

Display a box for provided product


CmsElementProductDescriptionReviews

source code

Display a description and reviews for provided product


CmsElementProductListing

source code

Display the list of products for currently active listing page


CmsElementProductName

source code

Display a name for a product


CmsElementProductSlider

source code

Display a slider of provided products


CmsElementSidebarFilter

source code

Display a sidebar containing filters for an active product listing


CmsElementText

source code

Display a text. Html to Vue mechanism is used to render buttons, links, images accordingly as Vue elements


CmsElementVimeoVideo

source code

Display a player for Vimeo media


CmsElementYoutubeVideo

source code

Display a player for YouTube video


CmsSectionDefault

source code

Renders a generic block type

See the <CmsPage/> source code to see how it's used


CmsSectionSidebar

source code

Renders a generic block type

See the <CmsPage/> source code to see how it's used


ProductCardSkeleton

source code