Skip to content

shopware/frontends - composables

shopware/frontends - composables

Set of Vue.js composition functions that can be used in any Vue.js project. They provide state management, UI logic and data fetching and are the base for all guides in our building section.

Features

  • createShopwareContext method to create a Vue 3 plugin to install
  • State management
  • Logic for UI
  • Communication with Store-API via api-client package

Setup

Install npm packages (composables & api-client):

bash
# Using pnpm
pnpm add @shopware/composables @shopware/api-client @shopware/api-gen

# Using yarn
yarn add @shopware/composables @shopware/api-client @shopware/api-gen

# Using npm
npm i @shopware/composables @shopware/api-client @shopware/api-gen

Now generate your types ysing the CLI:

bash
pnpm shopware-api-gen generate --apiType=store

Initialize the api-client instance:

js
import { createAPIClient } from "@shopware/api-client";
import type { operations } from "#shopware";

export const apiClient = createAPIClient<operations>({
  baseURL: "https://your-api-instance.com",
  accessToken: "your-sales-channel-access-token",
});

// and then provide it in the Vue app
app.provide("apiClient", apiClient);

Now, we can create a Vue 3 plugin to install a Shopware context in an app:

js
import { createShopwareContext } from "@shopware/composables";

// app variable in type of App
const shopwareContext = createShopwareContext(app, {
  devStorefrontUrl: "https://your-sales-channel-configured-domain.com",
});
// register a plugin in a Vue instance
app.use(shopwareContext);

Exclude @shopware/composables package from pre-building process:

ts
// vite.config.js or .ts
...
optimizeDeps: {
  exclude: ["@shopware/composables"],
},
...

The example does not provide the session handling and that means you need to do few additional steps if you need to keep your session after the page reload (see the chapter below with 🍪)

Basic usage

Now you can use any composable function in your setup function:

html
<script setup>
    import { useUser, useSessionContext } from "@shopware/composables/dist";

    const { login } = useUser();
    const { refreshSessionContext, sessionContext } = useSessionContext();
    await refreshSessionContext();
</script>
<template>
    <pre>{{ sessionContext }}</pre>
    <button @click="login({
        username: "some-user",
        password: "secret-passwd"
    })">
        Try to login!
    </button>
</template>

Session persistence with 🍪

By default, the API-Client is stateless, but accepts an optional context token as a parameter while initializing an instance. In order to keep a session, install some cookie parser to work with cookies easier:

bash
# Using pnpm
pnpm add js-cookie

# Using yarn
yarn add js-cookie

# Using npm
npm i js-cookie

Let's get back to the step where the api-client was initialized:

ts
import { createAPIClient } from "@shopware/api-client";
import Cookies from "js-cookie";

import type { operations } from "#shopware";

const shopwareEndpoint = "https://demo-frontends.shopware.store/store-api";

export const apiClient = createAPIClient<operations>({
  baseURL: shopwareEndpoint,
  accessToken: "SWSCBHFSNTVMAWNZDNFKSHLAYW",
  contextToken: Cookies.get("sw-context-token"),
});

apiClient.hook("onContextChanged", (newContextToken) => {
  Cookies.set("sw-context-token", newContextToken, {
    expires: 365, // days
    path: "/",
    sameSite: "lax",
    secure: shopwareEndpoint.startsWith("https://"),
  });
});

Thanks to this, the session will be kept to the corresponding sw-context-token saved in the cookie, so it can be reachable also in the SSR. Check the example to see it in action:

TypeScript support

All composable functions are fully typed with TypeScript and they are registed globally in Nuxt.js application, so the type hinting will help you to work with all of them.

Changelog

Full changelog for stable version is available here

Latest changes: 1.13.0

Minor Changes

  • #2663 7020545 Thanks @mkucmus! - useCmsElementImage now honours the ariaLabel and isDecorative fields of a CMS image element, which were ignored before, and returns both. imageAttrs.alt is empty for a decorative image. ariaLabel names the link the image sits in, as it does in the Storefront, so it is not copied into alt.

    Both fields are optional on the image element config, because a Shopware instance that has never had them set does not return them. useCmsElementConfig accepts optional config members now, so getConfigValue keeps the declared value type for them instead of widening to {}.

    SliderElementConfig gained the "none" value for navigationDots and navigationArrows. The Administration offers it, the type did not list it.

  • #2642 183c183 Thanks @mdanilowicz! - Add createDraftQuoteVersion and deleteDraftQuoteVersion to useB2bQuoteManagement.

    Quote write operations such as declineQuoteWithComment expect the identifier of a temporary storefront draft version, not the versionId property of the quote entity. createDraftQuoteVersion wraps POST /quote/{id}/draft-version and returns that identifier, throwing when the API responds without one; deleteDraftQuoteVersion discards the draft again.

    ts
    const { createDraftQuoteVersion, declineQuoteWithComment } =
      useB2bQuoteManagement();
    
    const versionId = await createDraftQuoteVersion(quoteId);
    
    await declineQuoteWithComment(quoteId, {
      comment: "Too expensive",
      lineItemId,
      versionId,
    });
  • #2642 183c183 Thanks @mdanilowicz! - Add declineQuoteWithComment to useB2bQuoteManagement, following the Store API POST /quote/{id}/decline schema, which as of 6.7.12 also carries lineItemId and versionId next to comment.

    declineQuote keeps its (quoteId, comment) signature and is deprecated. It will be removed in the next major.

    ts
    const { declineQuoteWithComment, createDraftQuoteVersion } =
      useB2bQuoteManagement();
    
    const versionId = await createDraftQuoteVersion(quoteId);
    
    await declineQuoteWithComment(quoteId, {
      comment: "Too expensive",
      lineItemId,
      versionId,
    });

Patch Changes

  • #2676 458494e Thanks @mdanilowicz! - Realign the composables with the 6.7.13.0 Store API schema:

    • useB2bQuoteManagement: getQuote() now invokes readQuote post /quote/{id} (was readQuote post /quote/detail/{id}) and createOrderFromQuote() now invokes createOrderFromQuote post /quote/{id}/order (was createOrderFromQuote post /quote/order/{id}), matching the renamed endpoints.
    • useListing: getSortingOrders is typed as Schemas["ProductListingResult"]["availableSortings"] instead of the removed Schemas["ProductSorting"][].
    • useProductSearch: the associations option is typed as Partial<Schemas["Associations"]> instead of the removed Schemas["Association"].
  • #2660 8913956 Thanks @mdanilowicz! - useCmsElementImage now returns the translated media alt in imageAttrs. It read element.data.media.alt from the entity root, which the Store API fills with the system language value, so the alt attribute ignored the language of the current request. The value is now resolved with getTranslatedProperty() and falls back to the root property when translated is missing.

  • Updated dependencies [2ddf156, 204c8f4, 183c183, 458494e]:

    • @shopware/helpers@1.8.0
    • @shopware/api-client@1.6.0

Composables list

Was this page helpful?
UnsatisfiedSatisfied
Be the first to vote!
0.0 / 5  (0 votes)