Upgrade to 17.0.0
Why you should upgrade
This upgrade includes a new market selector panel and product review component.
See release notes for more information
Pre-requisites
Before upgrading to 17, make sure you have already upgraded to 16. See guide here
Steps
Update .env
- Update your
.env
file. Here is an outline of what variables your local .env-file should contain.
Note that FALLBACK_MARKET_ALIAS
is used instead of FALLBACK_MARKET_ID
:
// Always needed
IMAGE_SERVER= *** (URL)
API_KEY= *** (STRING)
API_ENDPOINT= *** (URL)
AUTH_ENDPOINT= *** (URL)
SIGN_ENDPOINT= *** (URL)
BASE_URL= *** (URL including http)
FALLBACK_CHANNEL_ID= *** (STRING in format "number|countryCode", e.g. "1|se")
FALLBACK_MARKET_ALIAS= *** (STRING in format "countryCode", e.g. "se")
DEFAULT_LOCALE= *** (STRING in format "langCode", e.g. "sv")
APPINSIGHTS_INSTRUMENTATION_KEY= *** (STRING)
// Only needed when using "diffrentDomains", with one tld per language or
// add only one domain here to leave market and language out of path
DOMAINS= *** (STRING in format "langCode|urlWithoutHttp,langCode|urlWithoutHttp", e.g. "sv|www.site.se,fi|www.site.fi")
// Only needed when you want to use GTM
GTM_ID= *** (STRING)
// Only needed to use Nosto integration
NOST_API_APPS_KEY= *** (STRING)
NOSTO_ACCOUNT_ID= *** (STRING)
Update Dockerfile
- Update
Dockerfile
to useDOMAINS
andFALLBACK_MARKET_ALIAS
. Remove previous usedDOMAIN
variables:
...
// Remove this, no longer needed
ARG DOMAIN_SV=#{DomainSv}#
ARG DOMAIN_EN=#{DomainEn}#
// Add this
ARG FALLBACK_MARKET_ALIAS=#{FallbackMarketAlias}#
ARG DOMAINS=#{Domains}#
...
// Remove this, no longer needed
ARG DOMAIN_SV
ARG DOMAIN_EN
// Add this
ARG FALLBACK_MARKET_ALIAS
ARG DOMAINS
...
// Remove this, no longer needed
ENV DOMAIN_SV=${DOMAIN_SV}
ENV DOMAIN_EN=${DOMAIN_EN}
// Add this
ENV FALLBACK_MARKET_ALIAS=${FALLBACK_MARKET_ALIAS}
ENV DOMAINS=${DOMAINS}
...
Update nuxt.config.js
- Replace the
fallbackMarketId
withfallbackMarketAlias
:
replace:
nuxt.config.jsconst fallbackMarketId = process.env.FALLBACK_MARKET_ID;
with:
nuxt.config.jsconst fallbackMarketAlias = process.env.FALLBACK_MARKET_ALIAS;
- Add domain settings like this:
// Set the domain settings and market settings based on if env-variable DOMAINS exists
// Default settings for multi market / multi language
let domainSettings = {
differentDomains: false,
strategy: "prefix",
};
let domainUrls = null;
// Default settings for market for publicRuntimeConfig
let marketSettings = {
isMultiLanguage: true,
marketInPath: true,
};
if (process.env.DOMAINS) {
const domains = process.env.DOMAINS.split(",");
domainUrls = domains
?.map((domain) => {
const domainArr = domain?.split("|");
return {
[domainArr[0]]: domainArr[1] || "",
};
})
.reduce((result, item) => {
const key = Object.keys(item)[0];
result[key] = item[key];
return result;
}, {});
// If using DOMAINS, turn off multilang and marketInPath
marketSettings = {
isMultiLanguage: false,
marketInPath: false,
};
// If site should have only language prefix and no market prefix, remove the following declaration
domainSettings = {
differentDomains: false,
strategy: "no_prefix",
};
if (domains.length > 1) {
// If more than one domain, set diffrentDomains to true
domainSettings = {
differentDomains: true,
};
}
}
- Add the
fallbackMarketAlias
to thelistPageInfo
query:
...
query listPageInfo {
listPageInfo(
alias: "frontpage",
channelId: "${fallbackChannelId}",
marketId: "${fallbackMarketAlias}"
) {
meta {
description
title
}
}
}
...
- Add
getMarketsQuery
and fetch markets in the export default function:
export default async () => {
...
// Get fallback markets
const getMarketsQuery = await apolloClient.query({
query: gql`
query channel {
channel(channelId: "${fallbackChannelId}") {
defaultMarketId
markets {
id
defaultLanguageId
alias
virtual
onlyDisplayInCheckout
groupKey
allowedLanguages {
id
name
code
}
country {
name
code
}
currency {
name
code
}
}
}
}
`,
context: {
headers: {
"X-ApiKey": process.env.API_KEY,
},
},
});
const markets = await getMarketsQuery.data.channel.markets;
...
}
In the
@nuxtjs/i18n
module:- Remove the
strategy
and thedifferentDomains
properties, and add thedomainSettings
instead. - In the
locales
array, remove theflag
andcurrency
properties from each object. - Add the
domain
property to each object. - Update the objects in the
pages
object.
Should look something like this:
- Remove the
modules: [
// Doc: https://github.com/nuxt-community/pwa-module
'@nuxtjs/pwa',
[
// Doc: https://github.com/nuxt-community/i18n-module
'@nuxtjs/i18n',
{
baseUrl: process.env.BASE_URL,
seo: false,
locales: [
{
code: 'en',
iso: 'en-US',
file: 'en-US.js',
name: 'English',
domain: domainUrls?.en || '' // Only matters if diffrentDomains are used
},
{
code: 'sv',
iso: 'sv-SE',
file: 'sv-SE.js',
name: 'Swedish',
domain: domainUrls?.sv || '' // Only matters if diffrentDomains are used
},
{
code: 'nb',
iso: 'nb-NO',
file: 'nb-NO.js',
name: 'Norsk',
domain: domainUrls?.nb || '' // Only matters if diffrentDomains are used
},
{
code: 'nn',
iso: 'nn-NO',
file: 'nb-NO.js',
name: 'Norsk',
domain: domainUrls?.nn || '' // Only matters if diffrentDomains are used
},
{
code: 'da',
iso: 'da-DK',
file: 'da-DK.js',
name: 'Dansk',
domain: domainUrls?.da || '' // Only matters if diffrentDomains are used
},
{
code: 'fi',
iso: 'fi-FI',
file: 'fi-FI.js',
name: 'Finska',
domain: domainUrls?.fi || '' // Only matters if diffrentDomains are used
}
],
langDir: 'languages/',
defaultLocale: process.env.DEFAULT_LOCALE,
lazy: true,
vueI18n: {
fallbackLocale: process.env.DEFAULT_LOCALE
},
detectBrowserLanguage: false,
parsePages: false,
pages: {
'checkout/index': {
sv: '/kassan',
en: '/checkout',
da: '/kassen',
fi: '/kassa',
nb: '/kassen'
},
'account/orders': {
sv: '/mina-sidor/ordrar',
en: '/my-account/orders',
da: '/min-konto/bestillinger',
fi: '/tilini/tilaukset',
nb: '/min-konto/bestillinger'
},
'account/settings': {
sv: '/mina-sidor/installningar',
en: '/my-account/settings',
da: '/min-konto/indstillinger',
fi: '/tilini/asetukset',
nb: '/min-konto/innstillinger'
},
'account/balance': {
sv: '/mina-sidor/saldo',
en: '/my-account/balance',
da: '/min-konto/saldo',
fi: '/tilini/saldo',
nb: '/min-konto/saldo'
},
'favorites/index': {
sv: '/favoriter',
en: '/favorites',
da: '/favoritter',
fi: '/suosikkeja',
nb: '/favoritter'
},
'brands/index': {
sv: '/varumarken',
en: '/brands',
da: '/varemaerker',
fi: '/tavaramerkkeja',
nb: '/varemerker'
}
},
...domainSettings // Instead of 'strategy' and 'differentDomains'
}
]
- In
publicRuntimeConfig
: Remove theisMultiLanguage
andmarketInPath
properties. Replace thefallbackMarketId
withfallbackMarketAlias
, and Add themarkets
settings:
publicRuntimeConfig: {
...
// isMultiLanguage remove this
// marketInPath remove this
fallbackMarketAlias, // Instead of fallbackMarketId
...marketSettings, // Add this
markets, // Add this ... }
- Also add the
showProductReviewSectionarketInPath
andshowStarsInProductReviewForm
settings topublicRuntimeConfig
:
publicRuntimeConfig {
...
showProductReviewSection: true,
showStarsInProductReviewForm: true // it requires showProductReviewSection to be true
...
}
Implementation
Changes has been made to following mixins:
MixCheckout.js
: (Extensive changes, check out file in Ralph-UI)MixConfirmPage.js
: (added variablecheckoutMarket
to mutationcompleteCart
and queryconfirmCartQuery
)MixGlobalInit.js
: (Now usinggetMarketsQuery
)MixListPage.js
: (using$store.state.channel.id
instead of$store.state.channelId
)MixNostoSection.js
: (changed name fromCaNostoSection
toMixNostoSection
)MixDatalayer.js
,MixAddToCart.js
,MixNumberFormat.js
,MixProductCard.js
,MixProductPage.js
andMixUpdateCart.js
: (Usinggetters[channel/currentCurrency]
instead ofgetters.getCurrency
)If you have overriden any of these files and run into any problems, try to update the files.
- Add new file
channel.js
to your store folder:
import { state, getters, mutations, actions } from "channel";
export default {
state,
getters,
mutations,
actions,
};
- Add
@mixin scrollbarStyle
to/styles/helpers/_layout.scss
:
...
@mixin scrollbarStyle($color: $c-medium-gray, $hover: $c-darkest-gray) {
scrollbar-color: $color transparent;
scrollbar-width: thin;
&::-webkit-scrollbar {
background-color: transparent;
width: $px16 * 0.35;
height: $px16 * 0.35;
}
&::-webkit-scrollbar-track {
border-radius: 100vw;
}
&::-webkit-scrollbar-thumb {
background-color: $color;
border-radius: 100vw;
}
&::-webkit-scrollbar-thumb:hover {
background-color: $hover;
}
}
...
- Add
CaMarketPanel
to/layouts/default.vue
<template>
<div class="ca-layout-default" :class="modifiers">
...
<LazyCaMarketPanel
v-if="$store.state.channel.markets.length > 1"
mode="advanced"
/>
...
</div>
</template>
- Add
CaMarketSelectorButton
(replacesCaCountrySelectorPanel
) inCaSecondaryNav.vue
andCaTopBar.vue
(or wherever you prefer to place it).
<template>
<ul class="ca-secondary-nav">
...
<CaSecondaryNavItem>
<CaMarketSelectorButton />
</CaSecondaryNavItem>
...
</ul>
</template>
<template>
<div class="ca-top-bar" :class="{ 'ca-top-bar--undistracted': undistracted }">
...
<CaMarketSelectorButton
v-show="!undistracted"
class="ca-top-bar__lang-switcher only-computer"
/>
...
</div>
</template>
- Updates to
CaCheckout.vue
:- Use
selectableMarkets
instead ofmarkets
. - Use
setCheckoutMarket($event)
instead ofsetmarketId($event)
. - Use
!currentMarket
instead of!marketId
.
- Use
<template>
<div>
...
<CaCheckoutSection
v-if="
$store.getters['cart/totalQuantity'] &&
$config.checkout.showMultipleMarkets &&
selectableMarkets &&
selectableMarkets.length > 1
"
:loading="cartLoading"
>
<template #title>{{ $t('CHECKOUT_CHOOSE_COUNTRY') }}</template>
<CaCountrySelector
:data="selectableMarkets"
@input="setCheckoutMarket($event)"
/>
</CaCheckoutSection>
<CaCheckoutSection
v-if="$store.getters['cart/totalQuantity'] > 0"
:loading="shippingLoading"
:blocked="$config.checkout.showMultipleMarkets && !currentMarket"
>
...
</CaCheckoutSection>
</div>
</template>