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 
- Vue components for Shopping Experiences CMS
- CMS sections, blocks and elements styled using Tailwind CSS classes
- 🚀 Empowered by @shopware-pwa/composables-next
Setup 
Install npm package:
# ✨ 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-baseThen, register the Nuxt layer in nuxt.config.ts file:
// 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):
/* 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 ~/componentsdir 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).
⚠️ <RouterLink/> components used 
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.
Links 
- 👥 Community ( - #composable-frontends&- #shopware-pwachannel)
Changelog 
Full changelog for stable version is available here
Latest changes: 1.2.0 
Minor Changes 
- #1501 - 9c84519Thanks @mkucmus! - Ability to overwrite internal components- For example: - SwSharedPrice.vueis used for multiple times to display a price. Create a component with the same name to make- cms-basestart 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 - d4482d5Thanks @mdanilowicz! - Add smooth scrolling for listing pagination
Patch Changes 
- Updated dependencies [a87bbcf,2c337b5,13c83be,13c83be,8ba9702,a03a492]:- @shopware/api-client@1.2.0
- @shopware-pwa/composables-next@1.5.0
- @shopware-pwa/helpers-next@1.2.0
 
Available components 
CmsGenericBlock 
Renders a Block type structure
Example usage:
<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 
Renders an Element type structure
Example usage:
<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 
CmsPage 
An entrypoint to render the whole CMS object
Example usage:
<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 
CmsBlockCenterText 
CmsBlockCrossSelling 
CmsBlockCustomForm 
CmsBlockDefault 
CmsBlockForm 
CmsBlockGalleryBuybox 
CmsBlockImage 
CmsBlockImageBubbleRow 
CmsBlockImageCover 
CmsBlockImageFourColumn 
CmsBlockImageGallery 
CmsBlockImageHighlightRow 
CmsBlockImageSimpleGrid 
CmsBlockImageSlider 
CmsBlockImageText 
CmsBlockImageTextBubble 
CmsBlockImageTextCover 
CmsBlockImageTextGallery 
CmsBlockImageTextRow 
CmsBlockImageThreeColumn 
CmsBlockImageThreeCover 
CmsBlockImageTwoColumn 
CmsBlockProductDescriptionReviews 
CmsBlockProductHeading 
CmsBlockProductListing 
CmsBlockProductSlider 
CmsBlockProductThreeColumn 
CmsBlockSidebarFilter 
CmsBlockText 
CmsBlockTextHero 
CmsBlockTextOnImage 
CmsBlockTextTeaser 
CmsBlockTextTeaserSection 
CmsBlockTextThreeColumn 
CmsBlockTextTwoColumn 
CmsBlockVimeoVideo 
CmsBlockYoutubeVideo 
CmsElementBuyBox 
Render a product including prices, basic information and add to cart button
CmsElementCategoryNavigation 
Load a navigation menu for current category
CmsElementCrossSelling 
Render slider of the products from cross-selling setting of a product
CmsElementCustomForm 
Display a contact or newsletter sign up form
CmsElementForm 
Display a contact or newsletter sign up form
CmsElementImage 
Display an image for provided media content. Including extra attributes like srcset and alt
CmsElementImageGallery 
Display a gallery for provided media. Handles a plain image and the spatial (3d) images.
CmsElementImageGallery3dPlaceholder 
CmsElementImageSlider 
Display a slider of images
CmsElementManufacturerLogo 
Display a logo of manufacturer of a product
CmsElementProductBox 
Display a box for provided product
CmsElementProductDescriptionReviews 
Display a description and reviews for provided product
CmsElementProductListing 
Display the list of products for currently active listing page
CmsElementProductName 
Display a name for a product
CmsElementProductSlider 
Display a slider of provided products
CmsElementSidebarFilter 
Display a sidebar containing filters for an active product listing
CmsElementText 
Display a text. Html to Vue mechanism is used to render buttons, links, images accordingly as Vue elements
CmsElementVimeoVideo 
Display a player for Vimeo media
CmsElementYoutubeVideo 
Display a player for YouTube video
CmsSectionDefault 
Renders a generic block type
See the <CmsPage/> source code to see how it's used
CmsSectionSidebar 
Renders a generic block type
See the <CmsPage/> source code to see how it's used