Shopware 6.7 marks a transformative era for developers building custom storefronts. The platform has matured significantly, shedding legacy patterns in favor of a robust, type-safe architecture centered around modern Vue.js practices. If you are planning to build, extend, or migrate a storefront in version 6.7 and beyond, understanding the new ecosystem is critical. This guide explores the architectural shifts, the integration with the Shopware PWA SDK, and the practical implications for your development workflow.
A Modern Foundation: Vite, Composition API, and Pinia
The most immediate change you will encounter is the standardization of Vite as the build tool. Shopware 6.7 eliminates complex Webpack configurations in favor of Vite, delivering lightning-fast hot module replacement (HMR) and optimized production builds out of the box. This ensures your development workflow remains agile, allowing you to iterate on components without waiting for recompilation.
The core Vue infrastructure now strictly adheres to the Composition API. While Vue supports Options API, Shopware's SDK and recommended patterns utilize Composition API exclusively. This provides superior type inference, allows for logical grouping of state and logic via composables, and enhances code reusability.
State management has been unified around Pinia. The platform deprecates scattered plugin-based state updates in favor of centralized Pinia stores. This consolidation streamlines data flow, making it easier to track changes across complex features like the cart, user session, and navigation trees.
The Block System and Component Registration
Shopware 6.7 introduces a decoupled rendering engine driven by the Block System. Content elements are no longer hardcoded into templates; instead, they are defined as JSON structures in the backend and rendered dynamically by Vue components. This enables drag-and-drop flexibility while maintaining performance benefits through client-side hydration.
For developers, this means custom blocks must be registered to map backend definitions to Vue components. To register a custom block, you extend the CmsBlockRegistry within your storefront extension or theme. Crucially, Shopware 6.7 enforces type safety during registration. You must define props that strictly match the block configuration defined in the backend schema. This prevents mismatches between design and data structure at runtime.
// Example of registering a custom block in 6.7
import { CmsBlockRegistry } from '@shopware-pwa/cms-base-adapter';
import MyCustomBlock from './components/MyCustomBlock.vue';
export function registerCmsBlocks(registry: CmsBlockRegistry) {
registry.register({
componentName: 'my-custom-block',
blockClass: 'block-my-custom',
component: MyCustomBlock,
});
}
Unified Data Access via Shopware PWA SDK
Shopware 6.7 promotes the Shopware PWA SDK for all frontend implementations, even when building native storefronts rather than progressive web apps. The @shopware-pwa/frontends-core-vue package provides utilities that abstract API complexity and handle context-aware requests automatically.
Context and Composables
Data access is centralized through the useShopwareContext composable. This hook provides access to clients for products, navigation, checkout, and more, while ensuring all requests respect the current sales channel context, customer group pricing, and currency settings.
The SDK also introduces createProductSearchParams, a helper function that constructs query structures compliant with Store API v2. Using this helper ensures type-safe parameter generation and reduces the risk of malformed requests.
Here is a practical example of a custom Vue component fetching products in Shopware 6.7:
<template>
<section class="featured-products">
<h2>New Arrivals</h2>
<div v-if="loading" class="spinner">Loading...</div>
<div v-else class="grid">
<article v-for="product in products" :key="product.id" class="card">
<img :src="getThumbnailUrl(product.cover)" alt="Product image" />
<h3>{{ product.name }}</h3>
<p class="price">{{ formatPrice(product.price?.[0]?.gross) }} €</p>
</article>
</div>
</section>
</template>
<script setup lang="ts">
import {
useShopwareContext,
createProductSearchParams,
useCart
} from '@shopware-pwa/frontends-core-vue';
import { ref, onMounted } from 'vue';
import type { ProductListingResult } from '@shopware-pwa/storefront-api-ts';
const { context, clients } = useShopwareContext();
const cart = useCart();
const products = ref<ProductListingResult['elements']>([]);
const loading = ref(false);
onMounted(async () => {
loading.value = true;
try {
// Create type-safe search parameters
const params = createProductSearchParams({
limit: 12,
filter: [
{
field: 'active',
operator: '=',
value: true
},
{
field: 'categoryIds',
operator: 'contains',
value: ['YOUR_CATEGORY_UUID']
}
]
});
// Fetch via SDK client with automatic context injection
const result = await clients.productListingApi.search(
params,
context.shopwareContext
);
if (result?.elements) {
products.value = result.elements;
}
} catch (error) {
console.error('Product fetch failed:', error);
} finally {
loading.value = false;
}
});
// Helper to format price based on context
function formatPrice(price?: number): string {
return new Intl.NumberFormat(context.shopwareContext.currentCurrency?.isoCode, {
style: 'currency',
currency: context.shopwareContext.currentCurrency?.isoCode
}).format(price || 0);
}
function getThumbnailUrl(cover: any): string {
return cover?.url || '/placeholder.png';
}
</script>
This snippet demonstrates key 6.7 practices:
- Script Setup: Using
<script setup lang="ts">leverages the Composition API and provides full TypeScript support. - SDK Integration:
useShopwareContextandclients.productListingApihandle authentication and context resolution automatically. - Type Safety: Types are imported from
@shopware-pwa/storefront-api-ts, ensuring your variables match the API response structure.
Hydration, Performance, and Core Web Vitals
Shopware 6.7 prioritizes performance metrics like LCP and CLS. The storefront utilizes advanced hydration strategies to minimize time-to-interactive. When building custom components, avoid blocking the main thread during the mount phase. Use v-show over v-if for elements that exist in the DOM but should be hidden, as this preserves the hydration state more effectively.
For heavy interactive components, consider implementing selective hydration. The SDK allows you to defer hydration until a component enters the viewport or the main thread is idle, rendering it as static HTML initially. This strategy can significantly improve your LCP scores by reducing the JavaScript payload processed during the critical rendering path.
Migration Tips and Developer Experience
If you are migrating from Shopware 6.5, be aware of breaking changes:
- Asset Pipeline: Custom assets must now use the Vite pipeline integration. Ensure your
vite.config.jscorrectly resolves Shopware aliases. - Global Registry: Global component registration via the legacy plugin system is deprecated. Use explicit imports or module federation patterns supported by Vite.
- Validation: The SDK uses Zod for runtime validation. Rely on these inferred types rather than manual interfaces to stay in sync with API updates.
- CLI Improvements: Running
shopware new storefrontnow generates a Vite-based scaffold with pre-configured TypeScript, ESLint, and Prettier settings tailored for Shopware best practices.
Cart State Management
The cart state is managed via a dedicated Pinia store accessible through the useCart composable. This provides reactive access to cart items, prices, and promotions. In 6.7, all cart mutations are centralized, making it safer to implement custom checkout flows or cart rules. Always use the provided actions like addItemToCart or removeItemFromCart rather than mutating the store directly to ensure persistence and event synchronization.
Conclusion
Shopware 6.7 represents a significant leap forward in frontend development capabilities. By embracing Vue.js best practices, the PWA SDK, and modern build tools, Shopware empowers developers to create high-performance, scalable storefronts with improved maintainability. The emphasis on type safety, composables, and the block system provides a flexible foundation that adapts to diverse business needs without compromising developer productivity.
As you build with Shopware 6.7, leverage the comprehensive SDK documentation and community resources. The new architecture is not just an upgrade; it is an opportunity to deliver e-commerce experiences that are faster, more secure, and easier to scale than ever before.