@scayle/storefront-application-nuxt
1.12.0
Release Date: 2025-08-06
🔥 Highlights
🏷️ Introducing Campaigns: A Unified Display for All Deals
We're excited to introduce Campaigns, a powerful new way to highlight offers. To create a seamless experience for your customers, Campaigns are now fully integrated into the same UI components previously used for promotions. This means key areas throughout the shopping journey—from product cards and price displays to banners and the basket summary—will now clearly show details from both Campaigns and Promotions. As part of this unification, several components have been renamed to be more generic (e.g., SFPromotionRibbon is now SFDealRibbon), reflecting their new ability to display any kind of deal.
🚀 Introducing Express Checkout
To significantly speed up the purchasing process, Express Checkout is now available directly on the basket page.
This powerful feature, powered by the <scayle-express-checkout />
web component, allows all users—including guests—to complete their purchase with just a few clicks.
To support this seamless experience, we've refactored the basket summary into a single, responsive component and modernized how checkout scripts are loaded, ensuring a more robust and reliable integration.
🏗️ Future-Proofing Our Nuxt Architecture
To ensure our platform remains fast, stable, and ready for future innovation, we have made significant upgrades to our core architecture.
The Storefront Application has been upgraded to a newer version of Nuxt (v3.17.7
), bringing immediate performance and routing enhancements.
As part of this process, we've also proactively reorganized our project to align with the upcoming Nuxt 4, ensuring a smooth transition to the next generation of the framework.
Additionally, we've introduced more powerful configuration options for internationalization, allowing you to easily define your shop's routing behavior via a new environment variable.
🚀 Major Changes
- [Header & Footer] We've introduced scheduled visibility for navigation items directly from the SCAYLE Panel.
The
useHeaderNavigation
,useFooterNavigation
,useSimpleHeaderNavigation
anduseSimpleFooterNavigation
composables now support avisibleAt
parameter, allowing you to display or hide specific navigation links based on a set date and time. For more details, see the SCAYLE Resource Center Documentation. - [Architecture] To prepare for future development, the project has been made compatible with Nuxt 4, and the project's directory structure has been updated accordingly. Developers should familiarize themselves with the new Nuxt 4 directory structure to locate files in their new locations.
- [Architecture] The Storefront Application has been upgraded to
[email protected]
, which brings router enhancements and performance improvements. While this Nuxt release has no breaking changes, the update revealed two pre-existing issues in our application that have now been resolved: A duplicateddefinePageMeta
on the Product Listing Page and a missinginheritAttrs: false
on theSFModal
component. We had been inadvertently relying on a Nuxt bug which caused attributes to not be inherited throughClientOnly
. For more details on the Nuxt release, see the official blog post. - [Architecture] The application's shop selector mode is now configurable via the
SHOP_SELECTOR_MODE
environment variable. Set this variable before building your application to define the desired routing behavior for your international shops. Please refer to the documentation for available modes. - [Architecture] The custom logic for loading checkout web components has been replaced.
We now use the official
@nuxt/scripts
module, aligning with Nuxt best practices and simplifying script management. - [Basket] Merged
SFBasketSummaryMobile.vue
andSFBasketSummary.vue
into a singleSFBasketSummary.vue
component. This eliminates duplicated code and DOM elements, and ensures that only one instance ofSFExpressCheckout.client.vue
is mounted. This change addresses limitations of the<scayle-express-checkout />
web component, which requires a single instance. - [Basket] Express Checkout is now available on the basket page.
This feature, powered by the
<scayle-express-checkout />
web component, allows all users—including guests—to quickly proceed to checkout. The authentication guard (/app/middleware/authGuard.global.ts
and/app/pages/checkout.vue
) has been updated to permit guest access when an express checkouttransactionId
is present in the URL query parameter. For more details, see the Express Checkout documentation. - [E2E] To improve the overall quality of the end-to-end test suite, significant code improvements have been applied to both test files and Page Objects, making them more robust and efficient. Additionally, JSDoc comments have been added to further clarify test scenarios.
- [Config] You can now enable a Shared Basket and Wishlist across your multi-language shops. This optional feature provides a seamless experience for users navigating between different language versions of your store. For implementation details, please refer to our guide on integrating a Shared Basket within the SCAYLE Resource Center.
- [Promotions] The following components have been enhanced to display both promotion and campaign information, such as campaign badge labels and reduction amounts:
SFProductPrice
,SFBasketSummaryReductions
,SFBasketCardImage
, andSFProductCard
. Additionally, theSFPromotionBadge
component has been renamed to the more accurateSFDealBadge
. - [Promotions] To provide a unified experience for all types of offers, we've integrated Campaigns into our existing promotion components.
Components like the
SFDealRibbon
,SFPromotionSlideIn
andSFDealBanner
now display both promotions and campaigns, using new utility functions (getCampaignDisplayData
,getPromotionDisplayData
) to handle the display logic.
To better reflect this broader purpose, several components have been renamed fromSFProductPromotionBanner
toSFDealBanner
,SFPromotionRibbon
toSFDealRibbon
andSFPromotionTimer
toSFDealTimer
.- Before:
- After:
- Before:
- [Translations] To improve the reliability and maintainability of our translation files, we have refactored the codebase to use static translation keys where possible.
A new ESLint rule (
@intlify/vue-i18n/no-unused-keys
) has been enabled to flag unused keys as errors, ensuring our translation files remain clean and accurate. A few dynamic keys are intentionally ignored where necessary for code readability.
💅 Minor Changes
- [CMS] Addressed an issue where the
<CMSText />
component would fail if not nested within a paragraph from Contentful. The component now correctly checks the node type and can render standalone text content. - [Code Style] The project's ESLint configuration has been streamlined by removing the redundant
eslint-plugin-nuxt
package. - [Code Style] To standardize our development tooling, the local
eslint-auto-explicit-import
module has been replaced with the official@scayle/eslint-auto-explicit-import
package. This ESLint module automatically adds necessary imports as you code, replacing our previous local implementation and streamlining the development process. - [UI] To improve usability and provide a larger touch target, especially on mobile devices, the
SFCheckbox
component has been enlarged. The checkbox itself is nowsize-6
(24px
), and its label has been increased totext-md
(14px
). - [UI] The
<SFPopover />
component has been updated to render itscontent
slot only on the client side. This change was necessary to fix a hydration mismatch caused by using transitions with theappear
attribute that are not safe for server-side rendering. - [ShopSwitcher] Resolved a routing issue where the
useShopSwitcher
composable would generate an incorrect base path when switching to the default shop inpath_or_default
mode. It now correctly uses theuseLocalePath()
composable to ensure proper navigation.
🩹 Patch Changes
- [Code Style] To align with Vue best practices, explicit imports for the
defineOptions
compiler macro have been removed. These imports are unnecessary as Vue handles them automatically during compilation. - [E2E] The accuracy of PLP tests has been enhanced by introducing a new
parseLocatorTextToNumber
helper function. This utility more reliably extracts numbers from UI elements, ensuring that assertions for the product count and card data are correct after filtering or sorting. - [PLP] Addressed an issue where resetting filters would incorrectly remove all URL query parameters, not just those related to filtering.
The fix ensures that only parameters prefixed with
filters
are removed, preserving the rest of the page state. - [E2E] The end-to-end test framework has been refactored to be more modular and maintainable.
A new abstract
Base
class now centralizes common logic for all Page Objects, and a suite of reusable helper functions has been introduced to streamline common test automation tasks like navigation and filtering. - [UI] Resolved a layout issue in the basket popover card (
SFBasketPopoverCard
) where long product or brand names would cause the product image to shrink and the text to overflow. The text now truncates correctly, ensuring a consistent and clean layout, by settingmin-w-0
andoverflow-hidden
classes correctly solved both issues. - [Product Listing] To improve consistency across all filter types, the special
aria-label
translation for the size filter has been removed. It now uses the same labeling pattern as other attribute filters. - [E2E] To improve maintainability, our end-to-end tests have been simplified.
We've removed the outdated
priceSubtotalMobile
locator and simplified the checkout navigation logic, as the UI now uses a single, responsive component. - [PLP] Resolved a race condition where products could be loaded before their category-specific sorting configuration was applied.
The application now correctly awaits the category data (
useCategoryById
) before fetching the product list (getProductsByCategory
) to ensure the proper sort order is always used. - [Types] To improve code quality and maintainability, the obsolete module declaration for the removed
shop:change
hook has been deleted. - [Promotions] Updated dependency
@scayle/storefront-promotions
to2.2.2
. This release resolves issue with promotion code not being removed from basket.
🏡 Dependency Updates
- Added dependency
@nuxt/[email protected]
- Added dependency
@scayle/[email protected]
- Added dependency
@scayle/[email protected]
- Added dependency
[email protected]
- Added dependency
[email protected]
- Removed dependency
[email protected]
- Removed dependency
[email protected]
- Removed 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
@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
@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
@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
@contentful/[email protected]
to@contentful/[email protected]
- Updated dependency
@intlify/[email protected]
to@intlify/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[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
@testing-library/[email protected]
to@testing-library/[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
@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]
1.11.0
🔥 Highlights
✨ Smarter Product Discovery and a Modern Mobile Sorting Experience
Finding the right products is now faster and more intuitive than ever. We've completely overhauled the Product Listing Page by automatically hiding empty categories for a cleaner navigation experience and introducing a powerful new sorting mechanism, including custom and smart sorting. For mobile users, we've replaced the cumbersome sorting dropdown with a sleek and user-friendly slider, making it significantly easier to reorder products on the go.
🏷️ Drive Conversion with "Recently Viewed" and In-Basket Promo Codes
We're introducing two powerful new features designed to enhance the customer journey and increase conversion. A "Recently Viewed Products" slider now appears on the Product Detail Page, making it easy for shoppers to revisit items they're interested in. Furthermore, customers can now apply promotion codes directly in the shopping basket to see their final, discounted price before even starting the checkout process, reducing friction and cart abandonment.
🎨 A More Consistent and Scalable Storefront with Storybook and a Unified Design System
To ensure the highest quality and consistency across every part of your storefront, we've introduced Storybook, a professional-grade component library that documents our UI elements in isolation. Alongside this, we have performed a comprehensive overhaul of our entire design system, unifying our approach to colors, spacing, fonts, and responsive breakpoints. This foundational upgrade results in a more polished, professional, and visually consistent shopping experience that is easier to scale and maintain.
🚀 Major Changes
- [Architecture] To improve performance and dependency management, we have migrated from Yarn v1 to PNPM.
This results in faster installation times and more efficient use of disk space due to PNPM's unique approach to handling
node_modules
. Instead of running command viayarn some:command
, they will now be executed viapnpm some:command
, e.g.pnpm install
orpnpm dev
.
For more details on how to use PNPM and its extended features, check the official PNPM documentation. - [Architecture] Introduced Storybook for UI component development and documentation.
Storybook is an open-source tool for building and documenting UI components in isolation. It allows developers and designers to visually develop, test, and review components outside the main application, improving design consistency and development speed.
In this project, Storybook has been integrated as a development dependency, configured specifically for Nuxt 3 and our component architecture.
It serves as a living component library and a central place to showcase UI patterns, aiding both internal teams and external stakeholders in understanding and reusing shared components.
Initial example stories have been added for key UI components to demonstrate usage and recommended best practices.
- To run Storybook locally:
This starts a development server at http://localhost:6006. - To generate a static Storybook build, use:
The output will be placed in thepublic/storybook
directory and can be accessed at http://localhost:3000/storybook. - Further information can be found in the official Storybook documentation and the Nuxt Storybook guide.
- The following components are now available within Storybook:
- Order
SFOrderList
- Product
SFProductCard
SFProductPromotionBanner
- Base Components
SFAccordionEntry
SFButton
SFChip
SFCountdown
SFModal
SFPopover
SFSkeletonLoader
SFSliderIn
SFSliderArrowButton
SFCheckbox
SFDropdown
SFFilterRangeSlider
SFPriceInput
SFSwitch
SFTextInput
SFValidatedInputGroup
SFHeadline
SFGoBackLink
SFLink
SFPagination
SFItemsSlider
SFToast
SFToastContainer
- Base Components / Transitions
SFSlideInFromBottomTransition
SFSlideInFromLeftTransition
SFFadeInFromBottomTransition
SFFadeInTransition
- Order
- To run Storybook locally:
- [Architecture] Refactored
useAuthentication
to longer be tied to a specific authentication action. This simplifies the usage of the composable and prevents possible unexpected behavior if there is a mismatch between the authentication string passed to the composable and the authentication method which is called.- Before
- After
- Before
- [Performance] Updated
routeRules
innuxt.config.ts
to disable internal Redis page caching. The Storefront Application now relies solely onCache-Control
headers which can be handled efficiently by external CDNs like Cloudflare. - [PDP] A new "Recently Viewed Products" recommendation slider has been added to the Product Detail Page, allowing customers to easily navigate back to products they have previously viewed.
- [PLP] The category fetching logic has been updated to exclude categories that contain no products.
This change automatically removes them from the PLP side navigation for a cleaner interface.
- [PLP] To improve performance and create a single source of truth, the product listing logic has been refactored as part of the upgrade to
@scayle/[email protected]
.- Sorting Logic: The
useProductListSort
composable is now centralized at the page level to act as a single source of truth. - SEO Data: The
useProductListingSeoData
composable now requires an additional isDefaultSortSelected boolean parameter. - UI Labels: The
label
for the selected sort option is now a direct string and should no longer be passed through the translation function ($t(label)
).
- Sorting Logic: The
- [PLP] Implemented a smart and custom sorting mechanism for the
top_seller
sorting option (commonly referred to as "Recommendations"). If there are no sorting keys defined for a specific category, thetop_seller
sorting option will default to its original behavior. Here's the main logic for implementing smart and custom sorting keys: - [PLP] To enhance mobile usability, the new
SFMobileSortSelection.vue
component has been introduced. It implements a slider-and-chip interface and replaces the former dropdown-based sorting logic within SFFilterSlideInContent.vue. The previous dropdown implementation for sort selection on mobile devices was not optimal for touch interactions and required multiple taps to change sort options. The new slider interface with chips provides better touch targets for mobile users, offers immediate visual feedback and reduces the number of interactions needed to change sort order. - [Promotions] Users can now apply and remove promotion codes directly in the shopping basket.
A new
SFBasketPromotionCodes.vue
component has been added, allowing customers to see their discounts applied without having to proceed to the checkout page first. This replaces the current disclaimer on the basket page with a newSFBasketPromotionCodes.vue
component. This component builds on the latest enhancements to@scayle/[email protected]
and enables users to add and remove promotion codes without necessitating entering checkout first. - [UI] To simplify responsive design and improve maintainability, the application's breakpoints have been streamlined.
The
2xl
breakpoint has been removed to focus on a more essential set of screen sizes. Developers should now target thexl
breakpoint as the largest available size for any screen-specific styling.- Available Breakpoints:
- Available Breakpoints:
- [UI] The Tailwind CSS configuration has been simplified by removing custom
z-index
values (from60
to110
). We now rely on Tailwind's defaultz-index
scale, leading to a cleaner and more maintainable styling implementation. - [UI] Enhanced Tailwind configuration for
spacing
andsizes
. Configuration is refined forwidth
,minWidth
,maxWidth
,height
,minHeight
,maxHeight
,spacing
, andpadding
. These updates ensure a consistent and scalable design system.- Key changes:
- The
spacing
scale now serves as the foundation for multiple core plugins, including margin, gap, inset, space, translate, scrollMargin, and scrollPadding. - To maintain uniformity, all values are centralized within the
spacing
property, which incorporatesdefaultSizes
defined at the top of the Tailwind config file. - Additionally,
spacing
and other sizing values (maxHeight
andmaxWidth
) are extended within thetheme.extend
property, leveraging the default Tailwind spacing scale.
- The
- Updated configuration:
- Key changes:
- [UI] Streamlined the Tailwind font weight configuration for a cleaner and more consistent design.
- Updated font weight setup:
- Updated font weight setup:
- [UI] Enhanced and simplified Tailwind configuration for
font-sizes
andline heights
.- Key changes:
- The font size scale has been refined for better usability and consistency.
The following font sizes have been removed:
3xs
,2xs
,base
,4xl
,5xl
,6xl
,7xl
. - New Progression: The font size scale now aligns closely with Tailwind's default numerical progression.
3xs
and2xs
are replaced withxs
.base
is replaced withmd
.
- Line heights have also been streamlined:
- The
2.5
and3.5
values has been removed. - The configuration retains Tailwind's default line heights, ensuring compatibility across the application.
- The
- The font size scale has been refined for better usability and consistency.
The following font sizes have been removed:
- Updated configuration:
These updates make the configuration more intuitive, future-proof, and adaptable to evolving design needs. By aligning with Tailwind's default progression, the setup ensures consistency while maintaining flexibility for creative designs. - Key changes:
- [UI] Enhanced Tailwind configuration for
outline
,outline-offset
,border-width
, andborder-radius
.- Key changes include:
- Simplified
outline
andoutline-offset
configuration by removing redundant values. - Removed custom border-radius and border-width values to align with Tailwind's default values for consistency and maintainability.
- Simplified
- Updated configuration for outline values:
- Key changes include:
- [UI] Streamlined the Tailwind aspect ratio configuration.
- Updated aspect ratio setup:
- Updated aspect ratio setup:
- [UI] The color palette has been streamlined and unified
within the Tailwind configuration for improved consistency and simplicity.
The most notable refinements are in the
gray
andsecondary
color variants, which have been thoughtfully reduced to enhance usability and clarity. New gray and secondary color definitions are as follows:
Furthermore,white-smoke
,focus
, andprimary-400
colors has been removed, replacing them with carefully selected alternatives that align with the updated design system. - [UI] Enhanced and simplified Tailwind configuration for
box-shadows
.- Extracted CSS variables within
main.css
: - Tailwind configuration:
- Extracted CSS variables within
- [Unit Testing] To standardize test data generation, our unit tests now use the official order factories provided by the
@scayle/storefront-nuxt
package, replacing our previous custom implementations. This change simplifies our test setup and improves maintainability.
💅 Minor Changes
- [Architecture] Addressed an issue where
$config.public.baseUrl
provided an incorrect base URL for domain-based shops. This deprecated property has been removed, and we now useuseRequestURL().origin
to reliably get the correct base URL. - [PLP] The range filter functionality has been enhanced to support filtering by both price and discount percentage.
To reflect this broader use case,
SFPriceRangeSlider.vue
andSFPriceInput.vue
have been renamed to the more genericSFFilterRangeSlider.vue
andSFRangeInput.vue
. This refactoring was done as part of adding support for discount filters (e.g.,max_savings_percentage
) in the filter slide-in. - [UI] Improved aspect ratio configuration for
SFProductImage.vue
The product image aspect ratio is now defined in a single source of truth:config/ui.ts
. There's no longer a need to apply additional styling on the parent element to achieve the desired aspect ratio. This change enhances maintainability and makes it easier to adjust the aspect ratio in the future.- Before:
- After:
- Before:
- [E2E] Expanded end-to-end test coverage for the Wishlist page.
A new test in
e2e-Wishlist.spec.ts
now verifies that clicking a product card correctly navigates the user to the corresponding Product Detail Page. - [E2E] Aligned the PLP sorting test with recent mobile UI enhancements. The test logic has been updated to use the new sorting slider with chips instead of the previous dropdown, ensuring our tests accurately reflect the current user experience.
- [E2E] Aligned the mobile sorting test with recent UI enhancements.
The test locator in
playwright/page-objects/components/sorting.ts
has been updated to reflect the new design where all sort options are visible simultaneously, ensuring accurate validation of the user experience. - [UI] Streamlined and polished the UI module components by removing outdated and redundant props:
SFModal.client
: Simplified by removing thecloseOnOutside
property.SFPopover
: Decluttered with the removal ofdisablePopoverContent
andcontentWrapperClass
properties.SFSlideIn.client
: Transitioned to a singledefault
slide type (X-axis) by removing theslideType
property.SFDropdown
: Refined by eliminating theisLarge
property.SFSwitch
: Lightened up with the removal ofname
andrequired
properties.SFTextInput
: Enhanced by dropping thehint
andmask
properties.SFLink
: Unifiedactive
andexactActive
classes, saying goodbye toonlyExactActive
.SFItemsSlider
: Simplified by removingcontainer
andsliderClass
properties.SFModal
: Removed thehideCloseButton
prop, which was no longer in use.SFItemsSlider
: Removed thescrollable
prop, which was no longer in use.
- [UI] As part of a code quality improvement, the
SFHeadlineBadge
component was refactored. Its logic has been inlined into theSFHeadline
badge slot, removing an unnecessary component. - [UI] To standardize the styling of promotional elements, a dedicated
promotion
color has been added to the Tailwind color palette. This provides a consistent, themeable fallback color for all promotional banners and labels. - [UI] Removed
SFProgressBar
as it is not used. - [UI] The
SFHeadline
component has been refactored. Theloading
prop and its associated skeleton loader are no longer part of the component; developers are now responsible for handling the loading state externally (e.g., with a wrapper component). Thehidden
prop and the customvisually-hidden
class have also been removed to streamline the component's API.
🩹 Patch Changes
- [Accessibility] To ensure all text is easily readable and meets accessibility standards, the extra-small (
xs
) font size option has been removed. The smallest available font size is now12px
, guaranteeing a more legible experience for all users. - [Accessibility] Streamlined keyboard navigation within product sliders (
SFBaseProductSlider
). The arrow buttons are no longer focusable, allowing users to tab directly between products more efficiently. Additionally, the focus indicator on products is now always fully visible. - [Accessibility] Addressed an issue where focus would incorrectly return to a
SFHeaderNavigationItem
after amouseleave
event and subsequent page navigation The fix involves deactivating the focus trap without returning focus (returnFocus: false
) when the interaction is mouse-driven, preventing the unwanted focus jump. - [Account] Improved the behavior of the "Forgot Password" form. Submitting the form by pressing the Enter key now correctly validates the input instead of unexpectedly closing the modal. This was resolved by explicitly setting the non-submit button's type to button, ensuring the correct button is triggered on form submission.
- [Account] Improved the user experience in the "Forgot Password" modal by ensuring that old error messages are cleared when the modal is closed. Users will no longer see a stale error message when reopening the form.
The
errorMessage
is now correctly reset tonull
when the modal is dismissed. - [Account] Improved the clarity of the error message shown when a non-existent email is entered in the "Forgot Password" and "Reset Password" forms. The message now correctly refers only to the email address, removing a confusing mention of the password.
- [Architecture] To prevent hydration errors related to URL query parameters, Incremental Static Regeneration (ISR) has been disabled for all Vercel deployments. This change is a necessary workaround for a known issue where query params were not correctly handled during server-side rendering with ISR. More details are available in this Nitro issue.
- [Images] To improve visual consistency in the basket popover, the alignment of product images has been fixed. Images will now appear correctly aligned regardless of their original aspect ratio.
- [Login & Registration] Refactored the error handling strategy in the useAuthentication composable.
Authentication methods (
login
,guestLogin
,logout
,register
,forgotPassword
,resetPasswordByHash
) now throw exceptions instead of internally caching them. This creates a more predictable and standard error handling pattern, requiring consuming components to handle failures explicitly. - [PDP] Fixed issue where controls of the
<SFProductGallery />
were not usable after the<SFProductGalleryZoom />
was opened. Addingz-index: 10
ensures the controls can always be clicked. - [Performance] Fixed a bug where navigating between product detail pages caused multiple executions of
redirectProductIfNecessary
, potentially creating a redirect loop. The function now checks if the product status ispending
before executing, ensuring it only runs once per navigation. - [Promotions] Resolved an issue where the promotion badge was displayed in the
SFBasketCardImage
component even if the promotion was not applied anymore. The promotion badge is now displayed if the promotion exists and is valid. - [SEO] Addressed an issue where hreflang links were missing for PLPs and PDPs during server-side rendering.
The data required to check product/category availability in other shops (
useAllShopCategoriesForId
,useAllShopProductsForId
) was not yet available when the links were being generated. The application now awaits these data-fetching functions, guaranteeing the availability data is present and allowinghreflang
links to be generated reliably. - [Search] To prevent text overflow in smaller containers, the
SFShowAllResultsLink.vue
component now truncates its label. This change ensures a clean and consistent UI layout. - [Subscriptions] Addressed a bug where subscription attribute values were not displaying correctly on the Order Detail and Order Success pages.
The
SFOrderDetailProductSubscription
component has been corrected to ensure this information is always shown accurately. - [UI] Resolved an issue where the promotion count in the
SFPromotionSlideIn
and filter count in theSFFilterGroup
were not aligned properly. There is now a newSFBadge
UI component that can be used to display a badge with a count. This will align the styling of the badge within the Storefront Application. - [UI] Added
supports-hover
condition toSFButton
hover transparency so the style will only be applied on devices which support hover. - [UI] To improve code quality and reduce dependency bloat, the unused
mask
package has been removed from the project's dependencies. - [UI] To standardize the appearance of all product sliders, the
SFProductRecommendations
andSFRecentlyViewedProductsSlider
components have been updated to use the sharedSFSliderArrowButton
. - [UI] To improve usability, the mobile sorting selection (
SFMobileSortSelection.vue
) now displays all available options at once. This eliminates the need for scrolling and makes it easier for users to see the currently active sort order. - [UI] Addressed a visual bug in
SFSiblingSelection.vue
that caused image corners to overflow their container. The component's styling has been updated to hide overflow, ensuring a clean and contained appearance. - [UI] Addressed an issue where using margins to position the
SFPopover.vue
content created a gap that would cause the hover state to flicker. The component now uses transparent borders instead, which closes the gap and provides a stable hover experience. - [UI] Addressed a positioning bug where the flyout in
SFHeaderNavigationItem
would appear in the wrong place. The issue, caused by dynamictranslateX
positioning, has been resolved by anchoring the flyout's position relative to the main header. - [UX] Improved the user experience in the
SFStoreLocatorSlideIn
component. Users can now trigger a search by pressing the Enter key in the text input, thanks to the input being properly wrapped in a<form>
element.
🏡 Dependency Updates
- Added dependency
@nuxt/[email protected]
- Added dependency
@nuxt/[email protected]
- Added dependency
@nuxtjs/[email protected]
- Added dependency
@storybook-vue/[email protected]
- Added dependency
@storybook/[email protected]
- Added dependency
@storybook/[email protected]
- Added dependency
[email protected]
- Added dependency
[email protected]
- Removed dependency
[email protected]
- Removed dependency
[email protected]
- Removed 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
@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
@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
[email protected]
to[email protected]
- Updated dependency
@changesets/[email protected]
to@changesets/[email protected]
- Updated dependency
@contentful/[email protected]
to@contentful/[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
@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]
1.10.0
🔥 Highlights
📈 Introducing Tiered Promotions and Improved Delivery Cost Management
You now have more direct control over your storefront with powerful new features. Encourage higher basket values with a new tiered promotions display that visually shows customers their progress towards unlocking rewards, and easily manage delivery costs and their descriptions directly from the SCAYLE Panel.
🎨 Enhanced and Consistent User Interface
We've improved the user experience by introducing a new standardized component for displaying order statuses with clear, color-coded labels. The overall interface has been streamlined through a major cleanup of our UI components, resulting in a more consistent and polished look and feel.
🌍 Improved Internationalization (SEO & Translations)
The SCAYLE Storefront Application is now better optimized for international SEO, with intelligent hreflang
links that help search engines understand the different language and country versions of your pages.
We've also performed a comprehensive overhaul of all translation files to align with our new guideline, ensuring a more consistent and maintainable translation process for all languages.
🤝 Accessibility
We've implemented a major accessibility upgrade to ensure a more inclusive experience for all users. This includes significantly improved keyboard navigation, clearer focus indicators, better screen reader support across all components, and updated color contrasts for enhanced readability.
🚀 Major Changes
- [Architecture ] Updated Nuxt to version
3.16.2
. The primary change in this release is the upgrade to[email protected]
, which necessitates small adjustments to bothnuxt.config.ts
and the usage of theuseHead
composable. More details can be found on the Nuxt blog. Nuxt blog. - [Architecture] The
SFAsyncDataWrapper
has been split into two more specific components for handling async states:SFAsyncStatusWrapper
: Renders content based on a status prop. This wrapper component accepts anAsyncDataRequestStatus
as a prop. When the status issuccess
it will render the default slot and when thestatus
iserror
it will render an error slot. When thestatus
ispending
oridle
it will render a loading slot.SFAsyncDataWrapper
: Renders content based on an AsyncData object and provides the fetched data to its default slot. This wrapper component accepts anAsyncData
object as a prop. When data has been loaded it will render the default slot and pass the data asdata
slot prop. When there is no data loaded, it will render the error slot when the status iserror
and theloading
slot when the status ispending
oridle
.
- [Architecture] To reduce code and complexity when fetching categories,
useRootCategories
has been removed in favor ofuseCategoryTree
. The new method is more efficient and guarantees a consistentCategory[]
return value. - [Basket] The display of delivery costs and their descriptions is now configurable directly within the SCAYLE Panel. This allows for easier management of shipping information without requiring code changes. Developers can access this configuration in the storefront using the useShopConfigCustomData.ts composable. For full implementation details, see the SCAYLE Resource Center.
- [Basket] To standardize basket-related logic, the Storefront Application codebase now incorporates the new
@scayle/storefront-basket
package. Custom utility functions have been replaced with the officially provided utils from this new dependency. - [Build] To support updated dependencies and features, the minimum required Node.js version has been set to
22.15.0
. Please ensure your development and build environments meet this new requirement. - [Config] Enhanced storage flexibility by implementing a new server plugin (
./server/plugins/storageConfig.ts
). This provides preconfigured storage for@scayle/storefront-nuxt
, allowing developers to easily integrate any unstorage driver (e.g., Redis, Vercel KV). - [Orders] To improve clarity for users, the new
SFOrderStatus
component now displays order statuses with consistent, color-coded labels. This enhancement is applied to both the order list and order detail views. - [Promotions] Refactored the approach for handling product promotions by removing the
useProductPromotions
composable abstraction. Consuming components are now responsible for their own promotion logic and data handling. - [Promotions] Refactored how promotion conditions are checked within the
SFPromotionProgressWrapper
component. TheareGiftConditionsMet
andisGiftAddedToBasket
computed functions have been inlined directly into the component, removing their dependency on theuseProductPromotions
composable for this specific logic. - [Promotions] The
SFPromotionProgressWrapper.vue
component has been enhanced to support tiered promotions. It now displays a progress bar with milestones, showing customers how close they are to unlocking different promotion tiers. This new UI is also used for minimum-order-value promotions, which are now treated as a single-tier promotion for a consistent experience. - [SEO] To improve international SEO and search engine indexing,
hrefLang
links have been implemented for the Home, Product Listing, and Product Detail pages. For PLPs and PDPs, the system now intelligently checks for the product or category's availability in other shops before generating the correspondinghreflang
link, ensuring accurate page version mapping. - [Translations] We've performed a comprehensive overhaul of all translation files to align them with a newly introduced i18n guideline. This change ensures a consistent structure and adherence to best practices across all languages.
- [UI] The
SFProgressBar
component has been enhanced to visually display milestone ticks along the progress bar. This feature is enabled via the new milestones prop. - [UI] To improve maintainability and reduce the overall codebase size, unused components have been deleted.
Components with very limited usage have also been inlined directly where they were needed.
modules/ui/runtime/components/core/SFBreadcrumbs.vue
modules/ui/runtime/components/core/SFHorizontalItemsDivider.vue
modules/ui/runtime/components/core/SFMenu.vue
modules/ui/runtime/components/core/SFOverlay.vue
modules/ui/runtime/components/core/SFSwipeDelete.vue
modules/ui/runtime/components/core/SFTwoColumnList.vue
modules/ui/runtime/components/core/SFVerticalAccordion.vue
modules/ui/runtime/components/core/chip/SFColorChip.vue
modules/ui/runtime/components/core/flyout/SFFlyout.vue
modules/ui/runtime/components/core/flyout/SFFlyoutMenu.vue
modules/ui/runtime/components/form/SFRadioGroup.vue
modules/ui/runtime/components/form/SFRadioItem.vue
modules/ui/runtime/components/layout/SFPageContainer.vue
modules/ui/runtime/components/links/SFContainerLink.vue
modules/ui/runtime/components/listbox/SFListbox.vue
modules/ui/runtime/components/listbox/SFListboxButton.vue
modules/ui/runtime/components/listbox/SFListboxOption.vue
modules/ui/runtime/components/listbox/SFListboxOptions.vue
modules/ui/runtime/components/pagination/SFSimplePagination.vue
modules/ui/runtime/components/transitions/SFFadeInFromBottomGroupTransition.vue
modules/ui/runtime/components/transitions/SFSlideInFromRightTransition.vue
modules/ui/runtime/components/transitions/SFSlideInFromTopTransition.vue
💅 Minor Changes
- [Accessibility] Improved screen reader support by adding a descriptive
aria-label
to the 'close' button in both theSFAuthResetPasswordSlideInHeader
andSFAuthForgotPasswordSlideInHeader
components. - [Accessibility] Improved the accessibility of the "Scroll to Top" button by adding a descriptive
aria-label
to theSFScrollToTopButton
component. - [Accessibility] Improved keyboard navigation and focus management on the Product List Page.
When navigating between categories using the side navigation, focus is now correctly retained within the navigation panel.
This was achieved by preventing the PLP from re-rendering on category changes via setting a fixed key in
definePageMeta
: - [Accessibility] Users navigating the store selector via keyboard can now easily view a store's opening hours by focusing on the store and pressing the Enter key.
- [Accessibility] Addressed an issue where Chrome's handling of
scroll-margin
caused inconsistent scroll behavior in theSFSlideIn.client.vue
component. The implementation has been switched to usescroll-padding
for more reliable cross-browser results. - [Accessibility] Improved screen reader support by adding a descriptive
aria-label
to the 'close' button within theSFShopSwitcherFlyoutHeader.vue
component. - [Accessibility] Improved visual clarity in the
SFSiblingSelection.vue
component by changing the active item's color from black to the accent color. This helps users better differentiate the currently selected item from a keyboard-focused item. - [Accessibility] Resolved an issue where the focus outline for the slider arrow buttons (
SFSliderArrowButton.vue
) was cut off. Styling adjustments withinSFProductGallery.vue
now ensure the full outline is visible, improving keyboard navigation feedback. - [Accessibility] To prevent unintended filter updates in
SFPriceRangeSlider.vue
, the@change
event handler has been removed from the price input field. This stops a filter action from being triggered simply by blurring the input. - [Accessibility] Improved screen reader support in the
location.vue
component by adding a requiredaria-label
to a previously unlabeled element. - [Accessibility] Improved screen reader support for the variant picker (
SFVariantPicker.vue
) by adding a descriptivearia-label
to each individual variant option. - [Accessibility] Streamlined keyboard navigation in the
SFPriceRangeSlider.vue
filter modal. The slider bar itself is no longer a focusable element, allowing users to interact more efficiently and directly with the price input fields to set the desired range. - [Accessibility] Corrected an invalid ARIA implementation in
SFShopSwitcherFlyoutBody.vue
by removing arole="menu"
attribute from a<div>
wrapper. This resolves an accessibility issue where the element failed to meet the requirement of containing appropriate child roles (e.g.,menuitem
). - [Accessibility] To meet higher contrast ratio standards, core application colors have been updated.
This includes adjusting the primary red and a key gray value to improve readability, as well as unifying various text colors for a more consistent and accessible experience.
- Updated the primary red (
#E74B3A
→#D1000A
). - Adjusted a key gray (
#080808
→#757575
). - Unified text colors to use
text-gray-500
. - Updated the 'Scroll to Top' button's border to
border-gray-500
.
- Updated the primary red (
- [Accessibility] Corrected the ARIA implementation in
SFProductPromotionBanner.vue
. Thearia-label
is now conditionally applied only when the component is rendered as a link, ensuring proper accessibility without affecting non-interactive instances. - [Accessibility] Fixed the "skip to search" link, which was previously not functioning.
The correct element selector is now being used in
SFSkipLinks.vue
to ensure it works reliably for keyboard users. - [Accessibility] Enhanced readability in the
SFVariantPicker.vue
component by increasing the color contrast between the placeholder text and its background, ensuring it meets accessibility standards. - [Accessibility] Improved accessibility across the application by adding a descriptive
aria-label
to the promotional gift item button and by applyingaria-hidden="true"
to all purely decorative icons, preventing them from being announced by screen readers. - [Accessibility] To ensure proper page structure and improve SEO, a duplicate
<h1>
tag has been removed from the Product Listing Page. The headline within theSFProductListNoResults.vue
component is now correctly set to an<h2>
. - [Accessibility] To ensure proper page structure, the headline on the empty wishlist page has been removed, resolving an issue with a duplicate
<h1>
tag. This change also visually aligns the page with the empty basket view. - [Accessibility] To improve screen reader support, a visually hidden but accessible label has been added to the main search input.
- [Accessibility] To ensure proper keyboard interaction, the search input trigger has been assigned
role="button"
. This correctly identifies it as an interactive element for assistive technologies and resolves the "Non-active element in tab order" issue. - [Accessibility] To ensure proper keyboard interaction and screen reader support, required ARIA roles have been added to interactive elements within the
SFBasketCard.vue
andSFSearchInput.vue
components. - [Accessibility] To improve screen reader support during a password change, a visually hidden but accessible label has been added to the email field within the
SFProfilePasswordManagement
component. - [Accessibility] To prevent focusable elements from being hidden by the sticky action bar, a scroll margin has been added to all focusable items within the
SFSlideIn.client.vue
component. - [Architecture] The Product Detail Page's architecture has been enhanced by assigning it a static page key, which prevents full page reloads when toggling between variants and siblings. This change also allowed us to simplify the codebase by removing a page-specific middleware and merging its URL correction logic directly into the PDP component.
- [Architecture] Removed the now-redundant
router.options.ts
file. This custom configuration for preserving scroll position on navigation is no longer needed as this behavior works now out of the box in Nuxt 3. - [Architecture] To simplify the codebase, the
useFilterSlideIn
composable has been removed. Its logic was inlined, as the wrapper was an unnecessary layer of abstraction. - [Architecture] Added new linting rules for i18n using
@intlify/eslint-plugin-vue-i18n
. Developers will now see warnings or errors for improperly formatted or missing translation keys directly in their IDE. - [Architecture] Resolved an issue where navigating between categories on the Product Listing Page (PLP) was unresponsive. This was caused by a reactivity problem after a recent change prevented the page from fully reloading. The fix moves all category data fetching logic from the now-removed middleware directly into the PLP component, ensuring data updates correctly on navigation.
- [Basket] Resolved a bug in
SFBasketDeleteConfirmationModal
component by assigning its return value to thevisible
constant. This resolves an issue where the modal's visibility state was not being properly managed. - [Basket] Corrected the state handling for promotional gifts to enable the addition of multiple gift products.
Previously, the
variantId
of the initial gift was not being cleared, which blocked subsequent gift additions. - [Basket] To improve code maintainability, the empty and unused
useBasketItem
composable has been removed from the codebase. - [Build] To optimize the final Docker image size and build speed, the
.dockerignore
file has been extended. This prevents development files, such as the Playwright test suite, documentation, and local environment configurations, from being unnecessarily copied into the build context./playwright
README.md
CHANGELOG.md
CHANGELOG-RC.md
docker-compose.yml
vitest.config.ts
.prettierrc
.prettierrc.cjs
.prettierignore
.eslintrc.js
.eslintignore
.gitignore
.dockerignore
.nvmrc
- [Build] OpenTelemetry data can now be automatically enriched with Git repository information for improved observability.
To include the commit SHA and repository URL in your telemetry, pass the corresponding build arguments when creating the Docker image:
- [CMS] The
useCMSBySlug
composable has been enhanced to be fully reactive. It now automatically re-fetches CMS data whenever the provided slug changes, ensuring the content stays in sync with the state. - [CMS] To improve code organization and encapsulation, the
useBanner
composable has been moved from the global application context and is now properly integrated within the dedicated localcms
module. - [E2E] Addressed a potential test failure by updating the locator for the "accept terms and conditions" checkbox on the Checkout page. This change was required to adapt our Order Success Page (OSP) test suite to recent modifications in the checkout UI.
- [E2E] Aligned the Orders page end-to-end test (
e2e-Orders.spec.ts
) with a recent UI update. The test now correctly verifies the new order number display format, which uses a#
separator instead of a:
. - [E2E] The end-to-end tests for user authentication have been refactored to improve maintainability and clarity.
The constant objects related to logged-in user and registration tests have been updated, and comprehensive JSDoc documentation has been added to explain the required environment variable setup for dedicated test users.
Inline comments now outline the prerequisites, including the creation of specific test users via environment variables.
TEST_USER_EMAIL1=
: Dedicated test user for Chromium and default test user across end-to-end tests.TEST_USER_EMAIL2
: Dedicated test user for desktop Firefox.TEST_USER_EMAIL3
: Dedicated test user for desktop Webkit (Safari).TEST_USER_EMAIL4
: Dedicated test user for mobile Chrome.TEST_USER_EMAIL5
: Dedicated test user for mobile Webkit (Safari).TEST_USER_NO_ORDERS
: Test user with no orders placed. Used to verify Orders page empty state.TEST_USER_PASSWORD=
: Password (the same for all test users listed above).TEST_USER_WRONG_PASSWORD
: Password used for test that verifies user authentication with wrong credentials.TEST_USER_GUEST
: Test user used to verify Registration process for guest user.
- [E2E] To further improve the stability of end-to-end tests that navigate to the Product Listing Page, an additional wait condition has been added. Tests will now explicitly wait for the PLP breadcrumb element to be visible, preventing failures caused by race conditions or slow page loads.
- [E2E] Expanded end-to-end test coverage for the Orders page.
The test (
e2e-Orders.spec.ts
) now also verifies that the order status is correctly displayed on both the main order list and the individual order detail pages. - [E2E] To speed up test execution in non-Vercel environments, Vercel-specific HTTP headers are now applied conditionally.
This is controlled by the
isTargetingVercel
environment variable in the Playwright configuration, preventing unnecessary overhead. - [E2E] To improve test suite maintainability, the page object model (
playwright/page-objects/
) has been cleaned up. Outdated and unused DOM locators and methods were removed, resulting in a leaner and more manageable codebase. - [E2E] The end-to-end test for user data updates has been adapted to accommodate recent UI changes.
The
updateUserData()
method now uses the new, required birth date format to ensure the test remains stable and accurate. - [E2E] To improve the developer experience when working with the end-to-end test suite, a significant refactoring has been completed. This includes reorganizing shared constants, adding detailed JSDoc comments to explain the purpose and setup for each test, and ensuring consistent use of constants across the suite, making tests easier to read, run, and maintain.
- [E2E] To simplify the process of running and understanding our end-to-end tests, all test files have been updated with detailed JSDoc documentation.
Developers can now find the purpose, scope, and all necessary prerequisites—including required environment variables for test users and specific setup notes—directly within each test file, streamlining the testing workflow:
e2e-CountryDetector.spec.ts
: Explanation of timezone forcing for Country Detector modal testing.e2e-Footer.spec.ts
: Description of the test suite's scope.e2e-Orders.spec.ts
: Details on environment variable setup for test user credentials.e2e-OrderSuccessPage.spec.ts
: Prerequisites regarding product availability for successful order completion.e2e-Wishlist.spec.ts
: Scope and environment variable requirements for test user credentials.
- [E2E] To enhance test robustness, key end-to-end tests have been updated to reduce their dependency on specific content and product data. SEO verification on the PDP, Wishlist, Login, and Basket pages now performs more generalized checks instead of asserting exact text. Additionally, the Basket empty state test has been simplified to be independent of specific labels, ensuring greater stability.
- [E2E] The end-to-end test for the Basket's empty state (
e2e-Basket.spec.ts
) has been made more stable. A new step now automatically clears any pre-existing items from the logged-in user's basket, ensuring the test is reliable and independent of prior user activity. - [E2E] To improve maintainability, the Search end-to-end tests have been updated to use environment variables for test data.
To run these tests successfully, you must now set the required environment variables to provide appropriate search terms for your specific test environment:
E2E_SEARCH_TERM_PRODUCT
: Search term that doesn't match any category name, so the search suggestions are not shown, e.g. some product brand.E2E_SEARCH_TERM_CATEGORY_SUGGESTION
: Search term that fully or partially matches category name, e.g. "shirt" or "shirts".E2E_SEARCH_EXACT_PRODUCT_ID
: Search term that matches exact product ID, e.g. 123456.E2E_SEARCH_TAGS
: Descriptive search term that returns search suggestion tags in search suggestions list, e.g. "Black shoes size 44".E2E_SEARCH_PAGE
: Search term that fully or partially matches a (content) page, e.g. "faq" or "support".E2E_SEARCH_REFERENCE_KEY
: Search term that matches the exact product reference key, e.g. "123-ref-key".
- [E2E] The end-to-end test suite has been enhanced to be more robust and adaptable across different environments.
We have reduced dependencies on hardcoded product IDs and static URLs, leading to more reliable test runs.
e2e-Account.spec.ts
: Tests now navigate to the User Profile via the Homepage, eliminating the use of hardcoded profile URLs.e2e-Footer.spec.ts
: Footer link verification has been consolidated intoe2e-Homepage.spec.ts
, and the dedicated Footer links test has been streamlined.e2e-Orders.spec.ts
: Introduced an environment variable to provision test users with no prior orders.e2e-OrderSuccessPage.spec.ts
: Exact page title and description are no longer the part of SEO checks.e2e-Pdp.spec.ts
: Product information (name, brand, price) and Wishlist interactions are now generalized, removing the need for specific Product ID.e2e-Wishlist.spec.ts
: Verification of Wishlist contents and SEO elements is now independent of specific Product ID.
- [E2E] Improved the robustness of product variant selection in end-to-end tests.
A new method,
chooseProductVariant()
, now intelligently checks if the variant picker is disabled (for single-variant products) or enabled (for multi-variant products), ensuring tests can reliably handle different product types. - [E2E] Improved the reliability of the mobile Order Success Page test.
The test was refactored to navigate from the PLP to the PDP by clicking the product image, and size selection now uses a forced click (
{force: true}
) to prevent CI-related timeouts. - [E2E] Improved the end-to-end test suite for greater reliability and easier maintenance. Key changes include:
- Product Independence: Core tests (Basket, Checkout, OSP) now select the first available product variant instead of relying on hardcoded IDs.
- Category Independence: Navigation tests now dynamically traverse menus and categories, removing dependency on a fixed site structure.
- Test Suite Cleanup: Removed obsolete tests and their associated data to streamline the test suite.
- [E2E] Added an automated test to validate the behavior of our 404 "Page Not Found" error handling. The test simulates a user navigating to an invalid URL and asserts that the correct error page is displayed with the proper 404 code and a "Continue shopping" button.
- [Promotions] The promotional gift selection modal has been streamlined by removing price details from the available gift options.
- [Promotions] Corrected an issue where promotion badges for free gifts in the basket (
SFBasketCardImage.vue
) used custom frontend logic. The implementation has been changed to remove this custom label and derive the badge from the basket item's data, ensuring it reflects the actual promotion configuration. - [Promotions] To improve maintainability and reduce the codebase size, the unused
SFPromotionHeadline.vue
component has been removed. - [Promotions] To improve code quality and maintainability, obsolete code related to inline gift selection has been removed.
This includes the isLastItemWithPromotions function in
SFBasketAvailableItems.vue
and theshow-free-gift-selection
prop inSFBasketCard.vue
, both of which have been unused since Storefront Applicationv1.9.0
. - [Subscriptions] The
useSubscriptions
composable is now fully reactive. It will automatically re-fetch and update subscription data when the provided productref
changes, ensuring information always stays in sync. - [UI] To improved visual consistency, the mobile menu's overlay 'close' button has been restyled and enlarged to match the appearance of other icons in the header.
- [UI] To improve visual consistency, the 'sold out' indicator in
SFProductPromotionGiftItems.vue
now uses the sharedproduct-sold-out
color class, aligning its appearance with othersold-out
indicators across the application. - [UI] To improve visual consistency and depth, shadows have been added to the arrow buttons used in the product card slider and the image zoom gallery.
- [UI] To improve code quality and reduce bundle size, several unused animation styles (
ping
,ping-small
,grow
,shrink
) and their associated keyframes have been removed. The unusedanimateIcon
prop inSFButton
has also been deprecated as part of this cleanup. - [UI] Refactored slider arrow controls by replacing
SFProductCardImageSliderButton
and customSFButton
implementations with the newSFSliderArrowButton
component. This change centralizes logic and styling for a more maintainable and consistent codebase. - [UI] To improve visual consistency across form elements, the styling for the date input (
<SFTextInput type="date" />
) has been updated to match the appearance of other text input types. - [UI] To improve the layout of color filters, the
SFFilterColorChip
component now truncates long color names, preventing them from overflowing or wrapping awkwardly. - [UI] To improve code maintainability and reduce bundle size, several unused Tailwind plugins and their associated custom styles have been removed.
.top-white-shadow
: Custom box-shadow..search-decoration-none
: Removes default search input decorations.- Base styles for search inputs: Resets WebKit-specific search input decorations.
- [UI] To provide a more consistent and predictable user experience, the
SFStoreOpeningTimesSummary.vue
component will now always display the week starting on Monday. We've removed the locale-specificuseFirstDayOfWeek
composable and the correspondingintl.first_day
translation key to achieve this. If your project requires a localized start day, you can re-implement this functionality using the composable below. - [Utilities] Removed the usage of deprecated helper functions
isFirstIndexOfRow
andgetRowByIndex
. Their logic has been moved directly into the components where it was used, simplifying the codebase. - [Utilities] To standardize how product prices are handled, the custom price logic has been replaced with the official
useProductPrice
composable provided by@scayle/storefront-nuxt
. - [Utilities] To improve how product details are retrieved on the order detail page,
SFOrderDetailProductCard.vue
now uses theuseProductBaseInfo
composable for a more standardized approach. - [Utilities] To centralize reusable code, the specific logic for date validation has been transferred to the Storefront Application codebase.
Additionally, the local
useValidationRules()
composable has been enhanced with JSDoc comments for better documentation and clarity. - [Utilities] The return value of the
useProductBaseInfo
composable has been updated. It now returns the specificcolor
of the current product, rather than an array of all availablecolors
. - [Utilities] To simplify usage and improve consistency, the
useFormatDate
anduseFormatDistance
composables have been consolidated into a single, unifieduseFormat
composable. As part of this change,formatLocaleDate has been renamed to the simpler
formatDate, and it now returns undefined (instead ofnull
) when no locale is available, aligning with our standard patterns. - [UX] To improve code reuse and consistency, logic for the site logo has been extracted into a new
SFLogoLink
component. Shared across theSFHeader
andSFFooter
, it implements a "scroll-to-top" function when the logo is clicked on the home page.
🩹 Patch Changes
- [Architecture] Updated the
svgoConfig
implementation to merge with the default settings rather than completely replacing them. This prevents unintended side effects, such as icon alignment issues, caused by an incomplete configuration. - [Architecture] Addressed a potential build failure related to a sub-dependency of the
@nuxtjs/tailwindcss
module. The packageunicorn-magic
is now pinned tov0.2.0
as a resolution, mitigating a potential fatal build error. See https://github.com/nuxt-modules/tailwindcss/issues/954 for more details. - [PDP] Resolved a styling issue where the focus outline on the breadcrumb links was being partially obscured or cut off.
- [PLP] Restored custom styling for "Sale" categories in the side navigation by adding a
sale
property to the category fetch request, ensuring the necessary data is available for styling hooks. - [Subscription] Resolved a styling issue on the Product Detail Page where the focus outline for the subscription dropdown was being partially obscured or cut off.
- [UI] Resolved a styling issue that caused a broken appearance for the close button within the
SFFilterHeader
andSFStoreLocatorSlideIn
components. - [UI] Resolved a DOM collision issue by ensuring the SVG ID attribute for the empty state icon is unique. This fixes a consequential bug where the icon failed to render correctly.
- [UI] Fixed a layout issue on smaller screens where the
SFSearchInput.vue
component was not taking up the full available width. The input field is now correctly styled to span the full width on mobile devices. - [UI] Enhanced the
v-dialog
directive to be more robust. It now correctly handles cases where a modifier might beundefined
, preventing potential runtime errors. - [\UI] Resolved a layout issue in the
SFProductRecommendations
component where slider buttons could overlap the section title. This was corrected by adjusting the button sizes and implementing title truncation. - [UI] Addressed a Safari-specific rendering bug where an unwanted shadow would appear on the main content area after closing the filter slide-in.
This was resolved by adding a
focus:shadow-none
utility class to thedefault
layout'smain
tag.
🏡 Dependency Updates
- Added dependency
@scayle/[email protected]
- Added dependency
@scayle/[email protected]
- Added dependency
@scayle/[email protected]
- Added dependency
[email protected]
- Added dependency
@intlify/[email protected]
- Added dependency
@parcel/[email protected]
- Removed dependency
[email protected]
- Removed dependency
[email protected]
- Updated dependency
@contentful/[email protected]
to@contentful/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[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
@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
@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
@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
@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
[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
@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
@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]
- Updated dependency
[email protected]
to[email protected]
1.9.1
🩹 Patch Changes
- [CMS] Resolved styling defects and functional issues with the CMS Slider component.
The problems stemmed from a missing
nuxt-swiper
dependency, which has now been correctly added and configured.
🏡 Dependency Updates
- Added dependency
[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
[email protected]
to[email protected]
1.9.0
🔥 Highlights
🎁 Enhanced Promotions
We've significantly updated our Promotions integration, focusing on simplifying implementation, shifting towards more backend-driven logic, and making Storefront integration easier.
Key highlights include:
- Easier Integration: A new
@scayle/storefront-promotions
module with auseApplyPromotions
composable greatly simplifies the developer effort needed to ensure promotions are accurately applied to the basket in within any Storefront Application. - Smarter Promotion Display: Reflecting more refined backend logic, information about promotional gifts on Product Detail Pages (using the
SFProductPromotionGifts
component) now only appears when specific conditions are met, and promotions listed in the slide-in panel are now correctly sorted by priority. - Flexible Backend Control: The underlying structure for promotion custom data has been revised, providing enhanced flexibility for backend configuration of promotion presentation details like headlines, colors, and links. Components like the basket summary promotions display have been updated to utilize this structure.
👤 Redesigned Account Area
The Account Area of the Storefront Application has received a significant overhaul, focusing on improved usability and a more unified experience!
- Unified Account: Access your Profile, Orders, and Subscriptions from a newly redesigned central account page.
- Redesigned Profile & Orders: Enjoy completely revamped Profile, Orders list, and Order Detail pages with clearer layouts, comprehensive information (including detailed payment summaries and product info on order details), and easier management.
- Enhanced Management: Effortlessly update your personal details (name, gender, birth date) and change your password on the redesigned Profile page.
- Improved Navigation: Order items listed in your history are now clickable links directly to the product page, and the "Back" button on order detail pages provides smarter navigation.
- Visual Consistency: The Subscriptions page title now aligns visually with the rest of the refreshed Account Area.
🔧 UI Refinements, Accessibility Improvements & Performance Optimizations
This update introduces a variety of enhancements across the Storefront Application, focusing on improving accessibility, refining the user interface, and boosting performance:
- Accessibility: Keyboard navigation has been significantly improved, ensuring skip links and the header user menu are fully accessible. Screen reader support is also enhanced, notably providing clearer context for order detail links in the account area.
- UI Refinements: Experience a smoother interface with visually improved skeleton loaders that reduce layout shifts, more predictable behavior for filter panels (staying open when applying filters) and user popovers (closing automatically), and fixes for modals that previously stayed open incorrectly during navigation. Additionally, a logout button is now available in the mobile sidebar, and price inputs better restrict values to valid ranges.
- Performance Boosts: Enjoy faster internal page navigation thanks to optimized breadcrumb links that prevent unnecessary page reloads. We've also reduced redundant background API calls triggered by the price range filter and optimized how common UI elements like modals and slide-ins load for better overall performance.
🚀 Major Changes
- [Account Area] Introduced a completely redesigned Order Detail page, structured for clarity and comprehensive information.
The page features a detailed list of all ordered products, complete with in-depth information about each item.
At the bottom, a Payment Summary section presents a clear breakdown of the subtotal, shipping costs, and the final total.
The page is thoughtfully organized into sections, including:
- Order Details: Displays key information about the order.
- Payment Details: Provides a breakdown of payment methods.
- Delivery/Billing Address: Highlights the addresses associated with the order.
- [Account Area] Improved the navigation flow from the order detail page.
The "Back" button now provides a more seamless experience by returning the user to the
/orders
list page, unless they were just on that page, in which case it functions as a standard browser back action. - [Account Area] Introduced a redesigned profile page enabling users to easily manage their information. Key features include viewing consolidated account details, updating personal information (first/last name, gender, birth date), and changing their password, all within clearly defined sections.
- [Account Area] Items displayed using the
SFOrderItemCard
(e.g., in order details) are now clickable links, allowing users to easily navigate to the corresponding product page. - [Account Area] Introduced a fully redesigned "My Orders" page. The new layout presents a comprehensive list of the user's past orders, displaying key details for each entry and including a direct link to the specific Order Detail page for more information.
- [Account Area] Introduced a unified main Account page that seamlessly integrates sub-sections for Profile Management, Subscription Details, and Order History into a single, cohesive interface.
- [Account Area] Updated the visual styling of the Subscriptions page title to align consistently with the presentation of other pages within the Account Area. The page's core functionality and integrated subscription component remain unchanged.
- [Promotions] Promotions presented in the promotion slide-in panel (
SFPromotionSlideIn.vue
) are now ordered according to priority, ensuring higher-priority promotions are listed first. - [Promotions] The
SFProductPromotionGifts
component is now shown conditionally on the Product Detail Page, appearing only when its gift promotion criteria are met. - [Promotions] Revised the data structure for custom data associated with promotions.
Refer to the
PromotionCustomData
TypeScript interface for the new schema details (including fields likeheadline
,product
,color
,link
, etc.). TheSFBasketSummaryPromotions.vue
component has been updated to work with this new structure.- New
PromotionCustomData
Interface:
- New
- [Promotions] Added the
@scayle/storefront-promotions
module. Developers can now leverage theuseApplyPromotions
composable to integrate logic that automatically updates promotions on basket items during any basket change event (add, remove, update quantity).- Example Usage
- Example Usage
💅 Minor Changes
- [E2E] Added automated tests to confirm that the skip links functionality works as expected for keyboard users, specifically validating navigation to the "Main content" and "Search" targets.
- [E2E] Introduced a new end-to-end test suite for the password change functionality. Coverage includes both successful password updates and expected failure scenarios (e.g., incorrect old password, policy violations).
- [E2E] Implemented new end-to-end tests to ensure the reliability of the User Account Area. Test cases validate page load, navigation through its tabs, the data update process, and crucial input validations such as birth date format checking.
- [E2E] Added specific end-to-end test steps to validate the simplified footer shown during the checkout flow.
The tests confirm both its visual rendering accuracy and that all embedded links correctly utilize
target="_blank"
(open in new tab). - [E2E] Added end-to-end tests for the Login and Registration user flows. Key checks include ensuring the tab-based switching between forms works correctly and that mandatory links like the Privacy Disclaimer launch in a separate browser tab as required.
- [E2E] Store Locator E2E tests are now skipped by default in automated/scheduled test runs to save resources.
To execute them manually, remove the
.skip
suffix from the tests inplaywright/tests/e2e-StoreFinder.spec.ts
and relevant steps inplaywright/tests/e2e-Pdp.spec.ts
. - [E2E] Aligned the end-to-end test for gift product quantity handling in the basket with recent updates to the promotion system. The test now correctly validates quantity increments based on the current promotion rules.
- [E2E] Expanded end-to-end test coverage for the Orders page. Tests now verify the page's appearance and functionality for both users who have an order history and users who have no orders (empty state).
- [UI] Resolved a layout issue where the wishlist toggle button on product cards could overlap and obstruct the global "Scroll to Top" button, ensuring both elements remain clickable.
- [E2E] Aligned the login and logout end-to-end test flows with recent application updates. Specifically, tests were modified to accommodate changes within the User Profile section and the new logout interaction path on mobile.
- [E2E] Modified the end-to-end test to validate country selection in a language-agnostic way. The test no longer checks the visible country label (which varies with language settings) and instead confirms the selection using a stable, non-display mechanism.
- [E2E] Aligned end-to-end test scenarios with the latest Promotion feature updates. Tests covering the Promotion Ribbon and Promotions Flyout components have been modified to match the new expected behaviors and appearances.
- [Navigation] Improved the navigation experience by ensuring the sidebar (
SFMobileSidebar.vue
) consistently closes itself before transitioning the user to the selected page. - [OSP] Adopted the
SFASyncDataWrapper
component to manage and display UI states related to asynchronous data fetching, improving consistency and reliability. - [Subscriptions] Renamed the URL route for the subscriptions section from
/subscription
to/subscriptions
. - [UI] Refactored the handling of the gift selection modal (
SFProductPromotionSelectionModal
). Firstly, its visibility state is now managed locally within this component instead of using globaluseState
, resolving an issue where the modal incorrectly remained open after page navigation. Secondly, the implementation now utilizes a single, reusable modal instance for all gift options, optimizing component usage. - [UI] Prevented the filter panel (
SFFilterSlideIn.vue
) from automatically closing when the page route changes. This allows the panel to stay open when filters are applied, as filter application modifies the route via URL parameters. - [UI] Refined the Product Card's skeleton loader (
SFProductCardSkeleton.vue
) to better resemble the finalSFProductCard.vue
layout. This ensures a smoother visual transition as content loads and reducing layout shifts. - [UI] The user navigation popover now automatically closes when it loses focus (e.g., when the user clicks outside of it or tabs away with the keyboard).
- [UI] Applied
min
andmax
attributes to the underlying HTML input element within the price input component (SFPriceInput.vue
). This introduces browser-level validation to restrict input to the specified range. - [UI] Implemented a dedicated logout button within the mobile sidebar, enabling users to properly log out of their accounts directly from mobile devices.
🩹 Patch Changes
- [Accessibility] Corrected the behavior of skip links to ensure they are only visible and interactive when receiving keyboard focus (e.g., via the Tab key). This prevents accidental activation by mouse users.
- [Accessibility] Enhanced accessibility by enabling the user menu in the header to be opened via the keyboard. This ensures keyboard-only users can access account-related actions like Profile or Logout.
- [Accessibility] Added
orderId
to the order detail button'saria-label
on order cards for better screen reader context (via translation key update). - [Architecture] Standardized date presentation by updating the
formatLocaleDate
utility. It now consistently outputs dates in a short numeric format and is being reused across various parts of the application. The function's signature has changed: it now requires aDate
object as input, with date string parsing delegated to the calling code. - [Performance] Modified the
useBreadcrumbs()
composable to generate relative URLs instead of absolute URLs. This prevents Nuxt from treating breadcrumb links as external, which previously caused unnecessary full page reloads. Navigation via breadcrumbs now uses client-side routing. - [Performance] Optimized the price range filter by removing the
@update:model-value
event listener from theSFPriceRangeSlider
component. This eliminates redundant API calls that were previously triggered during the slider adjustment process. - [Performance] Optimized the
SFModal
andSFSlideIn
components by designating them as client-only. Since their functionality is entirely based on client-side user interaction, this prevents unnecessary server-side rendering and can improve initial page load performance. - [SEO] Enhanced URL handling for Product Detail and List Pages during client-side navigation. The application now automatically ensures the user lands on the SEO-optimized URL, redirecting from any non-canonical versions if necessary.
- [OSP] Improved error handling for cases where an order cannot be found. The correct empty state page is now displayed as intended.
- [OSP] Implemented error handling for failed attempts to fetch order data. In case of failure (e.g., network or server error during fetch), the user is now directed to the standard Nuxt error page.
- [PDP] Corrected visual inconsistencies in the skeleton loader's appearance across different screen widths. The loader now maintains proper alignment and styling at all relevant breakpoints.
- [PDP] Resolved a hydration mismatch error related to product subscriptions. The fix ensures that product subscription data is fetched and included during server-side rendering (SSR), preventing inconsistencies between the server-generated HTML and the client-side render.
- [Unit Testing] Updated unit tests to import and use
buyXGetYPromotionFactory
with the correct casing from the@scayle/storefront-nuxt
package, replacing the previously used incorrectbuyXgetYPromotionFactory
. - [Unit Testing] Added a global
vi.mock()
for therouteChangeTrackingObserver.global.ts
middleware. This intercepts the middleware import during tests and provides a dummy function (vi.fn()
) instead. This is necessary because the original middleware'ssetTimeout
could attempt to access the DOM (document) after happy-dom was destroyed, causing errors. Global mocks are now managed in the renamedtest/vitest-setup/storefront.ts
.- Renamed
test/vitest-setup/storefront-nuxt.ts
totest/vitest-setup/storefront.ts
to define global mocks.
- Renamed
🏡 Dependency Updates
- Added dependency
@scayle/[email protected]
- Added dependency
[email protected]
- Added dependency
[email protected]
- Added dependency
@contentful/[email protected]
- Added dependency
[email protected]
- Removed dependency
[email protected]
- Removed dependency
[email protected]
- Updated dependency
@contentful/[email protected]
to@contentful/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[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
@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
@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
[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
@eslint/[email protected]
to@eslint/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[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
[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.8.0
🔥 Highlights
✨ Streamlined CMS Integration in SCAYLE Storefront
We've streamlined our CMS integration to simplify setup, boost performance, and focus on content pages. A new static placeholder CMS provider (scayle
) makes initial setup for development purposes a breeze . Content fetching and display are also improved with new components like CMSProductListingPageTeaser
and CMSContentPage
, replacing older, less efficient methods. We've also removed service page support from the Storyblok and Contentful integrations, concentrating our efforts on content pages for a more streamlined experience.
🔑 Revamped Login & Registration
We've completely overhauled our login and registration process for a smoother, more user-friendly experience. Enjoy a cleaner login interface with simplified customization options for tenants. The redesigned registration flow now includes guest registration and support for IDP registration, along with prominent links to privacy and terms. Password resets are also streamlined with a new UI and improved security. Finally, we've boosted performance with server-side rendering and simplified data handling. These enhancements provide a more accessible and efficient login and registration journey for all users.
🛍️ Order Success Page Refresh
We've polished the Order Success Page (OSP) to provide a more enjoyable and informative post-purchase experience. Improvements include a visually refreshed greeting box, a redesigned order information section for improved clarity, and a simplified cost summary for easier understanding. These updates create a cleaner, more user-friendly OSP.
🔍 Optimized Search Results Page
We've redesigned the Search Results Page for a smoother, more consistent browsing experience. Leveraging existing components, it now shares the same structure and styling as the Product Listing Page. We've also streamlined filtering, dynamically hiding filter options when no results are found. Sorting is now automatic by relevance, simplifying the interface and prioritizing the most pertinent results. These changes create a cleaner, more user-friendly search experience.
🚀 Major Changes
- [CMS] Introducing a new static CMS placeholder provider
scayle
, that simplifies the initial setup process for Storefront Applications. Thescayle
static CMS placeholder delivers a single CMS page as static content, eliminating the need for access tokens, tenant space IDs, and other configuration typically required when setting up a Storefront Applications and CMS. This new provider is intended for development purposes only and should not be used in production environments. - [CMS] The
CMSCategoryData
fetching component has been removed and replaced by the newly introducedCMSProductListingPageTeaser
component. This new component is designed to handle the rendering of teaser images and manage the associated data fetching for each CMS provided.- Example Usage on PLP:
- Example Usage on PLP:
- [CMS] The
CMSServicePageData
component, responsible for fetching content data for service pages (/pages/s/[slug].vue
), has been removed from all CMS providers. Going forwards the Storefront Boilerplate CMS integration for Storyblok and Contentful are only supporting content pages (/pages/content/[slug].vue
). - [CMS] The
CMSPage
component has been removed from the Storefront Boilerplate and replaced with the newCMSContentPage
component. This change aligns the homepage structure with the refactored CMS content types in Storyblok and Contentful. TheCMSContentPage
component directly renders theCMSStory
component, eliminating the overhead of custom dynamic component loading. Additionally, the introduction of status-specific slots withinCMSContentPage
simplifies data fetching and handling by providing a more structured and predictable approach compared to the previous awaited fetching method in CMSPage. This change improves the overall maintainability and performance of the homepage.- Example Usage:
- Example Usage:
- [Login & Registration] The login user interface has been enhanced to provide a cleaner, more user-friendly experience and greater flexibility for tenant customization. The updated user interface features a standard login form with email and password fields, providing a familiar and intuitive login process. Existing integrations with external Identity Providers (IDPs) like Google remain unaffected by these changes. A key improvement in this update is the removal of IDP-specific styles that were previously embedded in the login user interface. This change simplifies the UI and empowers tenants to fully customize the styling and branding of their login experience, ensuring seamless integration with their overall website design.
- [Login & Registration] The user registration process has been completely redesigned for a more intuitive and streamlined experience. The new flow features a redesigned registration form with fields for gender, first name, last name, email, and password. A guest registration option simplifies the process for users who prefer not to create an account, omitting the password field. Support for IDP registration has been integrated, offering a secure and convenient way to sign up using existing identity providers. This implementation maintains a consistent and clean style, mirroring the design of the login page. Furthermore, prominent links to the privacy policy and terms of service are now displayed during registration, ensuring user awareness and compliance.
- [Login & Registration] The forgot password process has been redesigned with a new user interface.
A
"forgot password"
button on the login page now opens a slide-in form for requesting a password reset link. The reset link directs users to the sign-in page, where another slide-in form allows them to set a new password. Email validation and other improvements ensure a smooth and secure password reset experience. - [Login & Registration] Users will experience a smoother and more accessible login process.
The login/registration flow has been redesigned with a focus on simplicity and accessibility.
Changes include:
- UI/UX: Simplified layout, updated styling for text input fields and gender selection, and enhanced accessibility features (improved semantics and keyboard navigation).
- Functionality: Standardized handling of
redirectUrl
to ensure users are redirected to their intended destination after login. Improved form validation and more informative error messages displayed in a dedicated error container. Successful logins are now confirmed with a toast notification. - Performance: Implemented SSR for the signin page, resulting in faster initial load times. Removed client-side handling of the last logged in user information, eliminating the need for local storage management and further improving performance.
- [OSP] Improved the look and feel of the greeting box.
- [OSP] The order information section has been redesigned for a clearer and more user-friendly experience.
- [OSP] The cost summary on the Order Success Page has been simplified to improve clarity and user experience.
- [Search] The Search Results Page has undergone a redesign to create a more consistent and user-friendly experience.
By leveraging composables from
@scayle/storefront-product-listing
, the page now shares the same underlying structure and styling as the Product Listing Page, providing a unified browsing experience. The filtering functionality has been streamlined; the filters button is now dynamically hidden when no search results are returned, reducing visual clutter. Additionally, the sorting button has been removed as search results are now automatically sorted by relevance, simplifying the user interface and prioritizing the most relevant results. This redesign enhances usability and improves the overall search experience.
💅 Minor Changes
- [Architecture] Simplified component prop declarations by leveraging Vue's reactive destructuring.
This allows for more concise and readable prop definitions, reducing boilerplate code.
- Example:
- Example:
- [Architecture] Improved the Storefront Application's internationalization (i18n) implementation by switching to direct usage of the
useI18n
composable within thesetup
script blocks. This approach offers several advantages over accessing i18n throughuseNuxtApp
:- Simplicity: Directly using
useI18n
is simpler and more intuitive, reducing the complexity of code. - Performance: Accessing
useI18n
directly can be more performant as it avoids the additional overhead of going throughuseNuxtApp
. - Type Safety: Direct usage often provides better TypeScript support, ensuring type safety and better developer experience.
- Readability: It makes the code more readable and maintainable by clearly indicating the use of i18n functionalities.
However, it's important to note that this change introduces a constraint:useI18n
must now be called directly within thesetup
script. Attempting to use it within other composables that are not called within setup will result in an error. This trade-off is considered acceptable given the overall benefits of this optimization. - Simplicity: Directly using
- [Architecture] Improved the reactivity of several key composables (
useSubscription
,useProductBaseInfo
,useRowIntersection
, useProductPromotions,useProductPrice
,usePagination
, anduseBasketPromotionReductions
) by optimizing how getter values are passed and explicitly usingtoRef
where needed. This ensures consistent and predictable reactivity throughout the application. For more details, see the Vue documentation on prop passing. - [Architecture] Integrated the
@scayle/nuxt-image-provider
Nuxt module to optimize image delivery and leverage the full capabilities of the SCAYLE CDN. This module introduces a dedicated provider for@nuxt/image
, enabling support for SCAYLE-specific image modifiers that provide greater control over image transformations and optimizations. The module also includes theScayleImg
andScaylePicture
components, which offer a simplified way to integrate images optimized for SCAYLE CDN within your application. This enhancement improves image performance, reduces bandwidth consumption, and simplifies image management. - [Architecture] Enforced consistent
defineEmits
type-literal
syntax using thevue/define-emits-declaration
ESLint rule.- Before:
- After:
- Before:
- [Accessibility] The
SFProductCard
component now has a role of"link"
and theSFProductImage
component within theSFProductGallery
component now has a role of"button"
. This improves how these elements are interpreted by screen readers and other assistive devices. - [Accessibility] Improved the accessibility of the side navigation open button by providing an
aria-label
. - [Accessibility] Refactored the keyboard interaction logic for the
SFSlideIn
component within the localstorefront-ui
module. The core keyboard behavior, including focus trapping, tab order management, and 'Esc' key functionality, is now centralized within theSFSlideIn
component. This change eliminates redundant code in individual slide-in instances (e.g.,SFFilterSlideIn.vue
) and ensures consistent accessibility features across all slide-in components. - [Accessibility] Improved the accessibility of the
SFSearchInput
component by adding anaria-placeholder
attribute to the input field, providing better support for assistive technologies. - [Accessibility] Enhanced the accessibility of the
SFQuantityInput
component by adding anaria-label
attribute to the input field. - [Accessibility] Enhanced filter accessibility by adding
aria-label
attributes to filter elements, including the price range slider, size selection checkboxes, and the close button. This improvement makes filtering more accessible for users of assistive technologies such as screen readers. - [Accessibility] Improved accessibility for screen readers on the search button (
SFSearchInput
component). Usingaria-hidden=true
now correctly conveys the button's function to assistive technologies. - [Authentication] Refactored
/middleware/authGuard.global.ts
to conditionally fetch user data, skipping the process when an unprotected route is accessed. This optimization reduces the number of network requests and improves page load times. - [Authentication] Strengthened application security by centralizing route access control using route names within the global authentication guard (
/middleware/authGuard.global.ts
). The list of available routes (/utils/route.ts
) has been updated to contain all available routes to support this enhancement. - [Authentication] A redirect fallback to the homepage has been added for authentication flows. If no redirect URL is present in the query parameters, users will now be redirected to the homepage after authentication. This provides a smoother experience and prevents potential redirect errors.
- [Build] The file watcher has been configured to ignore files that are not relevant to the build process. This optimization reduces the workload on the watcher and improves overall build times during local development.
- [CMS] The
CMSAppFooterData
component has been removed from all CMS providers. This component was previously used to fetch and render footer links, but this approach has been replaced by a more efficient and centralized method. Footer content is now managed through dedicated composables from the@scayle/storefront-nuxt
package and configured using SCAYLE Navigation in the Panel. This change reduces code duplication and simplifies maintenance while providing a more consistent and flexible approach to managing footer links. - [Login & Registration] Enhanced the
404
error message to provide clearer and more user-friendly guidance. - [Login & Registration] The gender selection dropdown on the login and registration pages has been visually enhanced to seamlessly integrate with the design of the text input fields. This change creates a more cohesive and user-friendly form experience.
- [E2E] Expanded the promotions end-to-end test suite with scenarios covering the display and hiding of terms and conditions within the promotion tile, ensuring correct functionality.
- [E2E] Implemented E2E tests covering the resolution of matched pages and result accuracy in the Search feature when searching by product reference key. This ensures that searches using product reference keys consistently return the expected results.
- [E2E] Implemented end-to-end tests to verify the accuracy of SEO data on the Product Details, Basket, and Wishlist pages.
- [E2E] Expanded E2E test coverage to include validation of the
variantId
URL parameter on PDPs for products with multiple sizes and available variants. - [E2E] Added Guest User Registration E2E Test: A new end-to-end test has been implemented to cover the complete guest user registration process. This test validates the functionality and user flow of registering as a guest, ensuring a smooth and error-free experience.
- [E2E] Implemented an end-to-end test to verify the display of product variant availability information on the Product Details Page (PDP).
- [E2E] Implemented end-to-end tests to verify the behavior of updating product quantities in the basket, considering different maximum available quantity thresholds.
- [E2E] Implemented additional step in Order Success Page end-to-end test to verify page SEO data.
- [E2E] Implemented an end-to-end test to verify the display of sold-out products in the user's basket.
- [E2E] Implemented end-to-end tests for the Order Success page, covering the following key components: Greeting box, Payment details, Order details, Delivery address, Product card, Price summary, and CTA buttons. These tests ensure that the page renders correctly and all interactive elements function as expected after a user completes an order.
- [E2E] Expanded E2E test coverage to verify default Store Locator visibility on PDPs for one-sized products.
- [E2E] Implemented end-to-end tests to validate the accuracy of SEO data on the PLP for default views, filtered results, and sorted listings.
- [E2E] Implemented an end-to-end test to verify the handling of registration attempts with an existing email address.
- [E2E] Implemented an end-to-end test to verify the password reset process.
- [E2E] Implemented an end-to-end test to verify the functionality of the password visibility toggle on the Registration page.
- [E2E] Implemented an end-to-end test to verify the Order Success Page behavior when accessed with an incorrect CBD token.
- [E2E] Implemented end-to-end tests to verify the complete password reset process, including both successful resets and error handling.
- [E2E] Implemented end-to-end tests to verify the
variantId
URL parameter behavior on Product Detail Pages (PDPs) for both available one-size products and sold-out variants of multi-size products. - [E2E] Implemented an end-to-end test to ensure the Country Detection modal operates correctly, even when another flyout is already open.
- [E2E] Implemented end-to-end tests to cover the functionality of increasing and decreasing the quantity of free promotional items within the basket.
- [E2E] Implemented E2E tests to verify the SEO data on the Login and Registration pages.
- [Orders] The
Order
type is improved by introducing a new genericOrder<Product, Variant>
type. The related order helpers are now part of the Storefront Boilerplate and are used withinusePurchaseEvents
, where theuseOrder
generic is now ensuring correct order detail types. - [Search] Migrated to search utilities from
@scayle/storefront-search
and@scayle/storefront-product-listing
, replacing the existing implementation and allowing for improved upgradability and feature updates. - [Search] Migrated from
useSearchData
touseSearch
from@scayle/storefront-search
, providing improved upgradability and feature updates. - [SEO] Add redirect to correct PDP URL when the PDP URL does not match the expected format.
- [SEO] Added OnlineStore schema to homepage.
- [SEO] Added missing meta data to the wishlist page.
- [SEO] Modified
/pages/p/[...productName]-[id].vue
to utilize the ProductGroup JSON-LD schema. - [SEO] Implemented an optional
variantId
query parameter for PDP URLs. When this parameter is present and contains a valid variant ID, the corresponding product variant will be preselected on page load. This improvement enables deep linking to specific product variations and enhances user experience. - [Navigation] The Navigation's
SFNavigationTreeItem
now uses<ScayleImg>
for rendering and loading SVG icons, replacing the previous<object>
method. This addresses layout shifts that occurred due to delayed SVG loading and resolves console errors encountered in certain browsers stemming fromcontent-security-policy
discrepancies. All SVG icons loaded within the NavigationTree items also now use thepreload
attribute for enhanced loading performance. The initial approach with the<object>
tag was intended to enable modifications to the icon's visual appearance, such as color, but caused issues with browsercontent-security-policy
settings, leading to delayed SVG loading and layout shifts for each navigation tree item displaying an SVG icon. The<object>
-based implementation can be easily reinstated if needed. - [Tooling] Updated the OpenTelemetry configuration to capture common headers in span attributes.
- [Tooling] Introducing license-checker to generate a license overview file (
node-licenses.csv
) of used project dependencies. This is crucial for managing legal compliance and risk, ensuring that all used dependencies' licenses are compatible with the projects commercial software's licensing model. This automated overview simplifies audits, minimizes potential legal issues, and streamlines the process of addressing license conflicts.
🩹 Patch Changes
- [Accessibility] Removed arrow key handling from the focus change logic in the following components to align with WCAG accessibility guidelines for keyboard navigation.
- Removed all arrow key navigation in
/modules/ui/runtime/components/core/SFSlideIn.vue
- Removed left and right arrow key navigation in
/components/layout/headers/SFHeaderNavigationItem.vue
- Removed left and right arrow key navigation in
/modules/ui/runtime/composables/useDropdownKeyboardBehavior.ts
- Removed all arrow key navigation in
- [Account Area] Modified the
pickElements
function within theSFAddressSummary
component to support the newOrderAddress
type from@scayle/[email protected]
. This update narrows and clarifies the supported types. - [CMS] Fixed missing product data in
CmsProduct
click event. TheclickProduct
event in theCmsProduct
component was not correctly emitting product data. This issue has been resolved, and the event now includes the necessary product information when triggered.- Related Components:
- Storyblok:
/modules/cms/providers/storyblok/components/Product.vue
- Contentful:
/modules/cms/providers/contentful/components/Product.vue
- Storyblok:
- Related Components:
- [Code Style] Improved clarity and consistency of
ExistingItemHandling
value names within/composables/usePromotionGiftSelection.ts
,/composables/useBasketActions.ts
, and/composables/useBasketActions.nuxt.test.ts
- [Config] Improved Redis connection stability by adding
maxRetriesPerRequest
to prevent indefinite hangs. - [Config] Extended the
PublicShopConfig
interface with a new property:countryCode
. This addition addresses the need to distinguish shops based on region, especially in cases where the locale (language) is the same but the target country is different. This allows for proper identification of shops in scenarios like Germany having bothde_DE
(German) and en_US (English) storefronts, where the locale alone is insufficient. - [E2E] Adapted the Search results page E2E tests to account for the updated design, specifically for scenarios with no search results.
- [E2E] Improved stability of guest user registration E2E test by handling Toast message and User popover overlap.
- [E2E] Enhanced the stability of end-to-end tests for PLP Filters and Pagination across all browsers during parallel test runs.
- [E2E] Enhanced the reliability of end-to-end tests covering Search page Filters, ensuring consistent execution across all browsers when running in parallel.
- [E2E] Increased the reliability of logged-in user hydration tests by adding timeout waits to mitigate potential RPC issues.
- [E2E] Improved the hydration error tests by differentiating between guest and logged-in user contexts. Guest user tests now validate empty states for pages like Wishlist and Basket, while logged-in user tests verify pre-populated states. The scope of hydration testing has been expanded to include additional URLs defined in
/playwright/support/pages-hydration-check.json
. Error reporting has also been enhanced to provide more specific arguments and context for improved debugging. - [E2E] Enhanced the stability of end-to-end tests for basket summary price verification with promotion products, specifically for mobile browser execution.
- [E2E] Enhanced the "Verify PDP Multi-size product Store selector" end-to-end test to ensure the store selector flyout closes after store selection.
- [E2E] Adapted existing end-to-end tests to accommodate the recent design changes to the Login and Registration pages.
- [E2E] Enhanced the reliability of the Country Detector end-to-end test in CI environments by addressing Safari-specific performance characteristics.
- [E2E] Updated end-to-end tests for the Account, Wishlist, and Basket features to accommodate the recent changes to login redirection. Tests now verify correct redirection after successful login.
- [OSP] Fixed an edge case within the
SFOspProductCard
component where the OSP would throw an error if a product variant was missing a size attribute. This scenario is rare but could occur under specific circumstances. The issue stemmed from a missing optional chaining operator when accessing the size attribute. This has been corrected by adding the necessary optional chaining operator (?.
) to the size attribute accessor. - [PDP] Product data is now loaded lazily by setting the
lazy
option of totrue
. This change allows for variant preselection during Server-Side Rendering (SSR) and ensures that an appropriate HTTP error status code is returned if product data fetching fails. - [Search] The search result counter is now hidden while loading results.
- [Search] The search functionality now handles whitespace-only search queries more effectively. Instead of performing a search, these queries are now ignored, preventing unnecessary API calls and providing a smoother user experience.
- [SEO] Improved SEO by switching the BreadcrumbList JSON-LD schema-based markup to use absolute URLs. This change ensures search engines can correctly interpret the website's structure.
- [UI] Use color for RGBA manipulation and replacing the redundant
hexToRGBAColor
utility. - [UI] Input labels are now truncated when their text content exceeds the width of the corresponding input field. This prevents labels from overflowing and overlapping other UI elements, maintaining a clean and organized interface.
- [UI] The
SFBasketPopoverItems
component now displays sold-out items, providing users with a clearer view of all items in their basket, regardless of availability. - [UI] After refactoring to use prop destructuring in the
SFProductCardBadgesFooter
component, the default value of theisPromotionBadgeFullWidth
prop was not being applied correctly. This has been fixed, restoring the intended default behavior. - [UI] Implemented a focus trap in the
SFModal
component to maintain responsiveness when aSFSlideIn
is also open. - [UI] The
isGiftSelectionShown
property inSFProductPromotionSelectionModal
is now reset when the component is unmounted, preventing the modal from persisting across page navigation. - [UI] The
SFPriceInput
component now only emits theupdate:model-value
event when the input value actually changes, preventing unnecessary updates. - [UI] Resolved a layout issue with the filter button within the
/pages/c/[...categories]/[...slug]-[id].vue
component. - [UI] Fix sticky behavior of category side navigation in
/pages/c/[...categories]/[...slug]-[id].vue
.
🏡 Dependency Updates
- Added dependency
@scayle/[email protected]
- Added dependency
@scayle/[email protected]
- Added dependency
@scayle/[email protected]
- Added dependency
[email protected]
- Added dependency
[email protected]
- Removed dependency
[email protected]
- Updated dependency
@contentful/[email protected]
to@contentful/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[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
@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
@vueuse/[email protected]
to@vueuse/[email protected]
- Updated dependency
@vueuse/[email protected]
to@vueuse/[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
[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
@eslint/[email protected]
to@eslint/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[email protected]
- Updated dependency
@nuxt/[email protected]
to@nuxt/[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.7.1
💅 Minor Changes
- [Search] Fixed an issue where pressing enter in the search input didn't navigate to the first suggestion. Now, pressing enter will navigate to the first suggestion, or to the search results page if there are no suggestions.
- [E2E] Added an end-to-end test to verify that the product details page loads correctly after a product ID search is performed by pressing Enter. This addresses a previous issue where the product details page might not have loaded correctly in this scenario.
1.7.0
🔥 Highlights
🛒 Basket Enhancements for a Streamlined Shopping Experience
This release delivers a significantly enhanced basket experience, prioritizing user clarity, streamlined functionality, and a smoother checkout process. We've refined the basket's underlying architecture and SEO performance through comprehensive component refactoring and metadata improvements. Key enhancements include clear labeling of sold-out items, prominent badging for promotional offers, a helpful voucher disclaimer, and integrated subscription details directly on relevant items. Transparency is further improved with a detailed breakdown of all discounts in the basket summary.
Visually, the basket boasts a refreshed design, featuring updated empty basket and wishlist states and a redesigned item card. A new confirmation modal prevents accidental deletions, while a convenient basket preview in the top navigation allows for quick access and management. The checkout flow is streamlined with a dedicated final summary section, clearly displaying the final price and a direct checkout link.
Under the hood, we've implemented new utility functions for precise price calculations, along with summaries of applied promotions and regular product prices for increased transparency. Promotional gifts are now automatically added to your basket for a seamless shopping experience.
🧑🦯 Pushing Accessibility
We're committed to making our products accessible to all users. This release delivers key improvements to create a smoother, more inclusive experience.
Navigation is now easier with improvements for keyboard users throughout product listings and other areas. Interactive elements like search inputs and dropdowns are now easier to use.
We've also made information on product pages and account settings clearer and easier to understand through improved structure and organization. These updates demonstrate our continued focus on accessibility and delivering the best possible experience for all our customers.
🏗️ Architectural Improvements
This release features key architectural enhancements focused on dependency management, Nuxt configuration, and component organization within tenant projects.
We've significantly improved the robustness and maintainability of our Google Tag Manager integration by migrating to a locally maintained module, @scayle/nuxt-gtm. This transition leverages the latest advancements in @gtm-support/vue-gtm, resulting in performance gains, bug fixes, and simplified dependency management.
Additionally, our Nuxt configuration now adopts the recommended bundler module resolution, aligning with Vite/Vue best practices and improving third-party library compatibility. This update ensures correct imports for packages with well-defined exports, simplifying development and reducing potential conflicts.
Finally, to better support tenant project development, we've introduced a standardized naming convention for local application components, prefixing them with SF. This enhances code readability and maintainability, while providing a clear distinction between Storefront Boilerplate components and tenant-specific customizations. This separation is essential for streamlined CLI management and update processes, preventing unintended overwrites and ensuring a smooth development experience.
🚀 Major Changes
- [Basket] Refactored the basket summary component to integrate
SFBasketSummaryMobile
intoSFBasketSummary
for centralized logic. - [Basket] Sold-out items in the basket now display an additional title to clearly indicate their unavailability. [Basket] Added structured data and metadata to the basket page for improved SEO performance.
- [Basket] Added a visual badge to basket cards to clearly indicate when a promotional offer is applied to an item.
- [Basket] Added a voucher disclaimer to the basket page.
- [Basket] Introduced a new UI design for empty basket and wishlist states. This includes changes to the reusable
SFEmptyState
component. - [Basket] Added a utility function called
getTotalPriceWithoutReductions
for calculating the total basket price before any reductions are applied. - [Basket] Implemented a new section in the basket view that summarizes applied promotions and their corresponding reductions.
- [Basket] Implemented functionality to add promotional gifts to the basket if they are not already present.
- [Basket] Implemented a new section in the basket view that summarizes the prices of regular products, excluding discounts and promotions.
- [Basket] To streamline the shopping experience, a basket preview has been integrated into the top main navigation. This allows users to easily view and manage the items in their basket without leaving their current page, improving accessibility and convenience.
- [Basket] To provide greater transparency about discounts applied to the basket, a new section has been added to the basket summary. This section clearly displays both campaign-related discounts and sale reductions, allowing customers to easily understand how their final price is calculated.
- [Basket] Introduced a new basket item card design and a confirmation modal for deleting items from the basket, improving user experience and preventing accidental deletions.
- [Basket] To improve transparency and provide users with more information about their subscriptions, subscription details are now displayed on each subscription-relevant basket item.
- [Basket] To improve the user experience towards the checkout, a dedicated final summary section has been added to the basket page. This section clearly displays the final purchase price and provides a direct link to the checkout page, streamlining the checkout process and making it easier for customers to complete their purchase.
- [Basket] The basket page layout has been redesigned for improved clarity and organization. The basket item list generation has also been optimized to enhance performance and loading speed. These changes result in a more user-friendly and efficient basket experience.
- [Basket] Implemented a loading state for the basket page to provide better feedback to users during data fetching. Also added the ability to track
feature
errors usingtrackFeatureError()
. - [Architecture] To address the risks associated with using an unmaintained dependency and improve the long-term stability of our Google Tag Manager integration, we have replaced
@zadigetvoltaire/nuxt-gtm
with a locally maintained module,@scayle/nuxt-gtm
. This new module incorporates the most recent version of@gtm-support/vue-gtm
, benefiting from performance improvements, bug fixes, and ongoing maintenance. This migration also allows us to eliminate a custom patch previously required for compatibility, further simplifying our dependency management. - [Architecture] Updated Nuxt configuration (
nuxt.config.ts
) to utilize the recommendedbundler
module resolution introduced in Nuxt v3.10, removing thefuture.typescriptBundlerResolution: false
flag. This aligns our project with Vite/Vue best practices and improves compatibility with third-party libraries. While this change is generally beneficial, some packages might encounter issues. If you experience any problems, please report them in the affected library's repository. You can temporarily revert this change by addingfuture.typescriptBundlerResolution: false
back to yournuxt.config.ts
file.
This update allows for correct imports of third-party packages with well-defined exports, such as: - [Architecture] As part of ongoing improvements to support the development and maintenance of tenant projects, all local application components (UI and subscription modules) now have the prefix
SF
. This standardized naming convention brings several benefits: improved code readability and maintainability across the codebase, and clear differentiation between Storefront Boilerplate components and custom components developed by tenants. This clear separation is crucial for the CLI, which will be responsible for managing and updating default components in tenant projects, preventing accidental overwrites and conflicts. See the example below for how this affects component imports. - [Accessibility] Removed the unintended shift on hover from the side navigation on product listing pages to improve accessibility.
- [Accessibility] Addressed an accessibility issue where pagination items were not focusable using the Tab key. Replaced
<span>
elements with<SFButton>
components to ensure proper keyboard navigation. - [Accessibility] Enhanced accessibility of subscription selection dropdowns (
SFProductSubscriptionSelection
) by ensuring focusable elements are used. - [Accessibility] RRemoved the focus style from the
input
element within theSearchInput
component to address an issue where an unintended focus state was displayed on click. - [Accessibility] Added
aria-label
and translation toSFSearchInput
button. - [Accessibility] Added the
role="presentation"
attribute to the icon within theSFNavigationTreeItem
component to improve accessibility and conform with WCAG requirements. - [Accessibility] To prevent redundant focusable elements and improve keyboard navigation within the
SFPriceRangeSlider
component, the button element's focusability has been disabled. The slider's dots (provided byVueSlider
) already provide proper focus handling, making the button's focus redundant and potentially confusing for keyboard users. - [Accessibility] Improved the heading structure within the
StoreVariantAvailability
component (used for displaying store variant availability) and account overview page (account/index.vue
) to better reflect the informational hierarchy of the pages. This improves readability and accessibility for users, making it easier to understand the content. This involved adding new headings where necessary and adjusting existing headings to use the appropriate semantic level.
💅 Minor Changes
- [UI] Removed the
new
prefix that was recently added to icon names, reverting to the previous naming convention. In addition, unused icon files have been removed from the project, reducing the overall bundle size and improving performance. This cleanup also simplifies icon management and reduces the risk of naming conflicts. - [UI] Removed the
stop
andprevent
event modifiers from theSFButton
component. These modifiers were complicating the reasoning about the expected behavior of buttons in various contexts, potentially leading to unintended side effects. This change simplifies the component's logic and makes it easier to predict how buttons will interact with other elements on the page. - [Subscription] Introduced the
itemGroup
property to distinguish between standard and subscription product variants within the basket. This allows customers to add both variants of the same product to their basket simultaneously. - [Subscriptions] The quantity selected on the product page is now correctly applied when adding subscription items to the basket. Previously, the quantity might have been reset or ignored.
- [Subscriptions] Subscription items with different definitions are now added as separate items to the basket instead of updating existing items. This aligns the subscription add-to-basket flow more closely with that of regular products.
- [PDP] To prevent potentially misleading price displays on product detail pages (
/pages/p/[...productName]-[id].vue
), subscription items in the basket are now ignored when determining the price to display for the corresponding regular product. Previously, the presence of subscription items with potential extra discounts could lead to inaccurate price displays for regular items. This change ensures that the displayed price accurately reflects the price of the regular product itself. - [ShopSwitcher] Updated the
ShopSwitcher
component to use a Flyout menu instead of a Dropdown, improving accessibility and user experience. - [ShopSwitcher] Introduced
useCurrentShopLocale
anduseCurrentShopTranslators
composables to simplify access to relevant shop localization data for the ShopSwitcher. - [Performance] Addressed a hydration mismatch issue in the wishlist page (
/pages/wishlist.vue
) that was impacting performance. The count badge update is now delayed until hydration is complete, and the content is wrapped within an<SFAsyncDataWrapper>
to ensure proper server/client synchronization. This prevents content flickering and improves the overall loading experience. - [Performance] Resolved a hydration mismatch issue in the
SFQuantityInput
component specifically affecting Firefox. The disabled attribute was sometimes missing from the JavaScript DOM Node object, triggering hydration warnings. To prevent these warnings without impacting functionality, thedata-allow-mismatch="attribute"
attribute has been added. This tells the hydration process to tolerate mismatches on this specific attribute. - [Performance] The product image zoom gallery is now rendered entirely on the client-side, resulting in significantly improved performance and interactivity. Previously, server-side rendering limitations impacted the gallery's responsiveness. This change ensures a smoother and more engaging user experience when viewing product images.
- [E2E] Enhanced end-to-end tests to ensure accurate price calculations in the shopping basket, covering scenarios with regular prices, sales, and promotions.
- [E2E] Implemented end-to-end (E2E) tests to validate client-side hydration against server-rendered content.
- [E2E] Added an end-to-end test to ensure seamless navigation from the main navigation menu to product listing pages. This test covers navigation to main categories and subcategories up to the second level (e.g.,
Women > Clothing > Dresses
). This comprehensive test strengthens our automated testing coverage and helps ensure a smooth browsing experience for our users. - [E2E] Introduced an RPC fixture to streamline end-to-end testing. This fixture allows direct RPC calls from test code, enabling efficient setup of server-side state without requiring UI interaction. This significantly reduces test execution time and complexity.
- [Translations] Removed unused translation entries from the project.
- [Promotions] Refactored the handling of the bottom promotion banner height to improve performance and address several issues. Previously, the entire banner element was stored as a reference, leading to unnecessary layout re-renders and duplicated category API calls within the "Show deals" button triggered overlay due to
KeepAlive
issues. The implementation now uses a newusePromotionBanner
composable to store only the banner's height. This simplifies gap calculations between the floating container and the banner, eliminates redundant re-renders, and resolves the API call duplication. - [Promotions] Improved the performance of promotion loading by reducing the number of calls made to the
getCategoryById
function. This optimization reduces API requests and improves the overall responsiveness of the promotions feature.
Example: - [SEO] To streamline SEO management and reduce code duplication, we've removed our custom SEO utility functions and integrated with the SEO utilities available through the
@scayle/storefront-nuxt
package. This simplifies maintenance and ensures we're using the most up-to-date SEO practices. - [Types] Corrected the import paths for the
BasketItemUpdateData
andPromotionReductionItem
types.
🩹 Patch Changes
- [Images] Improved the construction of image URLs by using URL.parse. This ensures more robust and consistent URL generation when using a CDN, improving image loading performance and reliability.
- [PDP] Implemented title truncation for excessively long titles within the product page breadcrumbs.
- [ShopSwitcher] Updated the
ShopSwitcher
component to display the language code instead of the full language name. - [Account] Corrected the headline translation on the account page.
- [UI] Updated the
SFSlideIn
component to support full-screen display mode on mobile devices. This provides a more immersive experience and better utilizes screen real estate on smaller screens. - [UI] Increased the bottom margin of the "Scroll to Top" button on medium and larger screens (breakpoints
md
and above) to prevent overlap with footer links. - [Navigation] Added support for the
filters
properties onnavigationItem
's that link to category pages. - [Navigation] Ensured horizontal alignment between navigation list items and their corresponding header elements.
- [Navigation] Corrected a layout shift that occurred when hovering over navigation items.
- [Navigation] Refactored navigation lists to use semantically correct
ul
(unordered list) andli
(list item) tags. - [Navigation] Cleaned up and enhanced the
NavigationItem
test data. Thelanguages
field, which was no longer used, has been removed. Additionally, thefilters
property has been added to all category navigation items to facilitate more comprehensive testing of filtering functionality within the navigation. This change simplifies the test data and improves the accuracy of navigation-related tests. - [Tracking] Added tracking for customer logout events to capture the
customer_data
event. This ensures improved tracking of customer sessions and provides valuable insights into user behavior. - [Tracking] Updated search events to include page information attributes and added tracking for "show all results" clicks.
- [Tracking] Corrected the
search_destination
attribute value that is tracked when a user clicks on a suggested page in the search results. - [Tracking] The
method
key in thecustomer_data
tracking object has been renamed tologin_method
for clarity and consistency. - [Tracking] Removed the explicit
cart
event trigger when removing basket items usinguseBasketActions
. This event is already handled automatically by theuseUserItemsTrackingWatcher
. - [Tracking] Corrected an issue where a tracking event was not being triggered when clicking the "Show All" button in search results if other suggestions were present.
- [E2E] Modified the end-to-end test suite to reflect recent updates to the Basket and Wishlist pages, including their empty states and updated page titles.
- [E2E] The
e2e-happy-path.spec.ts
end-to-end test, which covers the critical user journey on the Basket page, has been updated to reflect the recent design changes. This ensures that the core flow towards the checkout remains functional and provides a seamless experience for our customers. - [E2E] As part of the ongoing improvements to our multi-shop platform and the introduction of global API routing for path-based shops, we've updated our E2E test suite. Tests relying on RPC calls have been refactored to reflect the new, simplified API access. This ensures our tests remain comprehensive and effective in validating multi-shop platform functionality, minimizing the risk of regressions and ensuring a seamless experience for our customers across all shops.
- [E2E] Updated the end-to-end tests to cover the redesigned
ShopSelector
functionality. - [E2E] Enhanced the stability of the main navigation end-to-end tests by adding a check for DOM content loading.
- [E2E] Refactored the
ShopSelector
DOM element handling for determining the currently selected country. This simplifies the logic and improves performance. - [E2E] Enhanced the reliability and stability of end-to-end (E2E) tests, particularly those involving user accounts. Each browser now uses a dedicated user account during test execution, preventing data conflicts and ensuring more consistent test results. Additionally, test timeout thresholds have been increased to accommodate potential temporary slowdowns and reduce the occurrence of false positives.
To configure dedicated test user accounts for each browser, set the following environment variables (refer to
env.example
for reference):TEST_USER_EMAIL
TEST_USER_EMAIL2
TEST_USER_EMAIL3
TEST_USER_EMAIL4
TEST_USER_EMAIL5
TEST_USER_PASSWORD
TEST_USER_WRONG_PASSWORD
TEST_USER_NO_ORDERS_PASSWORD
These variables can be set in a.env
file or via CI/CD variables. The mapping between browsers and user accounts is defined in the getUserForBrowser function inplaywright/support/utils
. - [E2E] Extended the basket price summary end-to-end tests to cover mobile browsers. This ensures accurate price calculations and display for sale and promotion products on mobile devices, maintaining consistency across different platforms.
- [E2E] Improved the robustness of the end-to-end test for filter deep links. The test now validates filter functionality irrespective of the order in which filters are returned by the backend. This addresses an issue where variations in filter order could lead to false negative test results, ensuring more consistent and reliable testing.
🏡 Dependency Updates
- Added dependency
@gtm-support/[email protected]
- Added dependency
[email protected]
- Removed dependency
@zadigetvoltaire/[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
@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
@tailwindcss/[email protected]
to@tailwindcss/[email protected]
- Updated dependency
@tailwindcss/[email protected]
to@tailwindcss/[email protected]
- Updated dependency
@vueuse/[email protected]
to@vueuse/[email protected]
- Updated dependency
@vueuse/[email protected]
to@vueuse/[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
[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
@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
@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]
1.6.0
🔥 Highlights
🎨 Introducing the new Header & Footer
Enjoy a refreshed look for SCAYLE Storefront, with greater flexibility at your fingertips! We've revamped both the header and footer design, as well as underlying technical implementation, now leveraging the SCAYLE Navigation as its data source. This change brings enhanced consistency and opens up a new world of customization possibilities through the SCAYLE Panel. The design refresh is aligning the included header and footer with the updated design language introduced in the past months for the Product Listing Page and Product Detail Page. This results in a more cohesive shopping experience across SCAYLE Storefront, and provides a modern foundation and flexible for your design customizations.
🧰 Major update to Storefront SDKs v8
SCAYLE Storefront SDK v8 (@scayle/storefront-nuxt@8.*
) delivers substantial enhancements to data handling, consistency, and overall developer experience.
This release introduces a revamped response structure and error handling for basket data, along with streamlined return values for RPC composables for increased predictability.
As part of our commitment to modernization, we have removed legacy code and deprecated features, including the disableDefaultGetCachedDataOverride
setting and support for outdated approaches like faceted search (useFacet
).
A comprehensive migration guide is available to ensure a smooth transition to this enhanced version, offering improved performance, stability, and a future-proof foundation for your storefront integrations.
🏗️ Starting transition to Storefront Feature Packages
We're increasing the flexibility and scalability of SCAYLE Storefront by transitioning to a new feature package architecture.
This means breaking down core features into independent, manageable packages, giving tenants more control over upgrades and customization.
Going forward, you can choose to adopt updates to specific functionalities without requiring a complete overhaul of your application.
We've already begun this transition by migrating key Product Listing functionalities into the @scayle/storefront-product-listing
package.
Additionally, our newly developed "Country Detection" feature is now available as the @scayle/storefront-country-detection
package, offering immediate access to this powerful functionality.
This is just the first step towards our new architecture, and we'll be supplementing this approach with additional tooling and documentation in the future.
🚀 Major Changes
- [Header & Footer ] We've updated the design of the page header. It now uses the SCAYLE Navigation as its data source.
- [Header & Footer ] We've updated the design of the page footer. It now uses the SCAYLE Navigation as its data source.
- [Header & Footer] We're introducing a new simplified header and footer design, which will be now used by default for the checkout page.
- [Storefront v8] We've revamped the response structure and error handling for basket data. Expect a more organized and consistent data format.
- [Storefront v8] Removed
disableDefaultGetCachedDataOverride
setting as this behavior is now the default. - [Storefront v8] We're aligning the return values of RPC composables by replacing
pending
withstatus
andfetch
withrefresh
. - [Storefront Feature Packages] Replace the composable
useProductListFilter
withuseFiltersForListing
as has been renamed in@scayle/storefront-product-listing
. We've also removed the return valueclearedPriceQuery
. Please use the utility functiongetClearedFilterQueryByKey
. - [Storefront Feature Package] Replace the composable
useProductsByCategory
withuseProductsForListing
from@scayle/storefront-product-listing
.- Previous implementation:
- Current implementation:
- Previous implementation:
- [Storefront Feature Packages] Replace the composable
useCategorySeoData
withuseProductListingSeoData
from@scayle/storefront-product-listing
.- Previous implementation:
- Current implementation:
- Previous implementation:
💅 Minor Changes
- [Search] Rename the search query parameter
term
tofilters[term]
to adhere to the established filter naming convention. This alignment ensures that search results only display filters matching the available products. To maintain existing functionality, all instances of accessingroute.query.term
need to be updated toroute.query.['filters[term]']
.- Example:
- This was done in:
composables/useFilter.ts
composables/useProductsSearch.ts
composables/useRouteHelpers.ts
pages/search.vue
- Example:
- [Search] Use new filter query parameter name (
filters[term]
) for search term when updating current route. - [UI] The component prop type in the
Button.vue
andLink.vue
components has been renamed to variant. This change prevents conflicts with the native HTML type attribute, enhancing code maintainability and reducing the risk of unexpected behavior. - [UI] Refactor
<Listbox />
to manage theisOpen
state without the use ofuseState
. Instead of passing a name to<ListboxButton />
and<ListboxOption />
, they now require a function to toggle the open state.- Example:
- Affected files:
components/layout/headers/ShopSwitcher.vue
- Example:
- [Accessibility] Improved keyboard navigation for better accessibility.
Users can now navigate directly to a PDP from a focused
ProductCard.vue
by simply pressing theEnter
key. - [Accessibility] The
SFSwitch
component now provides improved touch interaction. The<label>
is now associated with the switch control using the appropriateid
andfor
attributes. This allows users to easily toggle the switch by simply tapping on the label, making it significantly easier to interact with on touch devices. - [Dependencies] We've updated to
nuxt/[email protected]
. This introduces a new directory structure for localization to align with the upcoming changes of Nuxt 4.lang/
directory has been renamed toi18n/
i18n.config.ts
has been moved toi18n/i18n.config.ts
lang/{locale}.json
translation files have been moved toi18n/locales/{locale}.json
- Removed preconfigured
i18n.langDir
option innuxt.config.ts
to use new default directory structure - Additional details can be found in the official
nuxt/i18n
v8 to v9 migration guide
- [Middleware] We've refactored the
redirectTrailingSlash.global.ts
middleware to use aslice()
-based approach instead of a RegEx-based approach for normalizing the URL path and added some test cases to verify its intended functionality, including some performance comparison tests with the former implementation. - [Performance] To avoid hydration mismatches,
<AccordionEntry>
no longer generates id's used for accessibility features on its own. It now requires the id being passed from the the parent component. - [Tooling] We've introduced
@nuxt/fonts
to streamline web font integration. This change simplifies the process of adding and managing fonts in Storefront projects while improving performance:- Zero-config setup for popular font providers (Google Fonts, etc.)
- Customization options with support for custom providers
- Seamless Tailwind CSS Integration: Easily incorporate downloaded fonts into your Tailwind configuration for streamlined styling
- Enhanced Privacy and Performance through Local Font Downloads: Fonts are downloaded and served from your server, addressing privacy concerns related to third-party font hosting (like Google Fonts and GDPR compliance) while improving your website's loading speed
- Performance benefits:
- [Shop Switcher] Shop switching now defaults to redirecting users to the homepage of the newly selected shop. For cases where maintaining the current path is desired, the
<ShopSwitcher />
component now accepts aswitchToHomePage
prop. Setting this prop tofalse
will preserve the current path during the shop switch. - [Product] Cleanup and simplify product include handling. All relevant includes are now defined in
constants/withParams.ts
and there are only two product includes defined now:PRODUCT_DETAIL_WITH_PARAMS
which includes all attributes and advanced attributes to be used on the PDP and BasketPRODUCT_TILE_WITH_PARAMS
a smaller subset of data to be used for theProductCard
component (e.g. on the Product Listing Page, in the Search or for the Wishlist)
- [Wishlist] We overhauled the wishlist implementation and design align with the new design language of the Storefront Boilerplate
- Removes unnecessary tracking from other pages
- Improves grid handling for the Wishlist
- Updates loading view of the Wishlist
- Updates the Wishlist Header to be aligned with the Product Listing Page
- [Runtime] Upgrade Dockerfiles to Node 22 which is now the official LTS Version for Node.
- [E2E] Implemented end-to-end tests to ensure the accuracy and functionality of the Store Locator feature.
- [E2E] Implemented end-to-end tests to ensure accurate and reliable sorting functionality within Product Listing Pages (PLP)
- [E2E] Ensured Search page filters work correctly by adding end-to-end tests to verify the functionality of the filters on the Search page.
- [E2E] Refined tests to guarantee the reliability and correctness of pagination on Product Listing pages.
- [E2E] Implemented end-to-end testing for search suggestion tags and integrated tag-based filtering into the search results page.
- [E2E] Implemented an end-to-end test to verify the functionality of the shop selector, ensuring users can seamlessly switch between different shops within the platform.
🩹 Patch Changes
- [Header & Footer] Standardized footer logo dimensions by setting a fixed width (
w-7
/28px
) to improve usability and prevent accidental clicks. - [Header & Footer] Adjusted footer spacing on mobile for a more visually appealing and consistent browsing experience.
- [Header & Footer] Addressed an unexpected UI behavior in the
FooterLinkSection
component where theexpanded
state persisted after navigation. This fix ensures the mobile footer menu reliably collapses when navigating to a different page. - [Search] Enhanced the search result page user experience for users on low-bandwidth or slow connections. Instead of immediately displaying "0 hits" while results load, the page title now dynamically indicates loading progress, providing a clearer indication of ongoing search activity.
- [PDP] Adjusted layout to prevent the best price from displaying on the same line as the current price, improving price clarity for users.
- [PDP] Improved the visual presentation of tax information next to product prices.
Tax details are now displayed as superscript using the
<sup>
tag for consistent alignment and improved readability. - [PLP] Adjusted spacing of
ProductCardDetails
andProductPrice
withinProductCardDetails
for both mobile and desktop view. - [PLP] Fixed overlapping sales badges on top of product name within
ProductCardDetails
by adjustingProductPrice
positioning for mobile view. - [PLP] Adjusted top padding for content containers when teaser images are absent. This ensures optimal spacing between the breadcrumb navigation and the top of the page, enhancing visual clarity and user experience.
- [PLP] This change addresses an issue where the price filter would incorrectly persist when the
SFPriceRangeSlider
was returned to its original minimum and maximum values. Now, an event is emitted based on whether the provided event values match these filter limits (resetPriceFilter
orapplyPriceFilter
). This ensures that the filter is properly reset in all cases, even when the slider is moved back to its initial position. Previously, this scenario would result in the filter remaining active (applied), as potentially indicated by the filter counter on theFilterToggleButton
. - [Promotions] Only add alpha value to promotion color when alpha value was passed to
getBackgroundColorStyle()
andgetTextColorStyle()
. - [Promotions] Show
<VariantPicker>
for products with only one variant withinProductPromotionSelectionModal.vue
and remove unusedONE_SIZE_KEY
constant. - [Basket] Addressed a hydration mismatch issue in the
ProductCardBadgesFooter.vue
component that occurred when a product was already present in the user's basket. - [Basket] Removed the redundant flag
isLowestPreviousPriceActive
. Price display logic now relies on the SCAYLE Core System, ensuring consistency and accuracy across all supported countries. This change simplifies our codebase and removes the need for country-specific configurations related to lowest price display. - [Accessibility] The
primary
variant ofSFButton
now has its outline restored to improve its visibility for impaired users. - [Utilities] Moved
useDefaultBreakpoints
to the UI module. - [Utilities]
getBackgroundColorStyle()
andgetTextColorStyle()
now set alpha values when using the default color. Previously no alpha value was set, resulting in the same color for text and background of promotion prices. - [Performance] Local history checks inside
GoBackLink.vue
now occur after hydration to prevent potential issues. - [Tooling] Added all Tailwind CSS duration classes to the safe list, ensuring complete availability.
This addresses an issue where durations defined with the
duration-{duration}
syntax were unintentionally purged. Also consistency is improved by updating transition components to exclusively accept duration values defined within the Tailwind configuration. - [Tooling] Added a check for the existence of the
country_selection.override_codes.<...>
translation key before resolving its translation. This prevents console warnings that were previously triggered when attempting to resolve nonexistent translation keys. - [Tooling] Added
resolutions
for[email protected]
inpackage.json
to resolve issues with executingeslint
. - [UI] Remove hardcoded ID from
ListBox
to avoid conflicts. - [UI] Fixed links not opening in a new tab when they should.
- [UX] Show a
404
error on the PDP when the product cannot be found. - [UI] Fix button variant of
ShopSwitcherItem.vue
after the option was renamed inButton.vue
. - [UX] Resolved an issue with the ShopSwitcher where clicking the currently selected locale would unnecessarily reload the page.
- [E2E] Optimized end-to-end test suite for user login flow to prevent potential timeouts during authentication.
- [E2E] The footer end-to-end test was enhanced to verify correct homepage redirection and scroll-to-top functionality upon clicking the footer logo.
- [E2E] Updated end-to-end test for shop switching to enforce redirection to the Homepage after a user switches shops, ensuring alignment with the latest product requirements. Previously, tests allowed for redirects to non-Homepage destinations, which is no longer desired behavior.
- [E2E] Implemented end-to-end test for PLP filter functionality, ensuring product counter synchronization.
- [E2E] Updated end-to-end tests to reflect Header and Footer modifications.
- [E2E] Updated Footer Storefront guide URL constant value to match the updated page URL.
- [E2E] The "Verify Shop Selector switch from non-Homepage" end-to-end test
(e2e-ShopSelector.spec.ts
) is experiencing timeouts specifically on Mobile Safari during CI execution. This test is temporarily skipped for Mobile Safari to maintain a green CI pipeline. Investigation into the root cause of the timeouts is ongoing. - [E2E] Ensured the accuracy of end-to-end tests for the new footer following recent updates.
- [E2E] Enhanced end-to-end tests for homepage links to ensure more robust validation.
The tests now perform a more accurate check of response codes and status.
Additionally, if the initial header request (
page.request.head()
) fails, a full page visit is attempted to provide more comprehensive error detection. - [E2E] Updated tests to match the rename of the search query parameter
term
tofilters[term]
to adhere to the established filter naming convention. This alignment ensures that search results only display filters matching the available products. - [E2E] Refined end-to-end test to check the PLP applied Filters counter.
- [E2E] Updated the end-to-end test for the "Happy Path" user journey to reflect recent changes made to the Header Search component. This ensures continued, comprehensive testing of core search functionality after implementation updates.
- [E2E] Improved the stability and consistency of tests for the Basket and Shop Selector features specifically targeting mobile Safari browser.
🏡 Dependency Updates
- Added dependency
@nuxt/[email protected]
- Added dependency
@scayle/[email protected]
- Added dependency
@scayle/[email protected]
- Added dependency
@scayle/[email protected]
- Added dependency
[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
@vueuse/[email protected]
to@vueuse/[email protected]
- Updated dependency
@vueuse/[email protected]
to@vueuse/[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
[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
@eslint/[email protected]
to@eslint/[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
@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]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
- Updated dependency
[email protected]
to[email protected]
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. Our goal is to achieve full accessibility by 2025, making a Storefront-based shop a welcoming space for everyone.
🧪 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.
⚓ 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. - [UI] The ShopSelector component has been redesigned with an updated look and feel for a more intuitive and user-friendly experience.
- [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. - [UI] Streamlined minor part of the header to align with the new PLP and PDP.
- [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.
- Improved the accessibility and testability of Min and Max price input fields by adding 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 accessibility 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
- Remove boolean props on
Modal.vue
to control styling. Instead styling is done by adding styles to the<SFModal>
and its content. - Add skeleton loader for the product detail page.
- Added PDP E2E tests, first phase.
- Disable auto-imports for Vue components
- Simplify 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.
- Replace
InputToggle
withSwitch
component - Enhance product card component by removing slots, simplifying the HTML structure and removing unnecessary slots.
🩹 Patch Changes
- Fix placement of price within the
ProductCardDetails.vue
- Product color is now mapped by attribute value instead of ID
- Handle possibly undefined
orderData
when calculatingdeliveryDate
on Order Success page - Removes unused
useWishlistItem
anduseWishlistItemActions
from the project - Fixed an issue on CMS content pages with empty teaser image leading to unnecessary white space
- Replace 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:
(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: - [Utility Replacement] Replaced
radash.dash
with native string operations - [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: - [Utility Replacement] Replaced
radash.sum
with native calculations and array operations: - [Utility Replacement] Utility Replacement: Replaced
radash.min
with native array operations: - [Utility Replacement] Replaced
radash.snake
with custom native string operations: - [Utility Replacement] Replaced
radash.pick
with native array operations: - [Utility Replacement] Replaced
radash.group
with native array operations: - [Utility Replacement] Replaced
radash.capitalize
with native string operations: - [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:
- After:
- 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 overridden 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
web component
🏡 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]