docs
  1. SCAYLE Resource Center
  2. Developer Guide
  3. Migrations
  4. Nuxt 3
  5. Storefront Core changes

Storefront Core changes

Introduction

@scayle/storefront-nuxt is a new package for building storefront applications using Nuxt 3. It is based on @scayle/storefront-nuxt2, but because there are many differences between Nuxt 2 and Nuxt 3, there are consequently many differences between @scayle/storefront-nuxt and @scayle/storefront-nuxt2.

This document provides an overview of how @scayle/storefront-nuxt differs from @scayle/storefront-nuxt2. For a full guide on how to migrate your storefront application to Nuxt 3, see Storefront Boilerplate (DemoShop) migration guide.

Configuration changes

session

The session config is mostly the same. secret is now typed as string | string[] instead of string to enable changing the secret key used for signed session cookies without breaking existing sessions.

There is also a new provider option to control session store used. It can be set to 'redis' (default) or 'memory'.

See Sessions for more details.

cache

SSR-specific options are moved under cache.ssr. For example, instead of using cache.pathsDisabled to disable certain paths for SSR, use cache.ssr.pathsDisabled to disable certain paths for SSR, use cache.ssr.pathsDisabled.

redis

The Redis configuration can now be defined at the top-level. The top-level configuration will apply for all shops that don't specify their own redis configuration.

sapi (Storefront API)

The sapi (Storefront API) configuration option can be defined at the top-level now. The top-level configuration will apply for all shops that don't specify their own sapi configuration.

The only options on the sapi config are now host and token. Specifying username and password and using Basic authentication is no longer supported.

Please note that the term sapi is deprecated and only used to ensure compatibility. It will be updated in a later version.

oauth

A new top-level option has been added for oauth configuration. See Checkout login for more details.

log

A new top-level config option has been added for controlling the log behaviour. See Logging for more details.

auth

The top-level auth configuration is no longer available as this is now a store-specific configuration only.

apiBaseUrl

The apiBaseUrl configuration is no longer available, but will be reintroduced in a future update.

sessionCookieDomain

The sessionCookieDomain option has been removed. This is a leftover option that was never used in @scayle/storefront-nuxt2 either. The best way to configure the domain of a session cookie is through the session.domain option.

rpcMethods, rpcDir and rpcMethodNames

RPC methods are no longer passed directly to the storefront module config. Instead, rpcDir and rpcMethodNames must be configured to load custom RPC methods. See RPC Methods for more information.

shopSelector

'custom' is no longer supported as a shop selector method and getCurrentShop has been removed. See Shop Selector for more details.

stores/fetchStores

Fetching shop configurations on demand is not supported in @scayle/storefront-nuxt at this time. Shop configurations must be provided through the shops option and fetchStores has been removed. See Example Shop Config.

withParameters

Storefront config now supports withParams option so that we can pass the with parameters through the shop and set them as default parameters within certain composables (e.g useWishlist). Furthermore, as a third default, the min with (e.g MIN_WITH_PARAMS_BASKET) parameters constant is set for the composables where it's needed.

const defaultWithParams = useNuxtApp().$config.$storefront.withParams.wishlist
const withParams =
  toValue(params) || defaultWithParams || MIN_WITH_PARAMS_WISHLIST

Shop Config

Shop configurations must be specified as a ShopConfigIndexed object on the shops option, using a unique identifier like the shopId or the shops locale. The ShopConfig definition has also changed in @scayle/storefront-nuxt.

  • paymentProviders removed - use additional shop data if needed
  • appKeys added - will override the global appKeys option for the shop if set
  • sapi now optional - will override the global sapi option for the shop if set
  • redis now optional - will override the global appKeys option for the shop if set
  • apiBasePath removed
  • cache removed - This shop-level cache configuration was never used.
  • $sessionConfig renamed to sessionConfig

Example Shop Config

  shops: {
    '1234': {
        shopId: '1234',
        path: 'us',
        locale: 'en_US',
        currency: 'USD',
        paymentProviders: [
            'lastschrift',
            'visa',
            'mastercard',
            'ratepay',
            'klarna',
            'paypal',
        ],
        currencyFractionDigits: 2,
        storeCampaignKeyword: 'TEST'
        appKeys: {
            wishlistKey: 'wishlist_{shopId}_{userId}',
            basketKey: 'basket_{shopId}_{userId}',
            hashAlgorithm: HashAlgorithm.SHA256,
        },
        auth: {
            resetPasswordUrl: '',
        },
        checkout: {
            shopId: '1234',
            token: 'token',
            secret: 'secret',
            host: 'host',
            user: 'user',
        },
    }
  }

shop.checkout

In @scayle/storefront-nuxt shopId and oauthHost have been removed from the shop checkout config.

Extending the ShopConfig with additional properties

It's possible to add extra metadata to each shop configuration. How that data has to be typed has changed in @scayle/storefront-nuxt. In @scayle/storefront-nuxt2, ModuleOptions accepted a generic parameter CustomStoreConfig which defined the additional properties. In @scayle/storefront-nuxt the public interface AdditionalShopConfig should be extended with the additional properties.

declare module '@scayle/storefront-nuxt' {
  export interface AdditionalShopConfig {
    paymentProviders: string[]
  }
}

PublicShopData

In @scayle/storefront-nuxt, the list of built-in configuration options that are considered public is the same as in @scayle/storefront-nuxt2, minus the options that have been removed in @scayle/storefront-nuxt.

The top-level publicShopData option controls which additional shop properties are considered 'public' and can be delivered to the client.

RPC Methods

useRpc

The behavior of useRpc has changed for Nuxt 3 since the new implementation is built on useAsyncData

  • RPC params are passed to useRpc instead of the fetch function returned by useRpc. The params are typed as MaybeRefOrGetter<ParamsForMethod> which resolves to ParamsForMethod | () => ParamsForMethod | Ref<ParamsForMethod>. If the parameters are static and won't change you can use the first option. If you want the parameters to be resolved when refresh is called, you can pass a function that returns the parameters. When you pass the parameters wrapped in a Ref, a watcher will be added that executes refresh when the parameters change. The watcher can be disabled by overriding the AsyncDataOptions.
  • Instead of fetching, status is used to track the loading state
  • Instead of fetch, use refresh or execute to reload the data
  • fetching and fetch are made available as copies of status.value === 'pending' and refresh for compatibility
  • By default, useAsyncData executes the function automatically, without having to call refresh. useRpc disables this so it behaves more similar to the Nuxt2 version
  • When refresh is executed and an error occurs, no exception will be thrown. Instead use status and error to check for errors.
  • Note: pending is initially set to true even when refresh has not been executed yet. After the first execution it's only true while refresh is running.

Nuxt 2

function useRpc(
  method: RpcMethodName | ValueOf<RpcMethods>,
  key: string,
): {
  data: Ref<TResult | null>
  fetching: Ref<boolean>
  fetch: (params: TParams) => Promise<void>
} {}

Nuxt 3

function useRpc(
  method: RpcMethodName,
  key: string,
  params?: TParams,
  options?: AsyncDataOptions,
): {
  data: Ref<TResult | null>
  pending: Ref<boolean>
  refresh: (opts?: AsyncDataExecuteOptions) => Promise<void>
  execute: (opts?: AsyncDataExecuteOptions) => Promise<void>
  error: Ref<ErrorT | null>
  status: Ref<AsyncDataRequestStatus>
} {}

Cache

@scayle/storefront-nuxt adds a new cache.provider option which allows selecting various cache providers. The default value is "redis", which creates a Redis-backed cached, but it can also be set to "unstorage" which creates an in-memory unstorage cache.

Same as in @scayle/storefront-nuxt2, the AY_CACHE_DISABLED env var can be used to disable the cache. However, support for this env var will be removed in an upcoming release.

Redirects

The redirects module is configured through module options rather than environment variables. Instead of setting REDIRECTS_ENABLED and REDIRECTS_PARAM_WHITELIST, use @scayle/storefront.redirects.enabled and @scayle/storefront.redirects.queryParamWhitelist.

Logging

In @scayle/storefront-nuxt2, the storefront is responsible for creating the Log object and injecting it into the core. In @scayle/storefront-nuxt the Log is created in the core, but can be configured through module options.

Basic Auth

Basic auth is not supported as part of @scayle/storefront-nuxt (Nuxt 3). If basic auth is required, it should be configured on web server level (.e.g. within Nginx).

Checkout Login

In @scayle/storefront-nuxt, the only supported checkout authentication method is token-based authentication.

The OAuth configuration is configured through module options rather than env variables. Instead of setting OAUTH_API_HOST, OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET, use @scayle/storefront.oauth.host, @scayle/storefront.oauth.clientId and @scayle/storefront.oauth.clientSecret.

const config = {
  // ...
  oauth: {
    host: process.env.OAUTH_API_HOST,
    clientId: process.env.OAUTH_CLIENT_ID,
    clientSecret: process.env.OAUTH_CLIENT_SECRET,
  },
}

Sessions

In @scayle/storefront-nuxt2, the sessions handling is built on top of express-session. However, Nuxt 3 uses h3 instead of express so this library is no longer an option. Instead, we use @scayle/h3-session which is a port of express-session for h3. The options for configuring sessions remain the same. As the session storage and cookie format also remains the same, sessions should be preserved when migrating from Nuxt 2 to Nuxt 3.

The session persistence uses unstorage (and ioredis indirectly) instead of node-redis, but this is not expected to cause any issues. There is an additional session.provider option in @scayle/storefront-nuxt which allows switching between the default Redis store and an in-memory store (for testing).

session.secret can now be a string or string[]. This matches the option in express-session/@scayle/h3-session and allows changing the cookie-signing secret without invalidating existing cookies.

ShopSelector

In the Nuxt 3 module, the only options available for @scayle/storefront.shopSelector are 'path' and 'domain'. 'custom' has been removed because we are not able to execute a function that has been provided through the module options.

Path selection also works slightly differently. Instead of using the locale of shop as the path prefix, there is now a path property on the shop config that is used instead.

In API requests, the header x-shop-id is used. In the Nuxt 2 package, x-shop-locale was used.

What does this mean for Storefronts?

  • If you are using domain shop-selection, no changes should be necessary.
  • If you are using path shop-selection, make sure you configure each shop in your config with a path property.
  • If you are using custom shop-selection, switch to path or domain selection.

Injected values

In Nuxt 2, currentShop and availableShops are injected in the Nuxt context. In Nuxt 3, they are still injected but also can be accessed via composables.

Nuxt 2

const { $currentShop, $availableShops } = useContext()

Nuxt 3

const currentShop = useCurrentShop()
const availableShops = useAvailableShops()
// or
const { $currentShop, $availableShops } = useNuxtApp()

Composables

The list provides composables with breaking changes:

useSearch

  • fetching has been renamed to pending
  • searchIsActive has been removed. This value was not used.
  • goToSearchResultAndResetState has been removed. Routing should be handled in the app.

useSession

useSession now uses rpcCall instead of useRpc. The only exported members are the RPC functions. If you need a ref for the loading status, create one manually.

useUser

refresh is renamed to forceRefresh

Nuxt 2

const { isLoggingIn, loginData, login } = useSession()
login({ username, password })

Nuxt 3

const { login } = useSession()
const isLoggingIn = ref(true)
const loginData = await login({ username, password })
isLoggingIn.value = false

useNavigationTrees

The composable has been split into useNavigationTrees for fetching all navigation trees and useNavigationTree to fetch a specific tree by ID.

Renamed composables

  • useUserWithParams is now useUser
  • useBasketWithParams is now useBasket
  • useWishlistWithParams is now useWishlist

(See also: Configuration - With Parameters)

Removed composables

  • sharedRef has been removed - Use useState instead.
  • useUserFacet has been removed - Use useUser, useWishlist and useBasket instead

Helper functions

In Nuxt 2 we provided various helper functions within the $helper object of the context. Those helper functions are placed within the utils folder. This allows them to be auto imported, meaning they are globally available without any prefix.

In Nuxt2

const { $helpers } = useContext()
$helper.route.getCurrentPage(...)
<template>
  <div>{{ $helper.route.getCurrentPage(...) }}</div>
</template>

In Nuxt 3

getCurrentPage(...)
<template>
  <div>{{ getCurrentPage(...) }}</div>
</template>

Auto-imported helpers

The following helpers have been migrated to @scayle/storefront-nuxt. They are added to auto-import config in Nuxt 3 and do not have to be explicitly imported.

Route helpers

  • getCurrentPage

Price helpers

  • toCurrency
  • formatPrice