Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vue-demo): leverage edge cache #309

Merged
merged 13 commits into from
Jul 11, 2023
5 changes: 5 additions & 0 deletions .changeset/dull-steaks-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@shopware-pwa/nuxt3-module": minor
---

Added new config `useUserContextInSSR` - set to true if you want for the server to use session from cookie and prepare view with it. Use carefully with edge caching to avoid sharing user data with edge cache. Default is false, so server will always use new context to prepare rendered view.
5 changes: 5 additions & 0 deletions .changeset/eight-rivers-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"vue-demo-store": minor
---

Session data are no longer rendered on server. Improved edge caching to achieve better performence.
6 changes: 6 additions & 0 deletions .changeset/gold-rockets-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"vue-demo-store": minor
"@shopware-pwa/cms-base": minor
---

Images are now lazy loaded, saves data on initial page load
1 change: 1 addition & 0 deletions packages/cms-base/components/SwProductCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ const srcPath = computed(() => {
>
<img
ref="imageElement"
loading="lazy"
:src="srcPath"
:alt="getProductName({ product }) || ''"
class="transform transition duration-400 hover:scale-120"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const toggle = () => {

<div v-if="option.media?.url">
<img
loading="lazy"
class="ml-2 h-4 w-4"
:src="option.media.url"
:alt="option.media.translated?.alt || ''"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const srcPath = computed(() => {
>
<img
ref="imageElement"
loading="lazy"
:class="{
'h-full w-full': true,
'absolute inset-0': ['cover', 'stretch'].includes(displayMode),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ function next() {
@click="() => changeCover(i)"
>
<img
loading="lazy"
:src="image.media.url"
class="w-full h-full object-center object-cover"
alt="Product image"
Expand Down
40 changes: 26 additions & 14 deletions packages/nuxt3-module/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const ShopwarePlugin = {
install(app, options) {
const runtimeConfig = useRuntimeConfig();

const useUserCookieContext =
!!runtimeConfig.public?.shopware?.useUserContextInSSR ||
!options.isServer;

const contextToken = useCookie("sw-context-token", {
maxAge: 60 * 60 * 24 * 365,
sameSite: "Lax",
Expand Down Expand Up @@ -47,26 +51,33 @@ const ShopwarePlugin = {
password:
"<%= options.shopwareApiClient.auth ? options.shopwareApiClient.auth.password : undefined %>",
},
contextToken: contextToken.value || cookieContextToken,
languageId: languageId.value || cookieLanguageId,
contextToken: useUserCookieContext
? contextToken.value || cookieContextToken
: "",
languageId: useUserCookieContext
? languageId.value || cookieLanguageId
: undefined,
});
/**
* Save current contextToken when its change
*/
instance.onConfigChange(({ config }) => {
try {
contextToken.value = config.contextToken;
languageId.value = config.languageId;
Cookies.set("sw-context-token", config.contextToken || "", {
expires: 365, //days
sameSite: "Lax",
path: "/",
});
Cookies.set("sw-language-id", config.languageId || "", {
expires: 365, //days
sameSite: "Lax",
path: "/",
});
// only save cookies on client side render
if (useUserCookieContext) {
contextToken.value = config.contextToken;
languageId.value = config.languageId;
Cookies.set("sw-context-token", config.contextToken || "", {
expires: 365, //days
sameSite: "Lax",
path: "/",
});
Cookies.set("sw-language-id", config.languageId || "", {
expires: 365, //days
sameSite: "Lax",
path: "/",
});
}
} catch (e) {
// Sometimes cookie is set on server after request is send, it can fail silently
}
Expand All @@ -88,5 +99,6 @@ const ShopwarePlugin = {
export default defineNuxtPlugin(async (nuxtApp) => {
nuxtApp.vueApp.use(ShopwarePlugin, {
apiDefaults: getDefaultApiParams(),
isServer: !!nuxtApp.ssrContext,
});
});
7 changes: 7 additions & 0 deletions packages/nuxt3-module/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ export type ShopwareNuxtOptions = {
apiClientConfig?: {
timeout?: number | string;
};
/**
* Use user context in SSR mode. Warning: with wrong edge caching it can cause serving another user's data.
* Use when edge caching is configured properly.
*
* @default false
*/
useUserContextInSSR?: boolean;
};

declare module "@nuxt/schema" {
Expand Down
97 changes: 95 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions templates/vue-demo-store/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ useHead({
});

const { apiInstance } = useShopwareContext();
const { data: sessionContextData } = await useAsyncData(
"sessionContext",
async () => {
return await getSessionContext(apiInstance);
}
);
const sessionContextData = ref();
sessionContextData.value = await getSessionContext(apiInstance);

// If you enable runtimeConfig.shopware.useUserContextInSSR, then you can use this code to share session between server and client.
// const { data: sessionContextData } = await useAsyncData(
// "sessionContext",
// async () => {
// return await getSessionContext(apiInstance);
// }
// );

// read the locale from accept-language header (i.e. en-GB or de-DE)
// and set configuration for price formatting globally
Expand Down
Loading