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 neededappKeys
added - will override the globalappKeys
option for the shop if setsapi
now optional - will override the globalsapi
option for the shop if setredis
now optional - will override the globalappKeys
option for the shop if setapiBasePath
removedcache
removed - This shop-level cache configuration was never used.$sessionConfig
renamed tosessionConfig
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 thefetch
function returned byuseRpc
. The params are typed asMaybeRefOrGetter<ParamsForMethod>
which resolves toParamsForMethod | () => 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 whenrefresh
is called, you can pass a function that returns the parameters. When you pass the parameters wrapped in aRef
, a watcher will be added that executesrefresh
when the parameters change. The watcher can be disabled by overriding theAsyncDataOptions
. - Instead of
fetching
,status
is used to track the loading state - Instead of
fetch
, userefresh
orexecute
to reload the data fetching
andfetch
are made available as copies ofstatus.value === 'pending'
andrefresh
for compatibility- By default,
useAsyncData
executes the function automatically, without having to callrefresh
.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 usestatus
anderror
to check for errors. - Note:
pending
is initially set totrue
even whenrefresh
has not been executed yet. After the first execution it's onlytrue
whilerefresh
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 topending
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 nowuseUser
useBasketWithParams
is nowuseBasket
useWishlistWithParams
is nowuseWishlist
(See also: Configuration - With Parameters)
Removed composables
sharedRef
has been removed - Use useState instead.useUserFacet
has been removed - UseuseUser
,useWishlist
anduseBasket
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