Storefront Boilerplate
Changelogs of Storefront Boilerplate
@scayle/storefront-boilerplate-nuxt -> Changes for Nuxt 3-based Storefront Boilerplate
1.5.0
🔥 Highlights
🤝 Taking the First Steps Towards Enhanced Accessibility
This release marks the beginning of a dedicated effort to make Storefront truly inclusive for all users. We've taken the first steps by enhancing keyboard navigation, providing detailed alt text descriptions for product images, and ensuring proper language declaration for screen readers. These are just the initial steps in a long-term commitment to accessibility, with further enhancements planned in future releases.
🧪 Quality Assurance Through Rigorous Testing
The team focused on expanding test coverage across critical user flows, including checkout, basket functionality, the Country Detector, and product listing pages. By addressing issues that could lead to instability and implementing stricter testing standards, this release strengthens the Storefront's reliability and minimizes the risk of errors, ultimately benefiting the end user.
🕹️ Streamlined User Experience
This release prioritizes a smoother, more visually appealing experience for every user. The header has been refreshed with a redesigned ShopSelector component and updated styling, aligning with a modernized look and feel across Storefront.
⚓ A More Stable and Reliable Foundation
Beyond the visible changes, this release includes numerous improvements that bolster the platform's stability and reliability. Addressing issues like inconsistent image heights, inaccurate price rounding in filters, and conflicts with the Country Detector modal ensures a smoother user experience with fewer unexpected errors. These under-the-hood enhancements contribute to a more robust and dependable Storefront for all users.
Additionally, enabling Brotli compression by default for the Storefront Cache significantly reduces page load times, creating a snappier, more responsive browsing experience.
🚀 Major Changes
- [Architecture] Update default
node
version tov22
- [Accessibility] Enhanced the accessibility of the ShopSwitcher component by adding
aria-*
attributes to provide better context and functionality for assistive technologies. Additionally, we optimized keyboard navigation to ensure a smooth and intuitive experience for all users. - [Architecture] Introduced
LocalizedLink
, a new wrapper component built around the existingSFLink
of the local UI module. This component simplifies the implementation of localized links across the UI, ensuring a smoother experience for international shops. - [Header Refresh] The ShopSelector component has been redesigned with an updated look and feel for a more intuitive and user-friendly experience.
- [Header Refresh] Updated the header design with a fresh look to align with the new PLP and PDP.
- [Product Price] Implemented a feature to display the lowest price observed within the last 30 days alongside the current product price.
💅 Minor Changes
- [Accessibility] Added the
lang
attribute to the<html>
tag across all pages. This enhancement explicitly defines the page's default language, improving accessibility for screen readers and other assistive technologies while also aiding search engines in properly indexing and displaying our content. - [Architecture] Improved page load speed by enabling Brotli compression by default for cached data. This optimization can be customized via the
NUXT_STOREFRONT_STORAGE_CACHE_COMPRESSION
environment variable or thestorefront.storage.cache
option innuxt.config.ts
. - [Architecture] We've decoupled localization functionality from individual local modules, leading to a more modular and maintainable codebase. This change paves the way to pass translated strings directly from the primary application into the respective module code.
- [CMS] Fixed handling of partial story data structures in Contentful stories of content and service pages.
- [Country Detection] Enhanced the
closeModal()
function within our Country Detection tests to include a check for the modal's visibility on page load. This improvement ensures greater test stability, particularly when the test suite is executed from a different time zone than the targeted shop, as it accounts for potential modal visibility differences based on location and time. - [E2E] Implemented end-to-end tests (
e2e-CountryDetector.spec.ts
) to ensure robust functionality of the Country Detector feature. These tests cover key user flows such as closing the modal window, switching to a different shop, and remaining in the initial shop. - [E2E] Improved the stability of our Checkout end-to-end tests when running in parallel by assigning a dedicated test user to each browser. This prevents conflicts that can occur when multiple tests interact with shared user data (like order information) simultaneously, leading to more reliable and consistent test results.
- [Internationalization]: Improved the localization handling within the local CMS module, ensuring accurate and efficient handling of multilingual content for a smoother user experience across all supported languages.
- [PDP / Subscription] Improved
getVariant()
method to optionally handle exact product variant ID when the parameter is passed from the test. - [Product] Resolved the
Extraneous non-props attributes
warning within theProductPrice.vue
component. This ensures better code quality, making the component more readable and maintainable. - [Promotion] Updated the
getPromotionGiftProducts
method to exclude sold-out promotion gift items, improving API response efficiency. - [Search] Fixed an issue causing multiple requests to the
getSearchSuggestions
endpoint for a single user query. This reduces server load and improves the responsiveness of search suggestions. - [Unit testing] Introduced the factory pattern for creating reusable mock data structures in unit tests using
fishery
Patch Changes
- [Accessibility] Enhanced the
useDropdownKeyboardBehavior
function to prevent potential conflicts. This is done by limiting its key-down event listeners to elements within the dropdown itself. It ensures that keyboard interactions are correctly scoped and do not unintentionally affect other page elements. - [Accessibility] Improved accessibility of all product images by implementing detailed alt texts. This descriptive text, which now includes the product's brand, name, color, and relevant contextual information (such as gallery index or selected state), provides valuable information to users who are visually impaired, enhancing their overall browsing experience.
- [Basket] Campaign discounts are now clearly displayed within the basket summary, providing users with a transparent and accurate breakdown of their potential savings.
- [Cleanup] Remove unused components:
components/addOns/AddOnsSelector.vue
product/card/ProductDetailsSkeleton.vue
product/promotion/gifts/ProductPromotionGiftImageGallery.vue
modules/ui/runtime/components/ThumbnailSlider.vue
- [CMS] Fixed inconsistent heights of teaser images on product listing pages.
- [E2E] Addressed an issue affecting PDP end-to-end tests specifically within Chrome Mobile, where clicking the Variant Picker was frequently unsuccessful. While Playwright implements automatic retries for such actions, this often resulted in test timeouts. As the issue appears isolated to Chrome Mobile, we've introduced
{ force: true }
to thevariantPicker.click()
action. This is intended to bypass the problematic default click behavior and ensure consistent test execution across all browser environments. - [E2E] Addressed an issue affecting sticky elements on scrolled pages in Mobile Safari. The solution replaces
mouse.wheel()
withwindow.scrollTo()
for improved accuracy and reliability. - [E2E] Enhanced Homepage end-to-end tests by refining how links are identified. We've transitioned from user-facing selectors (
getByRole('link')
) to a more comprehensive approach using (page.locator('a')
). This ensures that we catch all links within the page, improving the thoroughness of our tests. We've also introduced a short delay usingpage.waitForLoadState('domcontentloaded')
after each page visit within our Homepage end-to-end tests. This prevents issues that can arise when tests run faster than the page can load, leading to more stable and reliable test results. - [E2E] Enhanced our Playwright end-to-end testing suite by integrating two new TypeScript linting rules within the
eslint.config.mjs
configuration:no-floating-promises
: This rule enforces the use of await for any call that returns a Promise, preventing unintentional side effects and ensuring that asynchronous operations are handled correctly within our tests.await-thenable
: This rule complementsno-floating-promises
by specifically targeting instances where await is used unnecessarily with values that are not Promises. This helps maintain consistency and clarity within our asynchronous code.
- [E2E] Enhanced PDP end-to-end testing reliability when adding products to the basket by implementing a
networkidle
wait state, ensuring all necessary network requests are complete before proceeding with the test steps. - [E2E] Enhanced the happy path end-to-end test (
e2e-happy-path.spec.ts
) to close the Country Detector modal window. This prevents potential blockages during test execution, leading to more reliable and consistent test results. - [E2E] Implemented a standardized method for closing the Country Detector modal on page load across all relevant tests. This prevents potential conflicts and ensures a smoother, more reliable testing process.
- [E2E] Implemented various improvements to our end-to-end tests, making them more adaptable to data changes and reducing the likelihood of false positives. This ensures the tests remain robust and reliable even as the data evolves.
- [E2E] Improved the resilience of our PLP end-to-end tests by modifying the sibling product selection logic. Tests now dynamically target the first available product within a PLP category page instead of relying on a fixed product ID. This change ensures that tests remain valid even if the order or availability of products fluctuates.
- [E2E] Improved the robustness of the Country Detector shop switcher end-to-end test by incorporating the
first()
method. This ensures we consistently select the first matching shop element in cases where multiple options are present, preventing potential test ambiguities and enhancing overall reliability. - [E2E] Improved the stability of our Basket end-to-end tests when running in parallel by assigning a dedicated test user to each browser. This prevents conflicts that can occur when multiple tests interact with shared user data, leading to more reliable and consistent test results.
- [E2E] Improvements in End-to-End test suite for PLP filters - Improved the accessibility and testability of Min and Max price input fields by adding the
data-testid
attribute.- Introduced the
openFilters()
method to theproductListingPage
class, simplifying the distinction between mobile and desktop test flows. - Updated the
Sale
filter switch element locator inplpFilters
to reflect recent UI changes. - Enhanced Filter tests (
e2e-Plp.spec.ts
) to handle deep links with predefined filters more reliably and addedpage.waitForLoadState('domcontentloaded')
for increased stability.
- Introduced the
- [E2E] Improvements in End-to-End test suite for Wishlist:
- Simplified the
productBrand
locator for greater reliability. - Tests related to adding products to the basket from the Wishlist have been temporarily skipped due to ongoing feature development. These tests will be reintroduced once the related functionality is fully implemented.
- Simplified the
- [E2E] Improvements in End-to-End test suite of the PLP - Removed unnecessary navigation steps leading to the category page, optimizing test execution speed. - Improved the stability of add / remove Wishlist tests by incorporating additional DOM element waits.
- [E2E] Introduced page title checks to our PLP and PDP end-to-end tests. This ensures that the correct page titles are displayed to users, contributing to a smoother and more understandable browsing experience.
- [E2E] Made Filters deep-link test case on Product Listing Page more generic by excluding "Brand" filter.
- [E2E] Optimized mobile search tests by streamlining the
exactProductItem
locator to be more robust and less prone to errors and removing a redundant check for search category list visibility withinmobileNavigation.ts
. The test now directly verifies if the desired list item is visible and proceeds to click it, resulting in a more efficient and stable interaction flow. - [E2E] Removed the serial execution constraint from Basket test cases, allowing them to run concurrently and further reducing overall test execution time.
- [E2E] Streamlined our Add to Basket end-to-end tests by combining the guest user and logged-in user flows. This change results in:
- Improved Stability: Reduced the potential for inter-test interference during parallel execution.
- Faster Execution: Eliminated redundant steps by merging separate test cases.
- Expanded Coverage: Added a new assertion to verify that products remain in the basket after user authentication, covering a crucial aspect of the user journey.
- [Lighthouse] Implemented optimizations to significantly reduce the execution time of Lighthouse tests, enabling us to get quicker feedback on performance and identify areas for improvement more efficiently.
- [Lighthouse] The lighthouseAudit.ts script now accepts a viewportSize parameter, allowing users to run Lighthouse audits simulating either mobile or desktop environments. This improves the accuracy of performance and accessibility assessments for different device types.
- [PDP] Removed the unnecessary close icon between the size and quantity selectors.
- [PLP] Fixed price rounding in the price filter.
- [UI] Improved code consistency and readability by replacing unnecessary, arbitrary values in Tailwind classes with their more semantic equivalents. This makes our styling easier to understand and maintain.
- [UI] Removed the colons from the Countdown widget to create a cleaner and more visually appealing display.
🏡 Dependency updates
- Added dependency
@vueuse/[email protected]
- Added dependency
@vueuse/[email protected]
- Added dependency
[email protected]
- Added dependency
[email protected]
- Added dependency
@testing-library/[email protected]
- Added dependency
@testing-library/[email protected]
- Added dependency
[email protected]
- Updated dependency
@contentful/[email protected]
to@contentful/[email protected]
- Updated dependency
@contentful/[email protected]
to@contentful/[email protected]
- Updated dependency
@scayle/[email protected]
to@scayle/[email protected]
- Updated dependency
@scayle/[email protected]
to@scayle/[email protected]
- Updated dependency
@scayle/[email protected]
to@scayle/[email protected]
- Updated dependency
@storyblok/[email protected]
to@storyblok/[email protected]
- Updated dependency
@storyblok/[email protected]
to@storyblok/[email protected]
- Updated dependency
@storyblok/[email protected]
to@storyblok/[email protected]
- Updated dependency
@vueuse/[email protected]
to@vueuse/[email protected]
- Updated dependency
@vueuse/[email protected]
to@vueuse/[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[email protected]
- Updated dependency
@nuxtjs/[email protected]
to@nuxtjs/[email protected]
- Updated dependency
@nuxtjs/[email protected]
to@nuxtjs/[email protected]
- Updated dependency
@scayle/[email protected]
to@scayle/[email protected]
- Updated dependency
@types/[email protected]
to@types/[email protected]
- Updated dependency
@types/[email protected]
to@types/[email protected]
- Updated dependency
@typescript-eslint/[email protected]
to@typescript-eslint/[email protected]
- Updated dependency
@typescript-eslint/[email protected]
to@typescript-eslint/[email protected]
- Updated dependency
@upstash/[email protected]
to@upstash/[email protected]
- Updated dependency
@vitest/[email protected]
to@vitest/[email protected]
- Updated dependency
@vue/[email protected]
to@vue/[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
1.4.0
🔥 Highlights
🛍️ New Product Detail Page
This release includes a newly refreshed Product Detail Page with an improved design, better accessibilty and extendability and more test coverage.
🧪 PDP E2E tests
In this release we've also added a new set of E2E tests to cover the product detail page.
📦 Removing Vue component auto imports
As part of our work to remove automatic imports, in this release Vue components will no longer be auto-imported. We've also added some ESLint rules to cover unimported components.
💅 Minor Changes
- Removed boolean props on
Modal.vue
to control styling. Instead styling is done by adding styles to the<SFModal>
and its content. - Added skeleton loader for the product detail page.
- Added PDP E2E tests, first phase.
- Disabled auto-imports for Vue components
- Simplified the wishlist card by utilizing the plain product card and eliminating all basket-related actions.
- The basket does not allow quantity > 50. Therefore, we limit the quantity on the PDP to 50.
- Replaced
InputToggle
withSwitch
component - Enhanced product card component by removing slots, simplifying the HTML structure and removing unnecessary slots.
🩹 Patch Changes
- Fixed placement of price within the
ProductCardDetails.vue
- Product color is now mapped by attribute value instead of ID
- Handled possibly undefined
orderData
when calculatingdeliveryDate
on Order Success page - Removed unused
useWishlistItem
anduseWishlistItemActions
from the project - Fixed an issue on CMS content pages with empty teaser image leading to unnecessary white space
- Replaced getters and setters across the app with
defineModel
- End-to-End and Lighthouse tests adaptions to match latest changes in Storefront Boilerplate.
- Take campaign discounts into account when displaying prices on a product card
- Cleanup image utilities to always use
primaryImage
🏡 Dependency updates
- Added dependency
@vueuse/[email protected]
- Added dependency
@vue/[email protected]
- Updated dependency
@scayle/[email protected]
to@scayle/[email protected]
- Updated dependency
@scayle/[email protected]
to@scayle/[email protected]
- Updated dependency
@scayle/[email protected]
to@scayle/[email protected]
- Updated dependency
@storyblok/[email protected]
to@storyblok/[email protected]
- Updated dependency
@storyblok/[email protected]
to@storyblok/[email protected]
- Updated dependency
@storyblok/[email protected]
to@storyblok/[email protected]
- Updated dependency
@types/[email protected]
to@types/[email protected]
- Updated dependency
@vercel/[email protected]
to@vercel/[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
@changesets/[email protected]
to@changesets/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[email protected]
- Updated dependency
@nuxtjs/[email protected]
to@nuxtjs/[email protected]
- Updated dependency
@scayle/[email protected]
to@scayle/[email protected]
- Updated dependency
@types/[email protected]
to@types/[email protected]
- Updated dependency
@typescript-eslint/[email protected]
to@typescript-eslint/[email protected]
- Updated dependency
@typescript-eslint/[email protected]
to@typescript-eslint/[email protected]
- Updated dependency
@upstash/[email protected]
to@upstash/[email protected]
- Updated dependency
@vitest/[email protected]
to@vitest/[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
1.3.0
🔥 Highlights
🌍 Introducing Country Detection
The Storefront now includes basic functionality to detect a user's country without relying on 3rd-party services. If a user visits a shop from a different country than the one detected, a shop/country switcher modal will appear, offering the option to switch to the appropriate local or global shop or stay on the current one
How it works
In the onMounted
hook, we look up the country of the user and check if it matches the current shop. If it does not match, we try to find a shop which does match that country and prompt the user to switch to the other shop. When a user is logged in or has already declined the prompt, we no longer show the dialog.
Disabling
If you want to disable this feature, remove the <CountryDetection/>
component from the default.vue
layout.
Customizing
The default implementation of the country detection uses the timezone of the browser to assume the user's country. If you would like to use a different method such as GeoIP lookup, the getCurrentCountryFromTimezone
function can be easily swapped out. The replacement function should return a single country code which represents the user's country, or undefined
if one cannot be found. Or in other words a function which matches the interface () => string | undefined
It's also possible to customize the getShopsForRegion
function. The default implementation will search the available shops for those which match the detected region. If there are multiple matches, multiple options will be presented in the dialog. A fallback shopId
can be passed as the second argument. This is useful if you have a global shop. When no shop matches the user's region, this fallback will be used instead. If there are no matches and a fallback is not specified, the user will not be prompted.
The country names shown in the prompt use the default translation of the shop's country code. If you would like to override this behavior, extend the translations file with the key country_selection.override_codes.CODE
. The code should be uppercase.
🧪 Playwright replaces Cypress as new End-to-End testing solution
We have fully transitioned from Cypress to Playwright as our End-to-End testing solution, enhancing overall test coverage in the process. Additionally, we’ve integrated Lighthouse performance testing to further improve application quality.
For more information check out the Storefront End-To-End Testing Guide in the SCAYLE Resource Center
🛍️ PLP Performance Improvements
We’ve started further refining the performance of the new Storefront PLP. This includes resolving existing hydration issues, resulting in unnecessary partial re-rendering, optimizing the wishlist icon toggling for a more responsive user experience, as well as improving the responsiveness when switching between categories.
🗞️ CMS Integration Stability Improvements
We’ve updated the CMS integration of Storefront, enhancing both Storyblok and Contentful to improve overall reliability and stability. These updates include removing unsupported legacy CMS components, optimizing content fetching behavior for certain page types, fixing multiple type-related issues, and consolidating CMS credential handling along with redundant plugin initialization.
🚀 Major Changes
- [Sorting] Introduced "Smart Sorting Keys" as new default sorting.
To learn more about Smart Sorting Keys, visit the SCAYLE Resource Center / Product Sorting. - [E2E] Removed
Cypress
and finished migration toPlaywright
as End-to-End testing suite - [Country Detection] Added
getCurrentCountryFromTimezone
util function to determine user's country from the browser's timezone settings
💅 Minor Changes
- [PLP] Improve responsiveness of switching categories on the product listing page The following changes were made to optimize the navigation that occurs on a category switch:
- Skipping unnecessary middlewares on the navigation
- Not unnecessarily reloading root categories on category switch
- Removing unnecessary awaits within
setup
functions - Passing
categoryId
touseProducts
directly to avoid additional fetches
- [nuxt/image] Renamed the
default
image provider toscayle
to improve clarity and removed the default provider setting in the@nuxt/image
module settings to allow using local images with theNuxtImg
component. For this, place your local image into thepublic/
folder and use the following component:<NuxtImg src="/{fileName}" />
(NOTE: The filename should be without the/public
folder name.) - [Utility Replacement] Replace
yn
with customstringToBoolean
utility function - [Utility Replacement] Replaced
radash.sort
with nativetoSorted
- [Utility Replacement] Replaced functional utility
sort
with nativetoSorted
- [Utility Replacement] Replaced
radash.min
andradash.sum
with custom functional utilities - [Utility Replacement] Replaced
radash.isString
with nativetypeof value === 'string
based check - [Utility Replacement] Replaced
radash.alphabetical
with nativetoSorted
- [Utility Replacement] Replaced functional utility
isEmpty
with nativeObject.values(obj).length === 0
check - [Utility Replacement] Replaced instances of
radash.debounce
withuseDebounceFn
fromvueuse/core
- [Utility Replacement] Replaced
sort
andalphabetical
utils with native functionality - [Utility Replacement] Replace
radash.sleep
withwait
util from@scayle/storefront-nuxt
- [Utility Replacement] Replaced
radash.snake
with custom functional utility - [Utility Replacement] Replaced
radash.unique
with native array operations:arrayValue.filter( (item, index, self) => index === self.findIndex((arrayItem) => arrayItem.value === item.value), )
- [Utility Replacement] Replaced
radash.dash
with native string operationsstringValue .split(/[\s_.-]+|(?=[A-Z][a-z])/) .join('-') .toLowerCase()
- [Utility Replacement] Replaced
radash.isEqual
with customisEqual
util
NOTE: Arbitrary comparison of objects can have a exponentially negative impact on performance the larger the compared objects are. We recommend to compare the values of explicit keys between two objects. - [Utility Replacement] Replaced
radash.pascal
with native string operations:stringValue .split(/[\s_.-]+|(?=[A-Z][a-z])/) .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) .join('')
- [Utility Replacement] Replaced
radash.sum
with native calculations and array operations:array.reduce((acc, item) => acc + item, 0)
- [Utility Replacement] Utility Replacement: Replaced
radash.min
with native array operations:// Plain array // Input: [4, 2, 8, 6] // Output: [2] Math.min(...(numbersArray.length ? numbersArray : [])) // Array containing objects // Input: [{ numberValue: 4 }, { numberValue: 2 }, { numberValue: 8 }, { numberValue: 6 }] // Output: { numberValue: 2 } const getValueForComparison = (objectValue) => objectValue.numberValue array.reduce((a, b) => getValueForComparison(a) < getValueForComparison(b) ? a : b, )
- [Utility Replacement] Replaced
radash.snake
with custom native string operations:stringValue .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) ?.map((x) => x.toLowerCase()) .join('_')
- [Utility Replacement] Replaced
radash.pick
with native array operations:// objectValue: Record<string, unknown> // keysList: string[] Object.fromEntries( keysList .filter((key) => key in objectValue) .map((key) => [key, objectValue[key]]), )
- [Utility Replacement] Replaced
radash.group
with native array operations:arrayValue.reduce( (acc, item) => { const groupId = item.id // Exchange item.id with the appropriate object key if (!acc[groupId]) acc[groupId] = [] acc[groupId].push(item) return acc }, {} as Record<string, TypeOfArrayElement[]>, )
- [Utility Replacement] Replaced
radash.capitalize
with native string operations:stringValue.charAt(0).toUpperCase() + stringValue.slice(1)
- [CMS] Removed auto-import capabilities of local CMS module in favor of using explicit imports for composables and utilities
- [CMS] Removed
axiosFetchAdapter
from Contentful CMS provider integration as Edge deployment support has been dropped - [CMS] Refactored deprecated usage of
pending
fromfetchBySlug
in CMS related components to usestatus
instead - [CMS] Removed unsupported CMS components from Contentful component definitions
SbListingDisruptor
SbNewsletter
SbStore
SbStorePage
- [CMS] Removed unsupported CMS components from Storyblok component definitions -
SbListingDisruptor
SbNewsletter
SbStore
SbStorePage
- [CMS] Fixed issues with fetching CMS data for categories and content pages due to changes in path slugs. Category slugs are expected to now have the form
c/c-{categoryId}
(beforecategory/{categoryId}
), while content pages are expected to have the formcontent/{pageName}
(beforec/{pageName}
). - [CMS] Fixed possible composable misuse errors.
useCMS
has been split intouseCMSBySlug
anduseCMSByFolder
to avoid possible errors, caused by calling a composable outside the appropriate context. This applies to both the Contentful and Storyblok providers.- Before:
const { fetchBySlug } = useCMS('some-key') const { data } = fetchBySlug('some-slug')
- After:
const { data } = useCMSBySlug('some-key', 'some-slug')
- Before:
- [E2E] Added tests for checking basic Home page layout and link validity
- [E2E] Added tests for Wishlist page
- [E2E] Added tests for User Orders page, user with and without orders
- [E2E] Added basic tests for Checkout page
- [E2E] Added tests to check Footer functionalities
- [E2E] Added tests for Promotion banner basic features
- [E2E] Added tests to verify User Account page features
- Verify User personal data layout
- Update birth date with correct and incorrect date format
- Update password matching and non-matching new password
- [E2E] Added tests for Basket:
- Empty state guest and logged in user
- Add to Basket guest and logged in user
- Basket features for regular product
- [E2E] Extended Product Listing Page test with sibling test cases
- [E2E] Extended tests for basket by adding
data-testid
attributes to "Login" and "Continue shopping" buttons in Basket empty state - [E2E] Set up mobile testing in Playwright to cover Chrome and Safari
- Adaption of test
e2e-happy-path.spec.ts
to work with mobile navigation
- Adaption of test
- [E2E] Extends tests for Search to run on mobile devices
- Added mobile specific locators to work with navigation and search features on mobile devices.
- [E2E] Optimizing tests to run faster and be more resilient
- Added
{ waitUntil: 'commit' }
or{ waitUntil: 'load' }
topage.goto()
method where possible - Implemented retry mechanism using
expect()
to handle callback function with the Playwright built-intoPass()
method to avoid possible failures caused by hydration - Added
test.step
into some tests with more steps to complete, to achieve better readability in the reports
- Added
- [E2E] Adapting E2E tests to use new test ID attributes due to the migration of existing
data-test-id
todata-testid
. This enables Playwright to use built-in locatorgetByTestId()
- Deleted existing PLP
.spec.ts
files and added all PLP tests toe2e-Plp-spec.ts
, so this file now contains all current and future PLP tests. Having multiple tests within one.spec.ts
file follows the logic of having multiple tests within one test suite related to respective application section. - Added test to check add/remove to/from Wishlist from PLP page
- Deleted existing PLP
- [UI] Updated the
Modal
component to use native HTML<dialog>
element - [UI] Removed unused
SFSlideshow
component
🩹 Patch Changes
- [CMS] Fixed footer social media icons not being visible even though content had been set via CMS provider
- [CMS] Fixed issues with Storyblok CMS setup by removing legacy runtime option (
public.storyblok
innuxt.config.ts
) and ensuring the necessaryaccessToken
is not overriden during Storyblok module initialization. - [CMS] Fixed issues with Storyblok CMS setup where the
@storyblok/vue
plugin has been initialized twice, resulting in misleading runtime warnings and errors. - [CMS] Replaced Storyblok RichTextResolver class with dedicated
@storyblok/richtext
dependency - [CMS] Removed deprecated
AppFooter
component as it has been replaced byCMSAppFooter
- [CMS] Fixed handling of empty Contentful CMS link values resulting in application crashes
- [CMS] Fixed type errors in Contentful's
useCms
composable - [Code Style] Applied consistent
v-bind
style and enforced through lint rule - [Code Style] Enabled and enforced
tailwindcss/no-custom-classname
lint rule - [Code Style] Resolved
no-explicit-any
issues in Vue components - [Code Style] Resolved
no-explicit-any
warnings in CMS modules - [Code Style] Enabled and enforced
no-explicit-any
lint rule and resolved remaining warnings - [Code Style] Resolved
no-explicit-any
warnings in tracking composables and utils - [Config] Removed duplicate TailwindCSS generation
- [Config] Resolved nuxt-i18n issues with domain shop selection
- Remove unused variable from
.env.example
- Use unique placeholder domains in nuxt-i18n config
- Replace the deprecated
iso
option withlanguage
- Remove unused variable from
- [Config] Removed
vite.build.rollupOptions.external
option to handle former@scayle/omnichannel-nuxt
Nuxt 2-support for@nuxtjs/composition-api
innuxt.config.ts
- [Config] Enabled
noImplicitAny
intsconfig.json
- [Config] Fixed missing image modifiers in SCAYLE provider for
nuxt/image
module - [Config] Enable cookieStore option to resolve Lighthouse
bfcache
audit - [PLP] Fixed focus behavior to don't focus close button in
FilterSlideIn
- [PLP] Fixed hydration error on product list caused by invalid HTML (nested anchor elements)
- [PLP] Only fetch necessary product attributes from SAPI to reduce payload size
- [PLP] Improve perceived performance of the wishlist toggle by optimistically changing the icon
- [PLP] Tweaked
useFilter
anduseProductsByCategory
to use the same parameters to avoid discrepancies - [PLP] Brought back
details
slot onProductCard.vue
which had been removed previously - [PLP] Used correct product name in URL when linking to PDP
- [PLP] Fixed current
categoryID
not being passed toFilterSlideIn
- [PLP] Used responsive classes instead of rendering different DOM based on size
- [PLP] Fixed height of
FilterSlideIn
on mobile devices - [Translations] Fixed the english translation for free gifts on the PDP
- [UI] Fixed scaling issue with large logout button on
AccountPage
🏡 Dependency Updates
- Added dependency
@storyblok/[email protected]
- Removed dependency
[email protected]
- Removed dependency
[email protected]
- Removed dependency
[email protected]
- Updated dependency from
@contentful/[email protected]
to@contentful/[email protected]
- Updated dependency from
@contentful/[email protected]
to@contentful/[email protected]
- Updated dependency from
@scayle/[email protected]
to@scayle/[email protected]
- Updated dependency from
@storyblok/[email protected]
to@storyblok/[email protected]
- Updated dependency from
@tailwindcss/[email protected]
to@tailwindcss/[email protected]
- Updated dependency from
@tailwindcss/[email protected]
to@tailwindcss/[email protected]
- Updated dependency from
@types/[email protected]
to@types/[email protected]
- Updated dependency from
@vueuse/[email protected]
to@vueuse/[email protected]
- Updated dependency from
@vueuse/[email protected]
to@vueuse/[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
@changesets/[email protected]
to@changesets/[email protected]
- Updated dependency from
@nuxt/[email protected]
to@nuxt/[email protected]
- Updated dependency from
@nuxt/[email protected]
to@nuxt/[email protected]
- Updated dependency from
@nuxtjs/[email protected]
to@nuxtjs/[email protected]
- Updated dependency from
@types/[email protected]
to@types/[email protected]
- Updated dependency from
@typescript-eslint/[email protected]
to@typescript-eslint/[email protected]
- Updated dependency from
@typescript-eslint/[email protected]
to@typescript-eslint/[email protected]
- Updated dependency from
@vitest/[email protected]
to@vitest/[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
- Updated dependency from
[email protected]
to[email protected]
1.2.0
🔥 Highlights
🛍️ New Product Listing Page
This release not only introduces a fresh look and feel of the Product Listing Page but also brings enhanced functionalities to improve the user experience:
- Advanced filtering: Improved filters to help users easily find the products they are looking for by dynamically updating filters and displaying only relevant filter options.
- Intuitive category navigation: Navigate seamlessly between nested and root categories.
- Enhanced badges: Badges highlight features, novelty, or other product attributes. This includes the "New In" badge for newly added products, custom badges for specific attributes (e.g., sustainability), and the "Already in Basket" badge to help users avoid duplicate selections.
Moreover, the new page is built with a simple and easily customizable codebase, ensuring that it can be tailored to meet your specific needs.
To learn more about the main components, data fetching and filtering logic, and customization opportunities, please refer to our Storefront Guide.
🔀 Multiple paths per shop
We now have the ability to configure multiple URL paths for single shops (per shopId
), where before could only handle one URL path per single shop. As example, this allows the same shop to be reachable under multiple different paths like your-shop.com/en-gb/
, your-shop.com/en-us/
, your-shop.com/en-au/
. This reduces the need for excessive configurations, while simultaneously enhancing performance.
The path
property in the shop config can now be defined as an array of strings. If this is the case, multiple path prefixes will point to the same shop. For example, with the config { path: ['en', 'en-US'], shopId: 1001 }
both example.com/en
and example.com/en-US
will use shop 1001. Because it is the same shop, /en
and /en-US
will have the same locale and share user sessions, baskets and wishlists. The first path in the array will be considered the default path and used for API calls.
🔭 Dedicated NPM package for OpenTelemetry integration
A while back we introduced support for OpenTelemetry. OpenTelemetry is an open-source standard for instrumenting your applications, providing valuable insights into performance and behavior. It allows you to collect, process, and export telemetry data like metrics, logs, and traces to various backend platforms, enabling better monitoring and troubleshooting. As part of our commitment to contributing more to the open-source community, we've published the previous integration as a dedicated NPM package, making it widely accessible and improving its capabilities.
🚀 Major Changes
- Use the newly introduced
useRpcCall
helper composable (More information can be found in the SCAYLE Resource Center) - Replace the internal OpenTelemetry module with the
@scayle/nuxt-opentelemetry
package - Re-enable caching for Vercel deployments
- Retrieve access token for
subscription-overview
web component viagetAccessToken
RPC - Disabled
imports.autoImports
innuxt.config.ts
. All required composables, utils and constants now need to be explicitly imported. - Added a hook within
nuxt.config.ts
to extend thevite
client build configuration and allow for improved manual chunking ofstoryblok
,contentful
andaxios
dependencies. This results in smaller client chunks below 500kb.
💅 Minor Changes
- Migrate configuration key
bapi
tosapi
withinnuxt.config.ts
- Renamed buildtime environment variable
DISABLE_PAGE_CACHE
toPAGE_CACHE_DISABLED
- Renamed buildtime environment variable
ENABLE_CONFIG_LOG_BUILD
toCONFIG_LOG_BUILD_ENABLED
- Renamed buildtime environment variable
ENABLE_CONFIG_LOG_PRETTIER
toCONFIG_LOG_PRETTIER_ENABLED
- Renamed buildtime environment variable
ENABLE_CONFIG_LOG_RUNTIME
toCONFIG_LOG_RUNTIME_ENABLED
- Renamed buildtime environment variable
ENABLE_NUXT_DEBUGGING
toNUXT_DEBUGGING_ENABLED
- Show IDP login buttons in
RegisterForm.vue
- Support toggling shop selection modes through a single const
SHOP_SELECTOR_MODE
in the nuxt config - Switch to
ModuleBaseOptions.shops
andShopConfig.shopCampaignKeyword
🩹 Patch Changes
- Add example multi-path shop
- Add missing
diverse
option toUserPersonalInfoForm.vue
- Allow
PromotionList.vue
to scroll to make all promotions accessible on smaller desktop sizes - Disable global components in local
ui
module - Fixed "More"-button of mobile search results now leads to search page
- Fixed disabled sold out sizes when adding wishlist items to the cart
- Hide
UpdatePasswordForm.vue
for IDP user within Account Overview page - Remove
idp
fromAdditionalShopConfig
, as it is available in the base storefront configuration - Remove required rule on
birthDate
field inUserPersonalInfoForm.vue
- Remove unnecessary
await
when using composables - Use integrated
nuxi typecheck
instead of customvue-tsc
typecheck script command - Use unique composable keys for
useOrderDetails
and withinusePromotionGifts
- Wait for user input completion before displaying any errors in the login form
🏡 Dependency Updates
🏘️ devDependencies
- Added
@scayle/[email protected]
- Updated to
@contentful/[email protected]
- Updated to
@contentful/[email protected]
- Updated to
@googlemaps/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@types/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Removed
@opentelemetry/api
- Removed
@opentelemetry/auto-instrumentations-node
- Removed
@opentelemetry/exporter-trace-otlp-proto
- Removed
@opentelemetry/instrumentation
- Removed
@opentelemetry/resources
- Removed
@opentelemetry/sdk-node
- Removed
@opentelemetry/semantic-conventions
- Removed
@vercel/otel
🏠 dependencies
- Updated to
@changesets/[email protected]
- Updated to
@nuxt/[email protected]
- Updated to
@nuxt/[email protected]
- Updated to
@nuxtjs/[email protected]
- Updated to
@nuxtjs/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@types/[email protected]
- Updated to
@typescript-eslint/[email protected]
- Updated to
@typescript-eslint/[email protected]
- Updated to
@upstash/[email protected]
- Updated to
@vitest/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
1.1.0
🔥 Highlights
👓 Live Preview for CMS provider
We have integrated proper Live Preview support for Storyblok and Contentful. This allows to edit the CMS content elements within the respective CMS provider web interface and show the changes immediately in the context of the Storefront application.
🚚 Introduced usage of explicit imports for Vue components
To align more with the JavaScript and TypeScript developer ecosystem, Storefront Boilerplate is slowly moving away on relying on the Nuxt "auto import" feature for dependencies and source code. With the next v1.2
release we will deepen the commitment and will disable the option imports.autoImport
within the nuxt.config.ts
.
As a first step we added explicit imports to all Vue components. As defineProps
, defineEmits
and withDefaults
are Vue compiler macros, they do not need to be imported explicitly and will trigger a compiler warning if done so.
🚀 Major Changes
- Enable live preview for CMS provider
storyblok
- Enable live preview for CMS provider
contentful
- Introduced local module
storefront-eslint-auto-explicit-import
to extendeslint
with explicit import injection - Introduced usage of explicit imports for composables, utilities and framework-specific functionalities in Vue components
- Fixed errors in async composable usage
- This change enables all rules in
@scayle/eslint-plugin-vue-composable
and ensures that all composables in the application conform to best practices regarding asynchronous usage. These changes may fix various bugs relating to reactivity issues. As part of this change, some composables are now entirely synchronous.
- This change enables all rules in
💅 Minor Changes
- Introducing eslint-plugin-vuejs-accessibility for basic accessibility linting of Vue components
- Renamed prop
until
totimeUntil
forSFCountdown
andPromotionCountdown
components to avoid name collision withuntil
from@vueuse/core
- Replace
radash-nuxt
module withradash
as dependency and use explicit imports instead - Share PDP state with
useProductDetailsBasketActions
andProductBasketAndWishlistActions.vue
- Updated mobile sidebar navigation to support expanding and collapsing top-level categories
🩹 Patch Changes
- Ensure
authGuard.global.ts
has user information during SSR - Ensure the OSP only does the user refresh on client side
- Fixed
SFLink
inBreadcrumbs
- Fixed missing error alert on failed login
- Fixed mobile basket layout when there are products with long titles
- Fixed Regenerate the
itemGroup.id
each time an itemGroup is added to the basket - Fixed selected gender being ignored during registration
- Prevent old user data from being applied to the state after
user.forceRefresh()
as happened on the OSP
🏡 Dependency Updates
🏘️ devDependencies
- Added
@typescript-eslint/[email protected]
- Added
@typescript-eslint/[email protected]
- Added
[email protected]
- Added
[email protected]
- Added
[email protected]
- Added
[email protected]
- Added
[email protected]
- Updated to
@changesets/[email protected]
- Updated to
@types/[email protected]
- Updated to
@typescript-eslint/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
🏠 dependencies
- Added
@contentful/[email protected]
- Added
[email protected]
- Removed
radash-nuxt
- Updated to
@contentful/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@types/[email protected]
- Updated to
@vercel/[email protected]
- Updated to
@vueuse/[email protected]
- Updated to
@vueuse/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
1.0.0
🔥 Highlights
🧱 Introducing storefront-ui
local module
We're introducing the first step towards more reusable components, the local storefront-ui
module. It contains most common and reused UI component from across the SCAYLE Storefront Boilerplate. The first iteration consists of most components mostly formerly located within the ./components/ui
directory.
To foster an increased separation of concerns, the local storefront-ui
module also contains composables and utilities that are closely related to the common and reused UI component. Moreover, all components within the the local storefront-ui
module are now prefixed with SF
(configurable via nuxt.config
) when using the components within the SCAYLE Storefront Boilerplate.
📡 Create OpenTelemetry spans for Nitro requests
In addition to initializing the OpenTelemetry SDK, the OpenTelemetry module now instruments incoming requests to the Nitro server. The spans include the matched route name, HTTP method and other request metadata.
Minor Changes
- Implemented an early return in
authGuard.global.ts
for API routes to prevent middleware misuse. - Switched from passing plain
basket-id
andcampaign-key
to passing JWT, containingbasket-id
andcampaign-key
as payload, toscayle-checkout
Patch Changes
- Updated badges to new arguments to use headlineParts as primary source and fallback to basketLabel if headlineParts are not defined.
- Fixed
ProductBadge
translation warnings - Fixed banner price calculation for promotion aggregation
- Fixed contentful Image.vue and contentful ImageText.vue. Only show image when an src link is available. Both image components now behave similar to the storyblok implementation.
- Fixed lost reactivity of
lastLoggedInUser
fromuseLastLoggedInUser()
- Fixed filter reset all button when price is changed
- Fixed new icon on free product
- Added promotion price overlay on PDP
- Improved countdown element style across the basket page and PDP page
- Fixed badges position on mobile
- Added ability to show and hide promotions
- Fixed badge styling in product card
- Switched from
ay-checkout
toscayle-checkout
Webcomponent
🏡 Dependency Updates
🏘️ devDependencies
- Added
@vue/[email protected]
- Added
[email protected]
- Removed
@crowdin/cli
- Updated to
@changesets/[email protected]
- Updated to
@eslint/[email protected]
- Updated to
@nuxt/[email protected]
- Updated to
@nuxt/[email protected]
- Updated to
@nuxt/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@types/[email protected]
- Updated to
@upstash/[email protected]
- Updated to
@vitest/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
🏠 dependencies
- Updated to
@opentelemetry/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@opentelemetry/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@types/[email protected]
- Updated to
@vercel/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
1.0.0-rc.10
🔥 Highlights
📡 HTTP Request tracing with OpenTelemetry
The Storefront Boilerplate now includes a built-in integration with OpenTelemetry. To enable the feature, set the environment variable OTEL_ENABLED
to true
. This will inject additional code into your application's entrypoint which will initialize the OpenTelemetry SDK. Automatic instrumentations as well as instrumentations from storefront-nuxt
will be captured and exported via the OTLP protocol.
Currently, Vercel and Node are the only supported platforms for the OpenTelemetry integration. Setting OTEL_ENABLED
to true
when building for other platforms will have no effect.
You should also set the runtime variable OTEL_SERVICE_NAME
to configure the service name used in traces. e.g. OTEL_SERVICE_NAME=storefront-boilerplate
Note: this variable is used directly by the OpenTelemetry libraries and is not available in the Nuxt runtimeConfiguration
.
🛍️ Improved UX / UI for Promotions
We've redesigned the promotion badges displayed on the Product Listing Page, the Wishlist, and the Basket page. The Badge text originates from Storefront APIs customData
, with headlineParts
in bold and badgeLabel
in regular font. We now implement ellipsis for long badgeLabel
texts.
Please Note: Due to space constraints, the basket page shows only badgeLabel
; if it is missing, it will fallback to headlineParts
.
We have also improved the user experience on the Product Detail page with free gift options. When the condition of a product, that has a free gift option configured, are met, a free gift option will be displayed on the page with a grayed-out overlay. Once conditions are met, a free gift option will be enabled and the user can add a free gift product to the cart.
🔍 Improved linting setup with ESLint v9
The Storefront Boilerplate now includes an improved linting setup. Relying on the new ESLint 9 and @nuxt/eslint
module to provide more project-aware linting. To make configuration more easier the ESLint config has been updated to the new flat config format, allowing for simpler customization and overriding of rules. Additionally the default Storefront ESLint config @scayle/eslint-config-storefront
v4 is now using a subset of opinionated rules of @antfu/eslint-config
.
Minor Changes
- Added subscription cancellation page to the subscription module
- New Price adoptions for basket page for promotions
- Increased eslint
no-composable-after-await
rule error level and fix the issues - Fix caching for domain-based setups where we now consider the host for the SSR cache key.
Additionally, we now set anintegrity
value that invalidates the SSR cache automatically when a new build is deployed. You can control the value through theVERSION
environment variable, which should be set to your current Git short commit sha.
Either you can set this normally during your build processVERSION=147f33d yarn build
or when using the docker imagedocker build --build-arg VERSION=${GIT_SHORT_COMMIT_SHA} -f docker/node/Dockerfile .
Patch Changes
- Removed an unnecessary CSS property which caused a visual bug on basket page
- Resolved a bug that affected the fetching of
combineWith
products - Resolved the issue where the welcome login tab was displayed instead of the registration tab upon clicking the register link.
- Implemented a new utility function to format addresses dynamically. The function adjusts the address format according to the countryCode
🏡 Dependency Updates
🏘️ devDependencies
- Added
"@eslint/[email protected]",
- Added
@nuxt/[email protected]
- Updated to
@nuxt/[email protected]
- Updated to
@nuxtjs/[email protected]
- Updated to
@nuxtjs/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@upstash/[email protected]
- Updated to
@vitest/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
🏠 dependencies
- Added
@opentelemetry/api": "1.8.0
- Added
@opentelemetry/auto-instrumentations-node": "0.45.0
- Added
@opentelemetry/exporter-trace-otlp-proto": "0.51.0
- Added
@opentelemetry/instrumentation": "0.51.0
- Added
@opentelemetry/resources": "1.24.0
- Added
@opentelemetry/sdk-node": "0.51.0
- Added
@opentelemetry/semantic-conventions": "1.24.0
- Added
@vercel/otel": "1.8.2
- Added
knitwork": "1.1.0
- Updated to
@scayle/omnichannel-nuxt": "3.0.0
to be compatible with latest Omnichannel API - Updated to
@scayle/storefront-nuxt": "7.66.4
- Updated to
@storyblok/nuxt": "6.0.10
- Updated to
@storyblok/vue": "8.0.8
- Updated to
@tailwindcss/typography": "0.5.13
- Updated to
cf-content-types-generator": "2.15.1
- Updated to
contentful": "10.9.0
- Updated to
storyblok-js-client": "6.7.3
v1.0.0-rc.9
🔥 Highlights
📖 Introducing Contentful as the new CMS Provider for StorefrontCMS
We've added a Contentful integration as an alternative to using Storyblok as a CMS provider. This allows you to fetch data from Contentful and use it in your SFB. To use this feature, you need to provide your Contentful space ID and access token in the .env
file. You can find these values in your Contentful account settings.
NUXT_PUBLIC_CMS_ACCESS_TOKEN=your-access-token
NUXT_PUBLIC_CMS_SPACE=your-space-id
Once you have added these values, you can use Contentful by selecting the contentful
option in the cms.provider
field of the nuxt.config.ts
file.
export default defineNuxtConfig({
// ...
cms: {
provider: 'contentful',
},
// ...
})
Now you have access to useCMS
composables and fetch data from Contentful in your SFB. useCMS
accepts a string as an argument that will be used for caching purposes and returns a fetchBySlug
function that you can use to fetch data by slug. fetchBySlug
is a wrapper around Nuxt's useAsyncData
and accepts a generic type that you can use to define the shape of the data you are fetching. Here is an example of how you can use this feature:
import type { TypeListingPageSkeleton } from '~/modules/cms/providers/contentful/types/contentful-defs'
const props = defineProps<{
selectedCategory: number | undefined
}>()
const route = useRoute()
if (!props.selectedCategory) {
console.log('No category selected')
}
const { fetchBySlug } = useCMS(`ListingPage-${route.path}`)
const { data } = await fetchBySlug<TypeListingPageSkeleton>(
`categories/${props.selectedCategory}`,
)
🔎 Introducing Search Engine v2
We've implemented and replaced the whole search flow based on the new Storefront API's Search Engine v2
. This includes:
- Overall UI and UX adaptations (header search input, suggestions dropdown, applicable filter indicator, search within the mobile sidebar, etc.)
- Category suggestions that can have filters applied
- Product suggestions that are resolved only by entering the exact ID
- Refined flow when resolving the search term
- Search page usage only as a fallback
Added Subscription Add-on
We've implemented the Subscription Add-ons as a local module. The subscription feature enables customers to subscribe to a specific variant of a product, which is then delivered at regular intervals on a chosen day. This convenience allows customers to make regular purchases effortlessly.
🚀 Major Changes
- Fixed an issue where an empty IDP component was shown when no IDPs were enabled. The
useIDP
composable now returns an empty object when the IDP integration is not enabled. Ensure that the user is redirected to CO when entering the sign-in page with aredirectUrl
parameter. This is now possible with the@scayle/storefront-nuxt@{version}
. We refactored the IDP callback to have its page to ensure we only call the IDP login RPC once. - Improved Storyblok integration through the SCAYLE Panel Add-on and plugin
- Disabled caching for Vercel Deployments Vercel's CDN Caching works slightly differently from the default Nuxt Page caching, which is currently incompatible with our Session handling. To disable all caching for Vercel Deployments, remove any
routeRules
you have configured in yournuxt.config.ts
. - Added ability to scroll to anchor links on the same page. The
Paragraph
component now supports ananchor
prop that will be used to create an anchor target for that paragraph. If you have a Table of Contents and want to link to a specific paragraph, you can use the create links function on any text in your Content to create a link to it. When the user clicks on the link, he will scroll to the paragraph on the page. We also introduced a new component,NestedParagraph,
that allows adding nested paragraphs, for example, for ordered lists.
💅 Minor Changes
- Tweaked account index page to be visually consistent with other account page layouts
- Introduced a new feature for logging both build and runtime configurations Configuration logging can now be toggled on or off using the
ENABLE_CONFIG_LOG_BUILD
andENABLE_CONFIG_LOG_RUNTIME
environment variables. - Added
@scayle/eslint-plugin-vue-composable
This plugin includes three rules@scayle/vue-composable/no-composable-after-await
,@scayle/vue-composable/no-lifecycle-after-await
,@scayle/vue-composable/no-watch-after-await
which catches common errors in composables. You can read more about the plugin here. - The improved user experience of the time box element within the Promotion Banner. Adds a clear understanding of the time left for the promotion to end by providing indicators of the time unit in the time box element for countdowns. The format of the time box element is changed to be more user-friendly with
(D : H : M)
format, or(H : M : S)
format if the promotion lasts less than24H
.
Patch Changes
- Modified paddings of PromotionHurryToSaveBanners to have visual consistency with PromotionItemContent
- Fixed a German translation issue for "save_your_free_gift"
- Fixed promotion automatic discount price on PDP
- Removed full capitalization of PromotionHurryToSaveBanner label
- Handle possible
undefined
results fromuseRpc
calls - Add store address, phone, and open status to the map marker card
- Fixed StoreLocator map covering navigation flyout
- Fixed a z-index issue with the ToastContainer so that notifications are not partially displayed underneath the Promotion Banner
- Adds missing Promotion Banner Link to Promotion Category on mobile view
- Removed dummy non-functional shipment detail link from OrderStatusBar
- An error has been fixed where an attempt was made to access the "document" object during server-side rendering, resulting in an inaccessible Order Success Page (OSP).
- Added translatable string 'pdp.no_product_information_provided' for ProductDescription and ProductCompositionAndCare components instead of static string
🏡 Dependency Updates
🏘️ devDependencies
- Added
@scayle/[email protected]
- Updated to
@crowdin/[email protected]"
- Updated to
@nuxt/[email protected]
- Updated to
@nuxtjs/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@types/[email protected]
- Updated to
@typescript-eslint/[email protected]
- Updated to
@typescript-eslint/[email protected]
- Updated to
@upstash/[email protected]
- Updated to
@vitest/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
🏠 dependencies
- Added
@contentful/[email protected]
- Added
@storyblok/[email protected]
- Added
[email protected]
- Added
[email protected]
- Added
[email protected]
- Added
[email protected]
- Added
[email protected]
- Added
[email protected]
- Removed
[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@tailwindcss/[email protected]
- Updated to
@types/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
1.0.0-rc.08
This release focuses on stabilization and modularization, to improve the technical foundation and developer experience.
🔥 Highlights
✨ Update to Nuxt 3.10.3 and Vue 3.4.21
Storefront Boilerplate now runs on both the latest Nuxt v3.10.3
and Vue v3.4.21
and benefits from a multitude of improvements. To get more details about all the changes see the Official Nuxt 3.10 Announcement Blog and the Official Vue 3.4.21 Changelogs.
📍 SCAYLE Omnichannel Add-on for Storefront
Storefront now supports the SCAYLE Omnichannel Add-on, which includes the StoreLocator
page and StoreAvailability
within the Product Detail Page.
🔭 Additional Tracking Improvements
The included tracking implementation has been refactored and received various improvements to increase the tracking data quality, as well as tracking data reliability.
🚀 Major Changes
- BREAKING: Refactored default
sameSite
cookie settings fromnone
tolax
inconfig/storefront.ts
- Added
StoreLocator
page based on Google Maps andSCAYLE Omnichannel
- Added
StoreAvailability
to Product Detail Page usingSCAYLE Omnichannel
- Added
patch-packages
for managing patches to third-party packages. SeeREADME.md
or thepatches/
directory for an up-to-date listing of currently applied patches.- Patched
unstorage
so the VercelKV driver is not logged asundefined
- Patched
- Removed
auth
config incomposables/useAuthentication.ts
anduseRuntimeConfig().public.storefront.auth
field inconfig/storefront.ts
- Changed public
runtimeConfig
type toModulePublicRuntimeConfig
💅 Minor Changes
- Fixed caching behaviour for account area via
routeRules
innuxt.config.ts
- Fixed wishlist toggle if wishlist data is being toggled and fetched in
components/product/WishlistToggle.vue
- Refactored error message handling during local development mode to show actual error with stack trace
- Fixed product detail page and product listing page (category page) behaviour if basket data is undefined
- Fixed Storyblok CMS data handling in
pages/s/[slug].vue
- Fixed Storyblok CMS components handling in
pages/c/[slug].vue
- Renamed
categoryNotFound
tofoundCategoryByPath
inpages/[...category].vue
- Fixed error handling for non-existing category slug by throwing a
404
error and removed error handling fromlayouts/defaults.vue
- Fixed redirection from the error page to the homepage
- Converted
routeChangeTrackingObserver
to the route middleware and added delayed execution - Fixed redirection behaviour on login from checkout, as it will now redirect after login back to checkout
- Used
onNuxtReady
instead oftryOnMounted
forcomposables/tracking/watchers/useCustomerDataChangeWatcher.ts
and removed user force refresh - Fixed links on Storyblok grid tile, clickable image and banner link
modules/cms/providers/storyblok/components/BannerLink.vue
modules/cms/providers/storyblok/components/ClickableImage.vue
modules/cms/providers/storyblok/components/GridTile.vue
modules/cms/providers/storyblok/components/StoryblokLink.vue
- Fixed category behaviour by using new composable
useCategoryByPath
to source category data inpages/[...category].vue
- Fixed category behaviour by using
stripShopLocaleFromPath
and remove the computed value inpages/[...category].vue
- Refactored root categories logic and implemented app navigation trees
- Added
composables/useCategory.ts
- Added
composables/useNavigationTreeItems.ts
- Added
composables/useRootCategories.ts
- Refactored
components/layout/footer/AppFooter.vue
- Refactored
components/layout/headers/AppHeader.vue
- Refactored
components/layout/headers/HeaderSubNavigation.vue
- Refactored
components/layout/navigation/MobileSidebar.vue
- Refactored
composables/useProductList.ts
- Refactored
pages/[...category].vue
- Added
- Improved tracking behaviour
- Refactored
composables/tracking/events/useUserActionEvents.ts
- Refactored
composables/tracking/watchers/useCustomerDataChangeWatcher.ts
- Refactored
composables/useWishlistPage.ts
- Refactored
nuxt.config.ts
- Refactored
- Fixed promotion handling and hides gifts if minimum order value (
mov
) is not satisfied- Refactored
composables/useBasketItemPromotion.ts
- Refactored
composables/useProductPromotions.ts
- Refactored
composables/usePromotionProgress.ts
- Refactored
utils/promotion.ts
- Refactored
- Adjusted promotion basket gift conditional banner labels
- Refactored
components/basket/promotion/BasketGiftConditionBanner.vue
- Refactored
composables/useBasketItemPromotion.ts
- Refactored
langs/de-DE.json
- Refactored
langs/en-GB.json
- Refactored
langs/en_origin.json
- Refactored
- Adjusted promotion conditional banner on the product detail page
components/basket/promotion/BasketGiftConditionBanner.vue
components/product/promotion/ProductPromotionGiftConditionBanner.vue
composables/useProductPromotions.ts
pages/p/[slug].vue
- Reduced duplicate promotion quantity and cost logic
- Added
composables/usePromotionConditionBanner.ts
- Refactored
components/basket/promotion/BasketGiftConditionBanner.vue
- Refactored
components/product/promotion/ProductPromotionGiftConditionBanner.vue
- Refactored
langs/de-DE.json
- Refactored
langs/en-GB.json
- Refactored
langs/en_origin.json
- Added
- Extracted promotion condition banner to unified component and reuse it
- Added
components/promotion/PromotionGiftConditionBanner.vue
- Refactored
components/basket/promotion/BasketGiftConditionBanner.vue
- Refactored
components/product/promotion/ProductPromotionGiftConditionBanner.vue
- Added
- Replaced used promotion
mov
abbreviation with full keywordminOrderValue
to reduce complexity- Refactored
components/basket/promotion/BasketGiftConditionBanner.vue
- Refactored
components/product/promotion/ProductPromotionGiftConditionBanner.vue
- Refactored
composables/useBasketItemPromotion.ts
- Refactored
composables/useProductPromotions.ts
- Refactored
composables/usePromotionConditionBanner.ts
- Refactored
langs/de-DE.json
- Refactored
langs/en-GB.json
- Refactored
langs/en_origin.json
- Refactored
- Extended End-to-End testing behaviour with promotion features
- Refactored
components/product/promotion/ProductPromotionSelectionModal.vue
- Refactored
components/promotion/PromotionHurryToSaveBanners.vue
- Refactored
composables/useBasketPromotions.ts
- Refactored
composables/useProductPromotions.ts
- Refactored
composables/usePromotionGifts.ts
- Refactored
pages/p/[slug].vue
- Refactored
- Fixed and refactored Identity Provider support
- Added
components/auth/IDPCallback.vue
- Refactored
components/auth/IDPForm.vue
- Refactored
components/auth/SignInForm.vue
- Refactored
components/auth/LoginForm.vue
- Refactored
composables/useAuthentication.ts
- Refactored
config/storefront.ts
- Added
🩹 Patch Changes
- Aligned check icon within colour chip
- Fixed missing flyout close for sub-navigation in
components/layout/headers/AppHeader.vue
- Replaced default Nuxt favicon with SCAYLE favicon in
public/favicon.ico
- Added
immediate: true
to watcher and refactoredcomposables/tracking/watchers/useCustomerDataChangeWatcher.ts
to avoid delayed execution and wrongly reported tracking data - Fixed application crash during server-side rendering while trying to access
window.localStorage
incomposables/useLastLoggedInUser.ts
- Fixed rendering issues with product price by using optional chaining
basketData.value?.items
incomponents/product/ProductPrice.vue
- Set the default TTL of the cache storage provider with Redis to
10
minutes to avoid unlimited cache keys - Replaced translation
Sicht
withAnsehen
for notification CTA - Fixed the wrong config type for
gtm.debug
innuxt.config.ts
- Fixed incorrect triggering of
content_view
tracking event during server rendering inmiddleware/routeChangeTrackingObserver.global.ts
- Hide the scrollbar on the homepage collection content
🏡 Dependency Updates
🏘️ devDependencies
- Updated to
@types/[email protected]
- Updated to
@upstash/[email protected]
- Updated to
@vitest/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
(For detailed changes see Release Notes for Nuxt) - Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
🏠 dependencies
- Added
@googlemaps/[email protected]
- Added
@scayle/[email protected]
- Added
@types/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@storyblok/[email protected]
- Updated to
@vueuse/[email protected]
- Updated to
@vueuse/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
(For detailed changes see Changelog for Vue)
1.0.0-rc.07
This release focuses on stabilization and modularization, to improve the technical foundation and developer experience.
🔥 Highlights
✨ Update to Nuxt 3.10.1 and Vue 3.4.19
Storefront Boilerplate now runs on both the latest Nuxt v3.10.1
and Vue v3.4.19
and benefits from a multitude of improvements. To get more details about all the changes see the Official Nuxt 3.10 Announcement Blog and the Official Vue 3.4.19 Changelogs.
🧪 Modularization: Extracting Cypress into a dedicated sub-package
The Cypress testing solution has been extracted into a dedicated child package located at cypress/
. This decouples the dependencies from the main Storefront application. To install all relevant Cypress dependencies, execute yarn install
within the cypress/
directory. By default, the current Cypress integration does not rely anymore on the commercial Cypress Dashboard integration. Please check the dedicated Readme file located at cypress/README.md
for more details.
The following dependencies have moved from package.json
to cypress/package.json
:
cypress
cypress-real-events
eslint-plugin-cypress
🧱 Modularization: Extracting Storyblok Integration into the local module
The Storyblok integration has been extracted into a dedicated local Nuxt module storefront-cms
. This allows to combine all CMS provider relevant functionalities within a central Nuxt module and allows for simple future inclusion of additional CMS providers.
The new local Nuxt module can be found under modules/cms/
and its path has been added to nuxt.config.ts
to the modules
list.
🧲 Tracking Refactoring and Improvements
The included tracking implementation has been refactored and received various improvements to increase the tracking data quality, as well as tracking data reliability.
🚀 Major Changes
- BREAKING: Added support for runtimeConfig with
@nuxt/image
- Added patch files for automatic dependency patching with
patch-package
. The tool will run inpostinstall
and apply any patches present in thepatches/
directory to the respective dependency. - Extended
README.md
with a section regardingPatches
to explain the details and currently applied patches
- Added patch files for automatic dependency patching with
- Added full support for an easy way of running the application through docker compose
💅 Minor Changes
- Refactored Wishlist
- Added
WishlistCardSlideIn
,WishlistCardImage
andWishlistCardDescription
components - Added
useWishlistPage
,useWishlistItem
anduseWishlistItemActions
composables
- Added
- Fixed an issue with Guest User being able to access the Account page, even though it did not have any content
- Fixed an issue with the Order pages not properly displaying content due to page caching issues while using path-based routing
- Fixed various UX/UI issues for the new Promotion Engine feature
- Fixed hydration issues related to viewport-dependent font-size classes on PDP in
pages/p/[slug].vue
- Fixed hydration issues related to viewport-dependent font-size classes on PLP in
components/product/card/ProductCard.vue
- Refactored various components to use new Vue v3
defineEmits
syntax for eventscomponents/layout/headers/search/MobileSearchInput.vue
components/search/CategorySuggestions.vue
components/search/ProductSuggestions.vue
components/search/SearchResultItem.vue
components/search/SearchResults.vue
components/search/SearchResultsContainer.vue
- Fixed
DefaultLink
behaviour with path-based routing incomponents/ui/links/DefaultLink.vue
- Fixed client-side validation behaviour for login and registration forms
components/auth/GuestLoginForm.vue
components/auth/LoginForm.vue
components/auth/RegisterForm.vue
components/auth/SalutationSelect.vue
- Fixed the "Register" link to open the "Registration" tab within the
SignInForm
incomponents/auth/SignInForm.vue
🩹 Patch Changes
- Added
hasOneSizeProductVariantOnly
helper withinsizes
util - Fixed UX / UI issues for the Order details page in
pages/account/orders.vue
- Fixed UX / UI issues with login and registration forms
- Fixed window scrolling on PLP pagination in
components/ui/pagination/PaginationButton.vue
🏡 Dependency Updates
🏘️ devDependencies
- Updated to
@crowdin/[email protected]
- Updated to
@nuxt/[email protected]
- Updated to
@nuxtjs/[email protected]
- Updated to
@nuxtjs/[email protected]
- Updated to
@types/[email protected]
- Updated to
@upstash/[email protected]
- Updated to
@vitest/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
🏠 dependencies
- Updated to
@scayle/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
1.0.0-rc.06
This release focuses on stabilization and refactoring, to improve the technical foundation and developer experience.
🚀 Major Changes
- BREAKING: Nest public Storefront-specific
runtimeConfig
properties under thestorefront
keyuseRuntimeConfig().public.log
anduseRuntimeConfig().public.auth
should be replaced byuseRuntimeConfig().public.storefront.log
anduseRuntimeConfig().public.storefront.log
(...storefrontRuntimeConfigPublic as any),
tostorefront: storefrontRuntimeConfigPublic as any,
innuxt.config.ts
💅 Minor Changes
- Extracted sorting and grouping basket helpers to
utils
- Properly resolve
basketGroup
RPC with params - Removed wishlist utils and moved them to the
useWishlistActions
composable - Replaced
validation
plugin withuseValidationRules
composable - Replaced
toast
plugin withuseNotification
composable - Replaces
tracking
plugin withuseTracking
composable - Renamed
divideWithHundred
price utility todivideByHundred
- Renamed
localeFormattedDate
date utility toformatLocaleDate
- Enforced using tracking sub-composables through the
useTrackingEvents
by turning off auto-import for sub-composables - Simplified
Countdown
component logic by usinguseIntervalFn
fromvueuse
- Changed
radash
utils prefix to be underscore (_
) instead ofuse
, to avoid confusion betweenradash
utilities and Vue composables. Resulting in e.g.useSleep
to become_sleep
. - Used radash
_sort
(useSort
) instead of nativesort
to avoid side effects - Export composables as named functions
- Refactored components to use
withDefaults
and type generics to define component properties - Refactored product and navigation components to reduce complexity
- Refactored account area component to reduce complexity and improve UI experience
components/account/AccountHeader.vue
components/account/AccountWrapper.vue
components/addOns/AddOnsSelector.vue
components/order/OrderHeader.vue
components/order/OrderItemCard.vue
components/order/OrderOverviewHeader.vue
components/order/OrderStatusBar.vue
pages/account/orders.vue
pages/account/user.vue
pages/account/orders/[id].vue
- Refactored account area orders components to reduce complexity and improve UI experience
components/account/AccountWrapper.vue
components/order/OrderHistoryItem.vue
components/order/OrderItems.vue
composables/useOrders.ts
- Refactored used Tailwind classes across the Storefront Boilerplate to comply with used Tailwind version
- Tweaked Promotion Engine implementation and UI experience across the Storefront Boilerplate
- Tweaked Order Success Page (OSP) complexity and UI experience
🩹 Patch Changes
- Refactored
slicedOrders
to be acomputed
property incomponents/account/AccountWrapper.vue
- Refactored
_sizes
to be acomputed
property incomponents/product/ProductSizePicker.vue
- Refactored
components/addOns/AddOnsSelector.vue
to usecomputed
properties instead ofref
and dedicated update functions - Refactored
basketItems
to have an empty array as fallback incomponents/basket/popover/BasketPopoverItems.vue
- Added missing state key for
footerNavigationTrees
incomponents/layout/footer/AppFooter.vue
- Simplified watcher for
searchQuery
incomponents/layout/headers/search/HederSearch.vue
- Refactored Nuxt-specific imports to import from
#app
instead ofnuxt/app
- Added
collapsed
component property tocomponents/product/detail/ProductDetailAccordionEntry.vue
- Use object for lookup of headline sizes instead of
computed
property incomponents/ui/headlines/Headline.vue
- Fixed desktop sidebar overlapping navigation in
pages/[...category].vue
- Added
time
constants inconstants/time.ts
and used it incomponents/ui/Countdown.vue
- Refactored
PromotionBanner
to be displayed ononNuxtReady
instead ofonServerPrefetch
to avoid missing interactivity during page load and hydration - Removed
runtimeConfig.public.storyblok.webhookSecret
fromnuxt.config.ts
, as it is not supported by thestoryblok-nuxt
module - Use
yn
to typecast potential build value ofruntimeConfig.public.gtm.debug
viayn(process.env.NUXT_PUBLIC_GTM_DEBUG)
innuxt.config.ts
🏡 Dependency Updates
🏘️ devDependencies
- Updated to
@crowdin/[email protected]
- Updated to
@nuxt/[email protected]
- Updated to
@nuxt/[email protected]
- Updated to
@nuxtjs/[email protected]
- Updated to
@types/[email protected]
- Updated to
@upstash/[email protected]
- Updated to
@vitest/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
(For detailed changes see Release Notes for Nuxt) - Updated to
[email protected]
- Updated to
[email protected]
🏠 dependencies
- Updated to
@scayle/[email protected]
- Updated to
@storyblok/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
(For detailed changes see Changelog for Vue)
1.0.0-rc.05
🔥 Highlights
✨ Update to Nuxt 3.9 and Vue 3.4
Storefront Boilerplate now runs on both the latest Nuxt v3.9
and Vue v3.4
and benefits from a multitude of improvements. To get more details about all the changes see the Official Nuxt 3.9 Announcement Blog and the Official Vue 3.4 Announcement Blog.
🛫 Introducing Promotion Engine
The Promotion Engine presents the user with various promotions that have specific conditions for receiving the discount. The Storefront Boilerplate currently supports the two types Automatic discount
and Buy X get Y
by default as promotions.
- SCAYLE Resource Center - Storefront Boilerplate / Promotion Engine
👥 Identity Provider support for Token-based Authentication
The Storefront Boilerplate now provides support for Single-Sign-On (SSO) via multiple Identity Providers (IDP) like Okta, KeyCloak, or Google. The IDP login / SSO flow integrates with the existing Token-based Authentication and can be used in parallel with the existing SCAYLE IDP.
- SCAYLE Resource Center - Storefront Core / Authentication
🔋 Introducing Page Caching with unified cache handling
The distributed default configuration of the Storefront Boilerplate comes with page caching enabled and relies on the global storefront-cache
storage mountpoint available via Storefront Core - Caching and configured via Storefront Core - Storage via Module Configuration.
- SCAYLE Resource Center - Storefront Boilerplate / Page Caching
🛫 Introducing support for Vercel Edge deployment
Storefront Boilerplate does now support deployment to Vercel Edge, besides Docker-based deployments.
- SCAYLE Resource Center - Storefront Boilerplate / Vercel Edge
🚀 Major Changes
- Updated Cypress E2E test suite
- Introduced new utility
formatCurrency()
inuseFormatHelpers
and refactored the usage ofgetCurrency()
&toCurrency()
- Removed
nuxt-viewport
and refactored the application to useuseDefaultBreakpoints
composable based onVueUse/useBreakpoints
(For details see VueUse Documentation) - Reduced the usage of viewport detection logic and refactored UI to rely on responsive layouts instead
- Extract and refactor Product Filter handling on the Category and Search page
- Refactored i18n integration and usage across applications due to the update of
@nuxt/i18n
tov1.0.0
stable release
💅 Minor Changes
- Removed
stylelint
, related dependencies, and package script commands - Replaced
nuxt-vitest
with@nuxt/[email protected]
as the projects have been officially merged together (For detailed changes see Changelog of @nuxt/test-utils)- Introduced
[email protected]
- Introduced
- Remove unsupported
imageBaseUrl
option key fromstorefrontRuntimeConfigPublic
inconfig/storefront.ts
- Removed usage of
process.env
fromnuxt.config
andconfig/storefront.ts
, relying on using runtime environment variables instead (_For details see Nuxt Documentation - runtimeConfig / Environment Variables) - Allowing to use HTTP during local development mode
- Extend
.env.example
with updated environment variables for locale development purposes - Added documentation reference links into
nuxt.config.ts
- Added comments with environment variable names to override runtimeConfig keys into
nuxt.config.ts
andconfig/storefront.ts
- Removed unused
nuxt/utils/cms.ts
- Introduce
useOrders
composable to unify orders handling - Changed usage of
forgotPassword(data: SendResetPasswordEmailRequest)
toforgotPassword(email: string)
inuseAuthentication
composable, refactored occurrences accordingly - Introduce
@vercel/kv
and@upstash/redis
for VercelKV support - Extend
routeRules
innuxt.config.ts
to handle Vercel page caching - Extend
routeRules
innuxt.config.ts
to support multiple cache configurations - Extend
routeRules
innuxt.config.ts
to allow disabling SSR Page Caching via environment variables during build time withDISABLE_SSR_CACHE
- Extend
cache-test.mjs
- Set
differentDomains
based on the environment variableDOMAIN_PER_LOCALE
during build time innuxt.config.ts
- Enable
debug: true
innuxt.config.ts
to be able to pinpoint potential hydration mismatches or enumerating key issues - Various types tweaks and refinements
🩹 Patch Changes
- Fixed Storyblok integration with the handling of invalid
product_ids
instoryblok/components/ProductSlider
- Fixed Storyblok integration on Category pages without defined Storyblok CMS category slug resulting in error pages in
pages/[...category].vue
- Fixed issue with unavailable product colors on the Product Detail Page in
pages/p/[slug].vue]
- Removed
version: getStoryblokContentVersion(),
fromcomposables/useCms.ts
- Fixed caching behaviour and incorrect product list layout in
components/productList/ProductList.vue
&pages/[...category].vue]
- Fixed Order types in
components/order/OrderHeader.vue
,components/order/OrderItems.vue
,components/order/summary/PaymentSummary.vue
,pages/account/orders/[id].vue
- Fixed computed property
orderItems
inpages/account/orders/[id].vue
- Fixed ProductBadge position in
components/product/ProductBadge.vue
andcomponents/productList/ProductList.vue
- Fixed user information disappearing after reloading by disabling
autoFetch
and fetching user data explicitlyonMounted
incomponents/layout/headers/user/UserPopover.vue
- Fixed re-fetching for product list in
pages/[...category].vue]
- Fixed mobile sidebar overlapping issue in
components/layout/navigation/MobileSidebar.vue
- Fixed-size picker overlapping issue in
components/wishlist/card/WishlistCard.vue
- Fixed SlideIn overlapping issue in
components/layout/SlideIn.vue
andcomposables/useSlideIn.ts
- Fixed the Wishlist and Basket page being incorrectly cached
- Fixed incorrect routing behaviour in the following files
components/layout/headers/search/HeaderSearch.vue
components/ui/links/DefaultLink.vue
composables/useRouteHelpers.ts
middleware/authGuard.global.ts
utils/route.ts
- Various other smaller fixes and improvements
🏡 Dependency Updates
🏘️ devDependencies
- Removed
@nuxt/devtools
from devDependencies, as it's now included with[email protected]
or higher - Updated to
[email protected]
(For detailed changes see Changelog for Vue) - Updated to
[email protected]
(For detailed changes see Release Notes for Nuxt) - Updated to
@crowdin/[email protected]
- Updated to
@nuxt/[email protected]
- Updated to
@nuxt/[email protected]
- Updated to
@nuxtjs/[email protected]
- Updated to
@nuxtjs/[email protected]
- Updated to
@scayle/[email protected]
- Updated to
@types/[email protected]
- Updated to
@types/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
[email protected]
[email protected]
- Updated to
[email protected].
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
and@vitest/[email protected]
- Updated to
[email protected]
(NOTE: This dependency update is required for proper[email protected]
type checking!)
🏠 dependencies
- Added
[email protected]
as it is now a standalone project within the Nuxt ecosystem - Added
[email protected]
as explicit dependency to avoid potential version mismatches - Updated to
@scayle/[email protected]
(For detailed changes see SCAYLE Resources Center - Releases) - Updated to
@storyblok/[email protected]
- Updated to
@tailwindcss/[email protected]
- Updated to
@vueuse/[email protected]
and@vueuse/[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
- Updated to
[email protected]
1.0.0-rc.04
🚀 Major Changes
- Use public npmjs.org package registry for
@scayle
packages and remove the need for a local.npmrc
file - Use public
storyblok-generate-ts
package instead of a private fork
💅 Minor Changes
- Updated to latest
@scayle/storefront-nuxt
package usingv7.37.2
- Improved Dockerfiles for build and deployments
🩹 Patch Changes
- Updated various dependencies to the latest versions
1.0.0-rc.03
🚀 Major Changes
- Introduced
vitest
for unit testing and created dummy test files for most components - Introduced page caching using Route Rules
- Replacing AuthGuard component with router middleware
- Use
defineOptions
forvue
component naming
💅 Minor Changes
- Introduce
localizedNavigateTo
for the programmatic routing approach - Upgrade to Vue 3.3.7
- Replaced
useUiState
with smaller composables which are:useFlyouts
,useMobileSearch
,useModal
&useSideNavigation
. - Enable auto-import for the
constants
folder - Various dependency minor dependency
🩹 Patch Changes
- Fixed session max-age
- Handle AddToWishlist errors
- Added missing Storyblok components
- Resolved Storyblok link
- Fixed broken links when path-based shops are enabled
- Various bug fixes
1.0.0-rc.02
💅 Minor Changes
- Upgrade to Nuxt 3.7.4
🩹 Patch Changes
- Reduction of hydration errors
- Improved error handling for invalid products on PDP, as well as category and service pages
- Improved handling of displaying account related UI elements for guest user
- Improved order refresh behaviour on Order Success Page
- Various smaller bug fixes
1.0.0-rc.01
🚀 Major Changes
- Introduce Nuxt 3
- Tracking of all relevant shop interactions with GTM
- Implemented Search Engine optimizations
- Provide more CMS content integrations (Storyblok) into all relevant pages
💅 Minor Changes
- Improved error handling and displaying of error pages
- Improvements to redirect handling
- Improved SVG icon handling
- Improvements to mobile styling and behaviour
🩹 Patch Changes
- Various bug fixes