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-base
Then, 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
~/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).
⚠️ <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-pwa
channel)
Changelog
Full changelog for stable version is available here
Latest changes: 1.1.2
Patch Changes
- Updated dependencies [
938c4cf
]:- @shopware/api-client@1.1.2
- @shopware-pwa/composables-next@1.4.2
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