Repository: shopware/frontends
Pull request #314 (2023-07-12 06:39:32)

feat(e2e): add general timeout for single tests
### Description

<!-- Describe the changes you did and which issue you're closing
 example: closes #230
-->

### Type of change

<!--
  Please select the relevant option.
  Remember to run `pnpm run changeset` and describe your change (plus potential migration guide/important notes) to your pull request. Read more: https://github.com/shopware/frontends/blob/main/CONTRIBUTION.md#changelog-preparation
-->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)

### Screenshots (if applicable)

<!-- Please attach any relevant screenshots or images to help explain your changes. -->

### Additional context

<!-- Add any other context about the pull request here. -->


vercel[bot]: [vc]: #oGIq4hd/gSazrUpvUG2/hFWea1SZEk/yDAH6QY5nAIg=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJzaG9wd2FyZS1mcm9udGVuZHMtZG9jcyIsInJvb3REaXJlY3RvcnkiOm51bGwsImluc3BlY3RvclVybCI6Imh0dHBzOi8vdmVyY2VsLmNvbS9zaG9wd2FyZS1mcm9udGVuZHMvc2hvcHdhcmUtZnJvbnRlbmRzLWRvY3MvQlBQRmVzYjRUWWh1ZnIzSng0Y3puaFRzZHB0RSIsIm5leHRDb21taXRTdGF0dXMiOiJQRU5ESU5HIn0seyJuYW1lIjoiZnJvbnRlbmRzLWRlbW8iLCJyb290RGlyZWN0b3J5IjoidGVtcGxhdGVzL3Z1ZS1kZW1vLXN0b3JlIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3Nob3B3YXJlLWZyb250ZW5kcy9mcm9udGVuZHMtZGVtby9BS05QYkRYWG9ucFd3SEdxNFJCdnA5TThTdG5kIiwibmV4dENvbW1pdFN0YXR1cyI6IlBFTkRJTkcifV19
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Updated (UTC) |
| :--- | :----- | :------ | :------ |
| **frontends-demo** | 🔄 Building ([Inspect](https://vercel.com/shopware-frontends/frontends-demo/AKNPbDXXonpWwHGq4RBvp9M8Stnd)) |  | Jul 12, 2023 6:39am |
| **shopware-frontends-docs** | 🔄 Building ([Inspect](https://vercel.com/shopware-frontends/shopware-frontends-docs/BPPFesb4TYhufr3Jx4cznhTsdptE)) |  | Jul 12, 2023 6:39am |




Patch:
diff --git a/.changeset/itchy-kiwis-sin.md b/.changeset/itchy-kiwis-sin.md
new file mode 100644
index 00000000..97d9456f
--- /dev/null
+++ b/.changeset/itchy-kiwis-sin.md
@@ -0,0 +1,5 @@
+---
+"vue-demo-store": patch
+---
+
+Extract lang code from accept-language header in SSR for Intl.NumberFormat purposes
diff --git a/.changeset/spicy-terms-prove.md b/.changeset/spicy-terms-prove.md
new file mode 100644
index 00000000..ac9b3b96
--- /dev/null
+++ b/.changeset/spicy-terms-prove.md
@@ -0,0 +1,5 @@
+---
+"vue-demo-store": minor
+---
+
+Move AccountAddressForm to the shareable components folder
diff --git a/.gitignore b/.gitignore
index 58d4c941..2c9f3abd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,7 @@ dist
 .vscode/*
 !.vscode/extensions.json
 !.vscode/settings.json
+.idea
 
 # debug
 npm-debug.log*
@@ -45,4 +46,4 @@ yarn-error.log*
 
 .env 
 temp
-.temp
\ No newline at end of file
+.temp
diff --git a/apps/docs/src/framework/requirements.md b/apps/docs/src/framework/requirements.md
index e87ee12c..a8191c6c 100644
--- a/apps/docs/src/framework/requirements.md
+++ b/apps/docs/src/framework/requirements.md
@@ -23,7 +23,7 @@ Shopware Frontends does not differ between provisioning of the Shopware API. Bot
 
 Every development instance / setup template is pre-configured with a public demo API. That way you don't have to set up a Shopware instance yourself.
 
-<PageRef title="Install Shopware 6" sub="Set up Shopware 6 for development" page="https://developer.shopware.com/docs/guides/installation/overview" target="_blank" />
+<PageRef title="Install Shopware 6" sub="Set up Shopware 6 for development" page="https://developer.shopware.com/docs/guides/installation" target="_blank" />
 
 ## IDE
 
diff --git a/packages/composables/src/mocks/LoginResponse.ts b/packages/composables/src/mocks/LoginResponse.ts
new file mode 100644
index 00000000..6665b294
--- /dev/null
+++ b/packages/composables/src/mocks/LoginResponse.ts
@@ -0,0 +1,9 @@
+import { ContextUpdateResult } from "@shopware-pwa/types";
+
+const LoginResponse: ContextUpdateResult = {
+  apiAlias: "array_struct",
+  contextToken: "CK273DThPuUSoG6g76qBAncveqQ9h5I3",
+  redirectUrl: null,
+};
+
+export default LoginResponse;
diff --git a/packages/composables/src/mocks/Menu.ts b/packages/composables/src/mocks/Menu.ts
new file mode 100644
index 00000000..2516a115
--- /dev/null
+++ b/packages/composables/src/mocks/Menu.ts
@@ -0,0 +1,598 @@
+import { StoreNavigationElement } from "@shopware-pwa/types";
+
+const Menu: StoreNavigationElement[] = [
+  {
+    extensions: {
+      search: {
+        extensions: [],
+        _uniqueIdentifier: null,
+        translated: [],
+        autoIncrement: 26,
+      },
+    },
+    versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+    translated: {
+      breadcrumb: ["Home", "Footer Navigation", "Shop service "],
+      name: "Shop service ",
+      customFields: {},
+      linkType: null,
+      internalLink: null,
+      externalLink: null,
+      linkNewTab: null,
+      description: null,
+      metaTitle: null,
+      metaDescription: null,
+      keywords: null,
+    },
+    createdAt: "2020-08-06T06:26:25.159+00:00",
+    updatedAt: null,
+    afterCategoryId: null,
+    parentId: "0208fc353bdb492aba4bbd910ea5cc5a",
+    mediaId: null,
+    name: "Shop service ",
+    breadcrumb: ["Home", "Footer Navigation", "Shop service "],
+    path: "|525abe8981214bd2ba94fd33942333ec|0208fc353bdb492aba4bbd910ea5cc5a|",
+    level: 3,
+    active: true,
+    childCount: 3,
+    visibleChildCount: 2,
+    displayNestedProducts: true,
+    parent: null,
+    children: [
+      {
+        extensions: {
+          search: {
+            extensions: [],
+            _uniqueIdentifier: null,
+            translated: [],
+            autoIncrement: 31,
+          },
+        },
+        versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+        translated: {
+          breadcrumb: [
+            "Home",
+            "Footer Navigation",
+            "Shop service ",
+            "Defective Product",
+          ],
+          name: "Defective Product",
+          customFields: {},
+          linkType: null,
+          internalLink: null,
+          externalLink: null,
+          linkNewTab: null,
+          description: null,
+          metaTitle: null,
+          metaDescription: null,
+          keywords: null,
+        },
+        createdAt: "2020-08-06T06:26:25.218+00:00",
+        updatedAt: null,
+        afterCategoryId: null,
+        parentId: "c568b6d678014d9bbc5e1e4b684b79c7",
+        mediaId: null,
+        name: "Defective Product",
+        breadcrumb: [
+          "Home",
+          "Footer Navigation",
+          "Shop service ",
+          "Defective Product",
+        ],
+        path: "|525abe8981214bd2ba94fd33942333ec|0208fc353bdb492aba4bbd910ea5cc5a|c568b6d678014d9bbc5e1e4b684b79c7|",
+        level: 4,
+        active: true,
+        childCount: 0,
+        visibleChildCount: 0,
+        displayNestedProducts: true,
+        parent: null,
+        children: [],
+        translations: null,
+        media: null,
+        cmsPageId: "cafbc9662dcd462a941c6fd8b284c462",
+        cmsPageIdSwitched: false,
+        cmsPage: null,
+        linkType: null,
+        linkNewTab: null,
+        internalLink: null,
+        externalLink: null,
+        visible: true,
+        type: "page",
+        productAssignmentType: "product",
+        description: null,
+        metaTitle: null,
+        metaDescription: null,
+        keywords: null,
+        seoUrls: [
+          {
+            translated: [],
+            createdAt: "2022-08-01T14:02:03.482+00:00",
+            updatedAt: "2022-08-03T08:06:59.193+00:00",
+            salesChannelId: "98432def39fc4624b33213a56b8c944d",
+            languageId: "2fbb5fe2e29a4d70aa5854ce7ce3e20b",
+            routeName: "frontend.navigation.page",
+            foreignKey: "a8ac011151204f10bc3a3bf32ef3f29d",
+            pathInfo: "/navigation/a8ac011151204f10bc3a3bf32ef3f29d",
+            seoPathInfo: "Shop-service/Defective-Product/",
+            isCanonical: true,
+            isModified: false,
+            isDeleted: false,
+            isValid: null,
+            url: null,
+            customFields: null,
+            id: "5bc3ec6562b24fbdbf520af312d39889",
+            apiAlias: "seo_url",
+          },
+        ],
+        customEntityTypeId: null,
+        customFields: null,
+        id: "a8ac011151204f10bc3a3bf32ef3f29d",
+        apiAlias: "category",
+      },
+      {
+        extensions: {
+          search: {
+            extensions: [],
+            _uniqueIdentifier: null,
+            translated: [],
+            autoIncrement: 44,
+          },
+        },
+        versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+        translated: {
+          breadcrumb: [
+            "Home",
+            "Footer Navigation",
+            "Shop service ",
+            "Payment / Dispatch",
+          ],
+          name: "Payment / Dispatch",
+          customFields: {},
+          linkType: null,
+          internalLink: null,
+          externalLink: null,
+          linkNewTab: null,
+          description: null,
+          metaTitle: null,
+          metaDescription: null,
+          keywords: null,
+        },
+        createdAt: "2020-08-06T06:26:25.371+00:00",
+        updatedAt: null,
+        afterCategoryId: "a8ac011151204f10bc3a3bf32ef3f29d",
+        parentId: "c568b6d678014d9bbc5e1e4b684b79c7",
+        mediaId: null,
+        name: "Payment / Dispatch",
+        breadcrumb: [
+          "Home",
+          "Footer Navigation",
+          "Shop service ",
+          "Payment / Dispatch",
+        ],
+        path: "|525abe8981214bd2ba94fd33942333ec|0208fc353bdb492aba4bbd910ea5cc5a|c568b6d678014d9bbc5e1e4b684b79c7|",
+        level: 4,
+        active: true,
+        childCount: 0,
+        visibleChildCount: 0,
+        displayNestedProducts: true,
+        parent: null,
+        children: [],
+        translations: null,
+        media: null,
+        cmsPageId: "cafbc9662dcd462a941c6fd8b284c462",
+        cmsPageIdSwitched: false,
+        cmsPage: null,
+        linkType: null,
+        linkNewTab: null,
+        internalLink: null,
+        externalLink: null,
+        visible: true,
+        type: "page",
+        productAssignmentType: "product",
+        description: null,
+        metaTitle: null,
+        metaDescription: null,
+        keywords: null,
+        seoUrls: [
+          {
+            translated: [],
+            createdAt: "2022-08-01T14:02:03.482+00:00",
+            updatedAt: "2022-08-03T08:06:59.193+00:00",
+            salesChannelId: "98432def39fc4624b33213a56b8c944d",
+            languageId: "2fbb5fe2e29a4d70aa5854ce7ce3e20b",
+            routeName: "frontend.navigation.page",
+            foreignKey: "a19b6eddb87a4a8d80828997ad3f7fd4",
+            pathInfo: "/navigation/a19b6eddb87a4a8d80828997ad3f7fd4",
+            seoPathInfo: "Shop-service/Payment-Dispatch/",
+            isCanonical: true,
+            isModified: false,
+            isDeleted: false,
+            isValid: null,
+            url: null,
+            customFields: null,
+            id: "19f5bda939cb4147bc71ac0efa1573a4",
+            apiAlias: "seo_url",
+          },
+        ],
+        customEntityTypeId: null,
+        customFields: null,
+        id: "a19b6eddb87a4a8d80828997ad3f7fd4",
+        apiAlias: "category",
+      },
+    ],
+    translations: null,
+    media: null,
+    cmsPageId: "c7feafffb4404ebfb4090ffa328d2c7c",
+    cmsPageIdSwitched: true,
+    cmsPage: null,
+    linkType: null,
+    linkNewTab: null,
+    internalLink: null,
+    externalLink: null,
+    visible: true,
+    type: "page",
+    productAssignmentType: "product",
+    description: null,
+    metaTitle: null,
+    metaDescription: null,
+    keywords: null,
+    seoUrls: [
+      {
+        translated: [],
+        createdAt: "2022-08-01T14:02:03.482+00:00",
+        updatedAt: "2022-08-03T08:06:59.193+00:00",
+        salesChannelId: "98432def39fc4624b33213a56b8c944d",
+        languageId: "2fbb5fe2e29a4d70aa5854ce7ce3e20b",
+        routeName: "frontend.navigation.page",
+        foreignKey: "c568b6d678014d9bbc5e1e4b684b79c7",
+        pathInfo: "/navigation/c568b6d678014d9bbc5e1e4b684b79c7",
+        seoPathInfo: "Shop-service/",
+        isCanonical: true,
+        isModified: false,
+        isDeleted: false,
+        isValid: null,
+        url: null,
+        customFields: null,
+        id: "3b2716a1648649bd8a8d93eb326bea3d",
+        apiAlias: "seo_url",
+      },
+    ],
+    customEntityTypeId: null,
+    customFields: null,
+    id: "c568b6d678014d9bbc5e1e4b684b79c7",
+    apiAlias: "category",
+  },
+  {
+    extensions: {
+      search: {
+        extensions: [],
+        _uniqueIdentifier: null,
+        translated: [],
+        autoIncrement: 38,
+      },
+    },
+    versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+    translated: {
+      breadcrumb: ["Home", "Footer Navigation", "Information"],
+      name: "Information",
+      customFields: {},
+      linkType: null,
+      internalLink: null,
+      externalLink: null,
+      linkNewTab: null,
+      description: null,
+      metaTitle: null,
+      metaDescription: null,
+      keywords: null,
+    },
+    createdAt: "2020-08-06T06:26:25.300+00:00",
+    updatedAt: null,
+    afterCategoryId: "c568b6d678014d9bbc5e1e4b684b79c7",
+    parentId: "0208fc353bdb492aba4bbd910ea5cc5a",
+    mediaId: null,
+    name: "Information",
+    breadcrumb: ["Home", "Footer Navigation", "Information"],
+    path: "|525abe8981214bd2ba94fd33942333ec|0208fc353bdb492aba4bbd910ea5cc5a|",
+    level: 3,
+    active: true,
+    childCount: 3,
+    visibleChildCount: 3,
+    displayNestedProducts: true,
+    parent: null,
+    children: [
+      {
+        extensions: {
+          search: {
+            extensions: [],
+            _uniqueIdentifier: null,
+            translated: [],
+            autoIncrement: 43,
+          },
+        },
+        versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+        translated: {
+          breadcrumb: [
+            "Home",
+            "Footer Navigation",
+            "Information",
+            "General terms \u0026 conditions",
+          ],
+          name: "General terms \u0026 conditions",
+          customFields: {},
+          linkType: null,
+          internalLink: null,
+          externalLink: null,
+          linkNewTab: null,
+          description: null,
+          metaTitle: null,
+          metaDescription: null,
+          keywords: null,
+        },
+        createdAt: "2020-08-06T06:26:25.359+00:00",
+        updatedAt: "2022-08-01T03:47:22.714+00:00",
+        afterCategoryId: null,
+        parentId: "162cd978ddaa498790e70be6dc75d089",
+        mediaId: null,
+        name: "General terms \u0026 conditions",
+        breadcrumb: [
+          "Home",
+          "Footer Navigation",
+          "Information",
+          "General terms \u0026 conditions",
+        ],
+        path: "|525abe8981214bd2ba94fd33942333ec|0208fc353bdb492aba4bbd910ea5cc5a|162cd978ddaa498790e70be6dc75d089|",
+        level: 4,
+        active: true,
+        childCount: 0,
+        visibleChildCount: 0,
+        displayNestedProducts: true,
+        parent: null,
+        children: [],
+        translations: null,
+        media: null,
+        cmsPageId: "cafbc9662dcd462a941c6fd8b284c462",
+        cmsPageIdSwitched: false,
+        cmsPage: null,
+        linkType: null,
+        linkNewTab: null,
+        internalLink: null,
+        externalLink: null,
+        visible: true,
+        type: "page",
+        productAssignmentType: "product",
+        description: null,
+        metaTitle: null,
+        metaDescription: null,
+        keywords: null,
+        seoUrls: [
+          {
+            translated: [],
+            createdAt: "2023-05-22T12:15:30.642+00:00",
+            updatedAt: null,
+            salesChannelId: "98432def39fc4624b33213a56b8c944d",
+            languageId: "2fbb5fe2e29a4d70aa5854ce7ce3e20b",
+            routeName: "frontend.navigation.page",
+            foreignKey: "7318eb39105f4c92b15ac2f84a252169",
+            pathInfo: "/navigation/7318eb39105f4c92b15ac2f84a252169",
+            seoPathInfo: "Information/General-terms-conditions/",
+            isCanonical: true,
+            isModified: false,
+            isDeleted: false,
+            isValid: null,
+            url: null,
+            customFields: null,
+            id: "ec1162dfa21744e18f12aef1c334a3d1",
+            apiAlias: "seo_url",
+          },
+        ],
+        customEntityTypeId: null,
+        customFields: {},
+        id: "7318eb39105f4c92b15ac2f84a252169",
+        apiAlias: "category",
+      },
+      {
+        extensions: {
+          search: {
+            extensions: [],
+            _uniqueIdentifier: null,
+            translated: [],
+            autoIncrement: 96,
+          },
+        },
+        versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+        translated: {
+          breadcrumb: ["Home", "Footer Navigation", "Information", "Contact"],
+          name: "Contact",
+          customFields: {},
+          linkType: null,
+          internalLink: null,
+          externalLink: null,
+          linkNewTab: null,
+          description: null,
+          metaTitle: null,
+          metaDescription: null,
+          keywords: null,
+        },
+        createdAt: "2023-06-06T08:24:43.018+00:00",
+        updatedAt: "2023-06-06T08:25:43.398+00:00",
+        afterCategoryId: "7318eb39105f4c92b15ac2f84a252169",
+        parentId: "162cd978ddaa498790e70be6dc75d089",
+        mediaId: null,
+        name: "Contact",
+        breadcrumb: ["Home", "Footer Navigation", "Information", "Contact"],
+        path: "|525abe8981214bd2ba94fd33942333ec|0208fc353bdb492aba4bbd910ea5cc5a|162cd978ddaa498790e70be6dc75d089|",
+        level: 4,
+        active: true,
+        childCount: 0,
+        visibleChildCount: 0,
+        displayNestedProducts: true,
+        parent: null,
+        children: [],
+        translations: null,
+        media: null,
+        cmsPageId: "76ed25ab9c694873948f9183a8979a71",
+        cmsPageIdSwitched: false,
+        cmsPage: null,
+        linkType: null,
+        linkNewTab: null,
+        internalLink: null,
+        externalLink: null,
+        visible: true,
+        type: "page",
+        productAssignmentType: "product",
+        description: null,
+        metaTitle: null,
+        metaDescription: null,
+        keywords: null,
+        seoUrls: [
+          {
+            translated: [],
+            createdAt: "2023-06-06T08:25:43.629+00:00",
+            updatedAt: null,
+            salesChannelId: "98432def39fc4624b33213a56b8c944d",
+            languageId: "2fbb5fe2e29a4d70aa5854ce7ce3e20b",
+            routeName: "frontend.navigation.page",
+            foreignKey: "829d37718fe84e9d89bf377c197a029e",
+            pathInfo: "/navigation/829d37718fe84e9d89bf377c197a029e",
+            seoPathInfo: "Information/Contact/",
+            isCanonical: true,
+            isModified: false,
+            isDeleted: false,
+            isValid: null,
+            url: null,
+            customFields: null,
+            id: "9840d61b7e304f3cbf997c1ecdd3339e",
+            apiAlias: "seo_url",
+          },
+        ],
+        customEntityTypeId: null,
+        customFields: null,
+        id: "829d37718fe84e9d89bf377c197a029e",
+        apiAlias: "category",
+      },
+      {
+        extensions: {
+          search: {
+            extensions: [],
+            _uniqueIdentifier: null,
+            translated: [],
+            autoIncrement: 52,
+          },
+        },
+        versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+        translated: {
+          breadcrumb: ["Home", "Footer Navigation", "Information", "Imprint"],
+          name: "Imprint",
+          customFields: {},
+          linkType: null,
+          internalLink: null,
+          externalLink: null,
+          linkNewTab: null,
+          description: null,
+          metaTitle: null,
+          metaDescription: null,
+          keywords: null,
+        },
+        createdAt: "2020-08-06T06:26:25.465+00:00",
+        updatedAt: "2023-06-06T08:24:47.486+00:00",
+        afterCategoryId: "829d37718fe84e9d89bf377c197a029e",
+        parentId: "162cd978ddaa498790e70be6dc75d089",
+        mediaId: null,
+        name: "Imprint",
+        breadcrumb: ["Home", "Footer Navigation", "Information", "Imprint"],
+        path: "|525abe8981214bd2ba94fd33942333ec|0208fc353bdb492aba4bbd910ea5cc5a|162cd978ddaa498790e70be6dc75d089|",
+        level: 4,
+        active: true,
+        childCount: 0,
+        visibleChildCount: 0,
+        displayNestedProducts: true,
+        parent: null,
+        children: [],
+        translations: null,
+        media: null,
+        cmsPageId: "cafbc9662dcd462a941c6fd8b284c462",
+        cmsPageIdSwitched: false,
+        cmsPage: null,
+        linkType: null,
+        linkNewTab: null,
+        internalLink: null,
+        externalLink: null,
+        visible: true,
+        type: "page",
+        productAssignmentType: "product",
+        description: null,
+        metaTitle: null,
+        metaDescription: null,
+        keywords: null,
+        seoUrls: [
+          {
+            translated: [],
+            createdAt: "2023-05-22T12:15:30.642+00:00",
+            updatedAt: null,
+            salesChannelId: "98432def39fc4624b33213a56b8c944d",
+            languageId: "2fbb5fe2e29a4d70aa5854ce7ce3e20b",
+            routeName: "frontend.navigation.page",
+            foreignKey: "0c1493c7e7ec4961a393f18cf0310522",
+            pathInfo: "/navigation/0c1493c7e7ec4961a393f18cf0310522",
+            seoPathInfo: "Information/Imprint/",
+            isCanonical: true,
+            isModified: false,
+            isDeleted: false,
+            isValid: null,
+            url: null,
+            customFields: null,
+            id: "a9d9439488e045f1b496c6a09809189a",
+            apiAlias: "seo_url",
+          },
+        ],
+        customEntityTypeId: null,
+        customFields: null,
+        id: "0c1493c7e7ec4961a393f18cf0310522",
+        apiAlias: "category",
+      },
+    ],
+    translations: null,
+    media: null,
+    cmsPageId: "cafbc9662dcd462a941c6fd8b284c462",
+    cmsPageIdSwitched: false,
+    cmsPage: null,
+    linkType: null,
+    linkNewTab: null,
+    internalLink: null,
+    externalLink: null,
+    visible: true,
+    type: "page",
+    productAssignmentType: "product",
+    description: null,
+    metaTitle: null,
+    metaDescription: null,
+    keywords: null,
+    seoUrls: [
+      {
+        translated: [],
+        createdAt: "2022-08-01T14:02:03.482+00:00",
+        updatedAt: "2022-08-03T08:06:59.193+00:00",
+        salesChannelId: "98432def39fc4624b33213a56b8c944d",
+        languageId: "2fbb5fe2e29a4d70aa5854ce7ce3e20b",
+        routeName: "frontend.navigation.page",
+        foreignKey: "162cd978ddaa498790e70be6dc75d089",
+        pathInfo: "/navigation/162cd978ddaa498790e70be6dc75d089",
+        seoPathInfo: "Information/",
+        isCanonical: true,
+        isModified: false,
+        isDeleted: false,
+        isValid: null,
+        url: null,
+        customFields: null,
+        id: "29b38ac4ebbc413ca1af745503cdc890",
+        apiAlias: "seo_url",
+      },
+    ],
+    customEntityTypeId: null,
+    customFields: null,
+    id: "162cd978ddaa498790e70be6dc75d089",
+    apiAlias: "category",
+  },
+];
+
+export default Menu;
diff --git a/packages/composables/src/mocks/Product.ts b/packages/composables/src/mocks/Product.ts
new file mode 100644
index 00000000..115b5908
--- /dev/null
+++ b/packages/composables/src/mocks/Product.ts
@@ -0,0 +1,563 @@
+import { Product } from "@shopware-pwa/types";
+
+const product: Product = {
+  versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+  apiAlias: "product",
+  autoIncrement: 1,
+  calculatedListingPrice: null,
+  cheapestPrice: null,
+  listingPrices: null,
+  extensions: [],
+  productManufacturerVersionId: null,
+  purchasePrice: null,
+  seoCategory: null,
+  parentVersionId: null,
+  price: null,
+  prices: null,
+  tagIds: null,
+  tags: null,
+  translated: {
+    metaDescription: null,
+    name: "Cigar Special 40%",
+    keywords: null,
+    description:
+      "\u003Cp\u003ELorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.\u003C/p\u003E\n\u003Cp\u003EIn enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar.\u003C/p\u003E",
+    metaTitle: null,
+    packUnit: "Flasche(n)",
+    packUnitPlural: null,
+    customFields: {},
+  },
+  createdAt: "2020-08-06T06:26:45.773+00:00",
+  updatedAt: "2023-06-26T20:20:14.785+00:00",
+  parentId: "c349b26a505c46ca980efbe2f3b71607",
+  childCount: null,
+  taxId: "d55571c0b59a4a538fe44f16a3a206c3",
+  manufacturerId: "ed811aac3d264b35949e6808670e1c8c",
+  unitId: "0e0be7e6c06a4ebcba222c306986065a",
+  active: true,
+  displayGroup: "dadaf7a913c869100c0de0c074876353",
+  manufacturerNumber: null,
+  ean: null,
+  sales: 0,
+  productNumber: "SW10044",
+  stock: 24,
+  availableStock: 19,
+  available: true,
+  deliveryTimeId: "0caaf7f6131142f6b1fa81f3e3f6c0fb",
+  deliveryTime: {
+    translated: {
+      name: "1-3 days",
+      customFields: {},
+    },
+    createdAt: "2020-08-06T06:26:54.178+00:00",
+    updatedAt: "2020-08-06T06:26:54.182+00:00",
+    name: "1-3 days",
+    min: 1,
+    max: 3,
+    unit: "day",
+    customFields: null,
+    id: "0caaf7f6131142f6b1fa81f3e3f6c0fb",
+    apiAlias: "delivery_time",
+  },
+  restockTime: 1,
+  isCloseout: false,
+  purchaseSteps: 1,
+  maxPurchase: null,
+  minPurchase: 1,
+  purchaseUnit: 0.2,
+  referenceUnit: 1,
+  shippingFree: false,
+  markAsTopseller: false,
+  weight: null,
+  width: null,
+  height: null,
+  length: null,
+  releaseDate: null,
+  categoryTree: [
+    "525abe8981214bd2ba94fd33942333ec",
+    "bda4b60e845240b2b9d6b60e71196e14",
+    "ca15f1e906204da49afe666bbcca7825",
+    "54a3e428361147c0a3372d44070fb84d",
+    "2b91ba3b1b8d40658eda14f62450152a",
+  ],
+  streamIds: [
+    "1318833f46df457981763b94179d9ef0",
+    "5675448d6b3a4dd2a659d31a3dde74da",
+  ],
+  optionIds: ["c3979c6ac5844104afa113c4fbde87f8"],
+  propertyIds: null,
+  name: "Cigar Special 40%",
+  keywords: null,
+  description:
+    "\u003Cp\u003ELorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.\u003C/p\u003E\n\u003Cp\u003EIn enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar.\u003C/p\u003E",
+  metaDescription: null,
+  metaTitle: null,
+  packUnit: "Flasche(n)",
+  packUnitPlural: null,
+  tax: {
+    translated: [],
+    createdAt: "2020-08-06T06:23:32.056+00:00",
+    updatedAt: "2020-08-06T06:26:46.462+00:00",
+    taxRate: 19,
+    name: "19%",
+    position: 0,
+    customFields: null,
+    id: "d55571c0b59a4a538fe44f16a3a206c3",
+    apiAlias: "tax",
+  },
+  manufacturer: null,
+  unit: {
+    translated: {
+      shortCode: "l",
+      name: "litre",
+      customFields: {},
+    },
+    createdAt: "2020-08-06T06:26:30.695+00:00",
+    updatedAt: null,
+    shortCode: "l",
+    name: "litre",
+    customFields: null,
+    id: "0e0be7e6c06a4ebcba222c306986065a",
+    apiAlias: "unit",
+  },
+  cover: {
+    versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+    translated: [],
+    createdAt: "2020-08-06T06:26:45.773+00:00",
+    updatedAt: "2023-06-26T20:20:14.427+00:00",
+    productId: "7e117859f69b4ee08947e1ae4fce1f69",
+    mediaId: "7233c32db0bb434c826b1cb6972dbdf2",
+    position: 1,
+    media: {
+      translated: {
+        alt: null,
+        title: null,
+        customFields: {},
+      },
+      createdAt: "2020-08-06T06:25:57.072+00:00",
+      updatedAt: "2020-08-06T06:26:45.789+00:00",
+      mimeType: "image/jpeg",
+      fileExtension: "jpg",
+      fileSize: 320388,
+      title: null,
+      metaData: {
+        type: 2,
+        width: 1380,
+        height: 3588,
+      },
+      uploadedAt: null,
+      alt: null,
+      url: "https://cdn.shopware.store/a/B/m/pPkDE/media/a4/65/72/Cigar_Special.jpg",
+      fileName: "Cigar_Special",
+      translations: null,
+      thumbnails: [
+        {
+          translated: [],
+          createdAt: "2020-08-06T06:25:57.070+00:00",
+          updatedAt: "2020-08-06T06:26:45.787+00:00",
+          width: 800,
+          height: 800,
+          url: "https://cdn.shopware.store/a/B/m/pPkDE/thumbnail/a4/65/72/Cigar_Special_800x800.jpg",
+          mediaId: "7233c32db0bb434c826b1cb6972dbdf2",
+          customFields: null,
+          id: "2b039146738b400995c67e4bfdb63aa9",
+          apiAlias: "media_thumbnail",
+        },
+        {
+          translated: [],
+          createdAt: "2020-08-06T06:25:57.071+00:00",
+          updatedAt: "2020-08-06T06:26:45.788+00:00",
+          width: 400,
+          height: 400,
+          url: "https://cdn.shopware.store/a/B/m/pPkDE/thumbnail/a4/65/72/Cigar_Special_400x400.jpg",
+          mediaId: "7233c32db0bb434c826b1cb6972dbdf2",
+          customFields: null,
+          id: "89e03f87e1f54a499e3a4bfc231974ee",
+          apiAlias: "media_thumbnail",
+        },
+        {
+          translated: [],
+          createdAt: "2020-08-06T06:25:57.072+00:00",
+          updatedAt: "2020-08-06T06:26:45.789+00:00",
+          width: 1920,
+          height: 1920,
+          url: "https://cdn.shopware.store/a/B/m/pPkDE/thumbnail/a4/65/72/Cigar_Special_1920x1920.jpg",
+          mediaId: "7233c32db0bb434c826b1cb6972dbdf2",
+          customFields: null,
+          id: "fd29b1641cc14e4fb40d336e910c69c3",
+          apiAlias: "media_thumbnail",
+        },
+      ],
+      hasFile: true,
+      private: false,
+      customFields: null,
+      id: "7233c32db0bb434c826b1cb6972dbdf2",
+      apiAlias: "media",
+    },
+    customFields: null,
+    id: "f18e3715c27746b9afab3dd28fd7daf3",
+    apiAlias: "product_media",
+  },
+  parent: null,
+  children: null,
+  media: [
+    {
+      versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+      translated: [],
+      createdAt: "2020-08-06T06:26:45.767+00:00",
+      updatedAt: "2023-06-26T20:20:14.427+00:00",
+      productId: "7e117859f69b4ee08947e1ae4fce1f69",
+      mediaId: "c3c3a2f9a92a4d0cbcf682f9b17f29f4",
+      position: 0,
+      media: {
+        translated: {
+          alt: null,
+          title: null,
+          customFields: {},
+        },
+        createdAt: "2020-08-06T06:26:02.517+00:00",
+        updatedAt: "2020-08-06T06:26:45.784+00:00",
+        mimeType: "image/jpeg",
+        fileExtension: "jpg",
+        fileSize: 320388,
+        title: null,
+        metaData: {
+          type: 2,
+          width: 1380,
+          height: 3588,
+        },
+        uploadedAt: null,
+        alt: null,
+        url: "https://cdn.shopware.store/a/B/m/pPkDE/media/4b/7b/ee/SW10044.jpg",
+        fileName: "SW10044",
+        translations: null,
+        thumbnails: [
+          {
+            translated: [],
+            createdAt: "2020-08-06T06:26:02.515+00:00",
+            updatedAt: "2020-08-06T06:26:45.782+00:00",
+            width: 800,
+            height: 800,
+            url: "https://cdn.shopware.store/a/B/m/pPkDE/thumbnail/4b/7b/ee/SW10044_800x800.jpg",
+            mediaId: "c3c3a2f9a92a4d0cbcf682f9b17f29f4",
+            customFields: null,
+            id: "88c1bbadc4094e84be02eed9f4dd9b21",
+            apiAlias: "media_thumbnail",
+          },
+          {
+            translated: [],
+            createdAt: "2020-08-06T06:26:02.516+00:00",
+            updatedAt: "2020-08-06T06:26:45.783+00:00",
+            width: 1920,
+            height: 1920,
+            url: "https://cdn.shopware.store/a/B/m/pPkDE/thumbnail/4b/7b/ee/SW10044_1920x1920.jpg",
+            mediaId: "c3c3a2f9a92a4d0cbcf682f9b17f29f4",
+            customFields: null,
+            id: "b4e007f7a9ff4180858dcd3eda74511f",
+            apiAlias: "media_thumbnail",
+          },
+          {
+            translated: [],
+            createdAt: "2020-08-06T06:26:02.517+00:00",
+            updatedAt: "2020-08-06T06:26:45.783+00:00",
+            width: 400,
+            height: 400,
+            url: "https://cdn.shopware.store/a/B/m/pPkDE/thumbnail/4b/7b/ee/SW10044_400x400.jpg",
+            mediaId: "c3c3a2f9a92a4d0cbcf682f9b17f29f4",
+            customFields: null,
+            id: "e9f8287bb01d4024889a6632bdc55533",
+            apiAlias: "media_thumbnail",
+          },
+        ],
+        hasFile: true,
+        private: false,
+        customFields: null,
+        id: "c3c3a2f9a92a4d0cbcf682f9b17f29f4",
+        apiAlias: "media",
+      },
+      customFields: null,
+      id: "57e282b46fa24848a5da0dc42ad43868",
+      apiAlias: "product_media",
+    },
+    {
+      versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+      translated: [],
+      createdAt: "2020-08-06T06:26:45.773+00:00",
+      updatedAt: "2023-06-26T20:20:14.427+00:00",
+      productId: "7e117859f69b4ee08947e1ae4fce1f69",
+      mediaId: "7233c32db0bb434c826b1cb6972dbdf2",
+      position: 1,
+      media: {
+        translated: {
+          alt: null,
+          title: null,
+          customFields: {},
+        },
+        createdAt: "2020-08-06T06:25:57.072+00:00",
+        updatedAt: "2020-08-06T06:26:45.789+00:00",
+        mimeType: "image/jpeg",
+        fileExtension: "jpg",
+        fileSize: 320388,
+        title: null,
+        metaData: {
+          type: 2,
+          width: 1380,
+          height: 3588,
+        },
+        uploadedAt: null,
+        alt: null,
+        url: "https://cdn.shopware.store/a/B/m/pPkDE/media/a4/65/72/Cigar_Special.jpg",
+        fileName: "Cigar_Special",
+        translations: null,
+        thumbnails: [
+          {
+            translated: [],
+            createdAt: "2020-08-06T06:25:57.070+00:00",
+            updatedAt: "2020-08-06T06:26:45.787+00:00",
+            width: 800,
+            height: 800,
+            url: "https://cdn.shopware.store/a/B/m/pPkDE/thumbnail/a4/65/72/Cigar_Special_800x800.jpg",
+            mediaId: "7233c32db0bb434c826b1cb6972dbdf2",
+            customFields: null,
+            id: "2b039146738b400995c67e4bfdb63aa9",
+            apiAlias: "media_thumbnail",
+          },
+          {
+            translated: [],
+            createdAt: "2020-08-06T06:25:57.071+00:00",
+            updatedAt: "2020-08-06T06:26:45.788+00:00",
+            width: 400,
+            height: 400,
+            url: "https://cdn.shopware.store/a/B/m/pPkDE/thumbnail/a4/65/72/Cigar_Special_400x400.jpg",
+            mediaId: "7233c32db0bb434c826b1cb6972dbdf2",
+            customFields: null,
+            id: "89e03f87e1f54a499e3a4bfc231974ee",
+            apiAlias: "media_thumbnail",
+          },
+          {
+            translated: [],
+            createdAt: "2020-08-06T06:25:57.072+00:00",
+            updatedAt: "2020-08-06T06:26:45.789+00:00",
+            width: 1920,
+            height: 1920,
+            url: "https://cdn.shopware.store/a/B/m/pPkDE/thumbnail/a4/65/72/Cigar_Special_1920x1920.jpg",
+            mediaId: "7233c32db0bb434c826b1cb6972dbdf2",
+            customFields: null,
+            id: "fd29b1641cc14e4fb40d336e910c69c3",
+            apiAlias: "media_thumbnail",
+          },
+        ],
+        hasFile: true,
+        private: false,
+        customFields: null,
+        id: "7233c32db0bb434c826b1cb6972dbdf2",
+        apiAlias: "media",
+      },
+      customFields: null,
+      id: "f18e3715c27746b9afab3dd28fd7daf3",
+      apiAlias: "product_media",
+    },
+  ],
+  cmsPageId: null,
+  cmsPage: null,
+  translations: null,
+  categories: null,
+  properties: null,
+  options: null,
+  configuratorSettings: null,
+  categoriesRo: null,
+  coverId: "f18e3715c27746b9afab3dd28fd7daf3",
+  categoryIds: ["2b91ba3b1b8d40658eda14f62450152a"],
+  productReviews: null,
+  ratingAverage: null,
+  mainCategories: null,
+  seoUrls: [
+    {
+      translated: [],
+      createdAt: "2020-08-06T06:26:52.576+00:00",
+      updatedAt: "2022-08-03T08:07:04.512+00:00",
+      salesChannelId: "98432def39fc4624b33213a56b8c944d",
+      languageId: "2fbb5fe2e29a4d70aa5854ce7ce3e20b",
+      routeName: "frontend.detail.page",
+      foreignKey: "7e117859f69b4ee08947e1ae4fce1f69",
+      pathInfo: "/detail/7e117859f69b4ee08947e1ae4fce1f69",
+      seoPathInfo: "Cigar-Special-40/SW10044",
+      isCanonical: true,
+      isModified: false,
+      isDeleted: false,
+      isValid: null,
+      url: null,
+      customFields: null,
+      id: "dd38c5ed443544e28818e967809c8914",
+      apiAlias: "seo_url",
+    },
+  ],
+  crossSellings: null,
+  canonicalProductId: null,
+  canonicalProduct: null,
+  streams: null,
+  downloads: null,
+  states: ["is-physical"],
+  customFields: {},
+  id: "7e117859f69b4ee08947e1ae4fce1f69",
+  calculatedPrices: [],
+  calculatedPrice: {
+    unitPrice: 14.45,
+    quantity: 1,
+    totalPrice: 14.45,
+    calculatedTaxes: [
+      {
+        tax: 0.95,
+        taxRate: 7,
+        price: 14.45,
+        apiAlias: "cart_tax_calculated",
+      },
+    ],
+    taxRules: [
+      {
+        taxRate: 7,
+        percentage: 100,
+        apiAlias: "cart_tax_rule",
+      },
+    ],
+    referencePrice: {
+      purchaseUnit: 0.2,
+      referenceUnit: 1,
+      unitName: "litre",
+      price: 72.25,
+      apiAlias: "cart_price_reference",
+    },
+    listPrice: null,
+    regulationPrice: null,
+    apiAlias: "calculated_price",
+  },
+  sortedProperties: null,
+  calculatedCheapestPrice: {
+    unitPrice: 14.45,
+    quantity: 1,
+    totalPrice: 14.45,
+    calculatedTaxes: [
+      {
+        tax: 0.95,
+        taxRate: 7,
+        price: 14.45,
+        apiAlias: "cart_tax_calculated",
+      },
+    ],
+    taxRules: [
+      {
+        taxRate: 7,
+        percentage: 100,
+        apiAlias: "cart_tax_rule",
+      },
+    ],
+    referencePrice: {
+      purchaseUnit: 0.2,
+      referenceUnit: 1,
+      unitName: "litre",
+      price: 72.25,
+      apiAlias: "cart_price_reference",
+    },
+    listPrice: null,
+    regulationPrice: null,
+    hasRange: true,
+    variantId: "7e117859f69b4ee08947e1ae4fce1f69",
+    apiAlias: "calculated_cheapest_price",
+  },
+  isNew: false,
+  calculatedMaxPurchase: 100,
+  //   seoCategory: {
+  //     // extensions: {
+  //     //   search: {
+  //     //     extensions: [],
+  //     //     _uniqueIdentifier: null,
+  //     //     translated: [],
+  //     //     autoIncrement: 47,
+  //     //   },
+  //     // },
+  //     versionId: "0fa91ce3e96a4bc2be4bd9ce752c3425",
+  //     translated: {
+  //       breadcrumb: [
+  //         "Home",
+  //         "Welcome to Shopware Frontends!",
+  //         "Cooking pleasure \u0026 Provence",
+  //         "Drink",
+  //         "Brandies",
+  //       ],
+  //       name: "Brandies",
+  //       customFields: {},
+  //       linkType: null,
+  //       internalLink: null,
+  //       externalLink: null,
+  //       linkNewTab: null,
+  //       description: null,
+  //       metaTitle: null,
+  //       metaDescription: null,
+  //       keywords: null,
+  //     },
+  //     createdAt: "2020-08-06T06:26:25.406+00:00",
+  //     updatedAt: null,
+  //     afterCategoryId: null,
+  //     parentId: "54a3e428361147c0a3372d44070fb84d",
+  //     mediaId: null,
+  //     name: "Brandies",
+  //     breadcrumb: [
+  //       "Home",
+  //       "Welcome to Shopware Frontends!",
+  //       "Cooking pleasure \u0026 Provence",
+  //       "Drink",
+  //       "Brandies",
+  //     ],
+  //     path: "|525abe8981214bd2ba94fd33942333ec|bda4b60e845240b2b9d6b60e71196e14|ca15f1e906204da49afe666bbcca7825|54a3e428361147c0a3372d44070fb84d|",
+  //     level: 5,
+  //     active: true,
+  //     childCount: 0,
+  //     visibleChildCount: 0,
+  //     displayNestedProducts: true,
+  //     parent: null,
+  //     children: null,
+  //     translations: null,
+  //     media: null,
+  //     cmsPageId: "33043b9b89d642eb93cc8d14b8cf8f14",
+  //     cmsPageIdSwitched: false,
+  //     cmsPage: null,
+  //     linkType: null,
+  //     linkNewTab: null,
+  //     internalLink: null,
+  //     externalLink: null,
+  //     visible: true,
+  //     type: "page",
+  //     productAssignmentType: "product",
+  //     description: null,
+  //     metaTitle: null,
+  //     metaDescription: null,
+  //     keywords: null,
+  //     seoUrls: [
+  //       {
+  //         translated: [],
+  //         createdAt: "2022-08-01T14:02:03.482+00:00",
+  //         updatedAt: "2022-08-08T10:23:53.514+00:00",
+  //         salesChannelId: "98432def39fc4624b33213a56b8c944d",
+  //         languageId: "2fbb5fe2e29a4d70aa5854ce7ce3e20b",
+  //         routeName: "frontend.navigation.page",
+  //         foreignKey: "2b91ba3b1b8d40658eda14f62450152a",
+  //         pathInfo: "/navigation/2b91ba3b1b8d40658eda14f62450152a",
+  //         seoPathInfo: "Cooking-pleasure-Provence/Drink/Brandies/",
+  //         isCanonical: true,
+  //         isModified: false,
+  //         isDeleted: false,
+  //         isValid: null,
+  //         url: null,
+  //         customFields: null,
+  //         id: "9f13d27e18d84ff1ae7b1f01f9db9e63",
+  //         apiAlias: "seo_url",
+  //       },
+  //     ],
+  //     customEntityTypeId: null,
+  //     customFields: null,
+  //     id: "2b91ba3b1b8d40658eda14f62450152a",
+  //     apiAlias: "category",
+  //   },
+};
+
+export default product;
diff --git a/packages/composables/src/mocks/Salutations.ts b/packages/composables/src/mocks/Salutations.ts
new file mode 100644
index 00000000..83f5e534
--- /dev/null
+++ b/packages/composables/src/mocks/Salutations.ts
@@ -0,0 +1,51 @@
+import { Salutation } from "@shopware-pwa/types";
+
+const salutations: Salutation[] = [
+  {
+    translated: {
+      displayName: "Mr.",
+      letterName: "Dear Mr.",
+      customFields: {},
+    },
+    createdAt: "2020-08-06T06:23:29.757+00:00",
+    updatedAt: "2020-08-06T06:26:29.283+00:00",
+    salutationKey: "mr",
+    displayName: "Mr.",
+    letterName: "Dear Mr.",
+    customFields: null,
+    id: "d5e543063dd642b48ef94b02d68e5785",
+    apiAlias: "salutation",
+  },
+  {
+    translated: {
+      displayName: "Mrs.",
+      letterName: "Dear Mrs.",
+      customFields: {},
+    },
+    createdAt: "2020-08-06T06:23:29.768+00:00",
+    updatedAt: "2020-08-06T06:26:29.267+00:00",
+    salutationKey: "mrs",
+    displayName: "Mrs.",
+    letterName: "Dear Mrs.",
+    customFields: null,
+    id: "fef89b093c4843af86f26a07d0e81108",
+    apiAlias: "salutation",
+  },
+  {
+    translated: {
+      displayName: "Not specified",
+      letterName: " ",
+      customFields: {},
+    },
+    createdAt: "2020-08-06T06:23:29.780+00:00",
+    updatedAt: "2020-08-06T06:26:29.274+00:00",
+    salutationKey: "not_specified",
+    displayName: "Not specified",
+    letterName: " ",
+    customFields: null,
+    id: "b84038d62c3f4d66b3bc626df7fa949e",
+    apiAlias: "salutation",
+  },
+];
+
+export default salutations;
diff --git a/packages/composables/src/useNavigation.spec.ts b/packages/composables/src/useNavigation.spec.ts
new file mode 100644
index 00000000..ba059ef2
--- /dev/null
+++ b/packages/composables/src/useNavigation.spec.ts
@@ -0,0 +1,53 @@
+import { describe, expect, it, vi } from "vitest";
+import { shallowMount } from "@vue/test-utils";
+import { useNavigation } from "./useNavigation";
+import * as apiExports from "@shopware-pwa/api-client";
+import Menu from "./mocks/Menu";
+
+const getMockProvide = () => ({
+  global: {
+    provide: {
+      shopware: {
+        apiInstance: {
+          config: {},
+        },
+      },
+    },
+  },
+});
+
+const Component = {
+  template: "<div/>",
+  props: {},
+  setup() {
+    const { navigationElements, loadNavigationElements } = useNavigation();
+    return { navigationElements, loadNavigationElements };
+  },
+};
+
+describe("useNavigation", () => {
+  const wrapper = shallowMount(Component, getMockProvide());
+
+  vi.spyOn(apiExports, "getStoreNavigation").mockImplementation(() => {
+    return new Promise((resolve) => {
+      resolve(Menu);
+    });
+  });
+
+  it("should set the menu", async () => {
+    await wrapper.vm.loadNavigationElements({
+      depth: 3,
+    });
+    expect(wrapper.vm.navigationElements.length).toBe(Menu.length);
+  });
+
+  it("menu is empty because of the error", async () => {
+    vi.spyOn(apiExports, "getStoreNavigation").mockImplementation(() => {
+      throw new Error("Test error");
+    });
+    await wrapper.vm.loadNavigationElements({
+      depth: 3,
+    });
+    expect(wrapper.vm.navigationElements.length).toBe(0);
+  });
+});
diff --git a/packages/composables/src/useProduct.spec.ts b/packages/composables/src/useProduct.spec.ts
new file mode 100644
index 00000000..0a2926fc
--- /dev/null
+++ b/packages/composables/src/useProduct.spec.ts
@@ -0,0 +1,24 @@
+import { describe, expect, it } from "vitest";
+import { shallowMount } from "@vue/test-utils";
+import { useProduct } from "./useProduct";
+import mockedProduct from "./mocks/Product";
+const Component = {
+  template: "<div/>",
+  props: {},
+  setup() {
+    const { product, configurator, changeVariant } = useProduct(mockedProduct);
+    return { product, configurator, changeVariant };
+  },
+};
+
+describe("useProduct", () => {
+  const wrapper = shallowMount(Component);
+
+  it("should return product object", () => {
+    expect(wrapper.vm.product).toStrictEqual(mockedProduct);
+  });
+
+  it("should return undefined configurator object", () => {
+    expect(wrapper.vm.configurator).toBe(undefined);
+  });
+});
diff --git a/packages/composables/src/useProduct.ts b/packages/composables/src/useProduct.ts
index c1a5dc42..a02c9a24 100644
--- a/packages/composables/src/useProduct.ts
+++ b/packages/composables/src/useProduct.ts
@@ -5,6 +5,7 @@ import ContextError from "./helpers/ContextError";
 
 export type UseProductReturn = {
   /**
+   * Returns product object
    * {@link Product} object
    */
   product: ComputedRef<Product>;
diff --git a/packages/composables/src/useSalutations.spec.ts b/packages/composables/src/useSalutations.spec.ts
new file mode 100644
index 00000000..7c70240f
--- /dev/null
+++ b/packages/composables/src/useSalutations.spec.ts
@@ -0,0 +1,47 @@
+import { useSalutations } from "./useSalutations";
+import { describe, expect, it, vi } from "vitest";
+import { shallowMount } from "@vue/test-utils";
+import Salutations from "./mocks/Salutations";
+import * as apiExports from "@shopware-pwa/api-client";
+
+const Component = {
+  template: "<div/>",
+  props: {},
+  setup() {
+    const { mountedCallback, fetchSalutations, getSalutations } =
+      useSalutations();
+
+    return {
+      mountedCallback,
+      fetchSalutations,
+      getSalutations,
+    };
+  },
+};
+
+const getMockProvide = () => ({
+  global: {
+    provide: {
+      shopware: {
+        apiInstance: {
+          config: {},
+        },
+      },
+    },
+  },
+});
+
+describe("useSalutations", () => {
+  vi.spyOn(apiExports, "getAvailableSalutations").mockImplementation(() => {
+    return new Promise((resolve) => {
+      resolve({ elements: Salutations });
+    });
+  });
+
+  const wrapper = shallowMount(Component, getMockProvide());
+
+  it("should init value on init", async () => {
+    await wrapper.vm.mountedCallback();
+    expect(wrapper.vm.getSalutations).toStrictEqual(Salutations);
+  });
+});
diff --git a/packages/composables/src/useUser.spec.ts b/packages/composables/src/useUser.spec.ts
new file mode 100644
index 00000000..a2412fc5
--- /dev/null
+++ b/packages/composables/src/useUser.spec.ts
@@ -0,0 +1,102 @@
+import { useUser } from "./useUser";
+import * as useSessionContext from "./useSessionContext";
+import * as useCart from "./useCart";
+import { describe, expect, it, vi } from "vitest";
+import { shallowMount } from "@vue/test-utils";
+import * as apiExports from "@shopware-pwa/api-client";
+import LoginResponse from "./mocks/LoginResponse";
+
+const Component = {
+  template: "<div/>",
+  props: {},
+  setup() {
+    const {
+      login,
+      register,
+      user,
+      isLoggedIn,
+      isCustomerSession,
+      isGuestSession,
+      refreshUser,
+      logout,
+      updateEmail,
+      updatePersonalInfo,
+      setDefaultPaymentMethod,
+      loadSalutation,
+      salutation,
+      loadCountry,
+      country,
+      defaultBillingAddressId,
+      defaultShippingAddressId,
+      userDefaultPaymentMethod,
+      userDefaultBillingAddress,
+      userDefaultShippingAddress,
+    } = useUser();
+
+    return {
+      login,
+      register,
+      user,
+      isLoggedIn,
+      isCustomerSession,
+      isGuestSession,
+      refreshUser,
+      logout,
+      updateEmail,
+      updatePersonalInfo,
+      setDefaultPaymentMethod,
+      loadSalutation,
+      salutation,
+      loadCountry,
+      country,
+      defaultBillingAddressId,
+      defaultShippingAddressId,
+      userDefaultPaymentMethod,
+      userDefaultBillingAddress,
+      userDefaultShippingAddress,
+    };
+  },
+};
+
+const getMockProvide = () => ({
+  global: {
+    provide: {
+      shopware: {
+        apiInstance: {
+          config: {},
+        },
+      },
+    },
+  },
+});
+
+describe("useUser", () => {
+  vi.spyOn(apiExports, "login").mockImplementation(() => {
+    return new Promise((resolve) => {
+      resolve(LoginResponse);
+    });
+  });
+
+  const useSessionContextSpy = vi
+    .spyOn(useSessionContext, "useSessionContext")
+    .mockImplementation((): any => {
+      return {
+        refreshSessionContext: () => undefined,
+      };
+    });
+  const useCartSpy = vi
+    .spyOn(useCart, "useCart")
+    .mockImplementation((): any => {
+      return {
+        refreshCart: () => undefined,
+      };
+    });
+
+  const wrapper = shallowMount(Component, getMockProvide());
+  it("login function", async () => {
+    await wrapper.vm.login("test@test.zzz", "test");
+
+    expect(useSessionContextSpy).toHaveBeenCalled();
+    expect(useCartSpy).toHaveBeenCalled();
+  });
+});
diff --git a/packages/types/shopware-6-client/models/checkout/cart/price/CalculatedPrice.d.ts b/packages/types/shopware-6-client/models/checkout/cart/price/CalculatedPrice.d.ts
index 6f813ab8..e30319e8 100644
--- a/packages/types/shopware-6-client/models/checkout/cart/price/CalculatedPrice.d.ts
+++ b/packages/types/shopware-6-client/models/checkout/cart/price/CalculatedPrice.d.ts
@@ -12,15 +12,16 @@ export type CalculatedPrice = {
   calculatedTaxes: CalculatedTax[];
   taxRules: TaxRule[];
   referencePrice: ReferencePrice;
-  hasRange: boolean;
+  hasRange?: boolean;
   listPrice: {
     price: number;
     discount: number;
     percentage: number;
     apiAlias: string;
-  };
+  } | null;
   regulationPrice: null | {
     price: number;
   };
-  apiAlias: "calculated_price";
+  apiAlias: string;
+  variantId?: string;
 };
diff --git a/packages/types/shopware-6-client/models/checkout/cart/price/ReferencePrice.d.ts b/packages/types/shopware-6-client/models/checkout/cart/price/ReferencePrice.d.ts
index 4ad4eee0..4ad2c46d 100644
--- a/packages/types/shopware-6-client/models/checkout/cart/price/ReferencePrice.d.ts
+++ b/packages/types/shopware-6-client/models/checkout/cart/price/ReferencePrice.d.ts
@@ -1,5 +1,7 @@
 export type ReferencePrice = {
   price: number;
-  referenceUnit: string;
+  purchaseUnit: number;
+  referenceUnit: number | string;
   unitName: string;
+  apiAlias?: string;
 };
diff --git a/packages/types/shopware-6-client/models/common/Entity.d.ts b/packages/types/shopware-6-client/models/common/Entity.d.ts
index 1f5ff270..b9f22824 100644
--- a/packages/types/shopware-6-client/models/common/Entity.d.ts
+++ b/packages/types/shopware-6-client/models/common/Entity.d.ts
@@ -7,10 +7,10 @@
  * @beta
  */
 export type Entity = {
-  _uniqueIdentifier: string;
+  _uniqueIdentifier?: string;
   versionId: string;
   translated: unknown;
-  createdAt: Date | null;
+  createdAt: Date | string | null;
   updatedAt: Date | string | null;
   apiAlias: string;
 };
diff --git a/packages/types/shopware-6-client/models/content/category/Category.d.ts b/packages/types/shopware-6-client/models/content/category/Category.d.ts
index 5eb1e6c4..9757471a 100644
--- a/packages/types/shopware-6-client/models/content/category/Category.d.ts
+++ b/packages/types/shopware-6-client/models/content/category/Category.d.ts
@@ -5,7 +5,7 @@ import { Entity } from "../../common/Entity";
 import { Tag } from "../../system/tag/Tag";
 import { CategoryTranslation } from "./CategoryTranslation";
 import { CustomFields } from "../../common/CustomField";
-
+import { SeoUrl } from "../navigation/Navigation";
 /**
  * Source: https://github.com/shopware/platform/blob/master/src/Core/Content/Category/CategoryDefinition.php#L50
  *
@@ -18,7 +18,7 @@ export type CategoryType = "page" | "link" | "folder";
  */
 export type Category = Entity & {
   parentId: string | null;
-  autoIncrement: number;
+  autoIncrement?: number;
   mediaId: string | null;
   name: string | null;
   breadcrumb: string[];
@@ -30,45 +30,49 @@ export type Category = Entity & {
   children: Category[] | null;
   translations: CategoryTranslation[] | null;
   media: Media | null;
-  products: Product[] | null;
-  nestedProducts: Product[] | null;
+  products?: Product[] | null;
+  nestedProducts?: Product[] | null;
   afterCategoryId: string | null;
-  customFields: CustomFields;
-  tags: Tag[] | null;
+  customFields: CustomFields | null;
+  tags?: Tag[] | null;
   cmsPageId: string | null;
   cmsPage: CmsPage | null;
-  slotConfig: [] | null;
+  slotConfig?: [] | null;
   externalLink: string | null;
-  linkNewTab: boolean;
+  linkNewTab: boolean | null;
   visible: boolean;
   type: CategoryType;
-  description: string;
+  description: string | null;
   id: string;
-  parentVersionId: string;
-  childrenCount: number;
-  afterCategoryVersionId: string;
+  parentVersionId?: string;
+  childrenCount?: number;
+  afterCategoryVersionId?: string;
   path?: string;
   route?: {
     path?: string;
   };
-  seoUrls: {
-    apiAlias: string;
-    pathInfo: string;
-    seoPathInfo: string;
-  }[];
+  seoUrls: SeoUrl[] | null;
   metaTitle: string | null;
   metaDescription: string | null;
   keywords: string | null;
   translated: {
     name: string;
     breadcrumb: string[];
-    description: string;
-    externalLink: string;
+    description: string | null;
+    externalLink: string | null;
     metaTitle: string | null;
     metaDescription: string | null;
     keywords: string | null;
-    customFields: CustomFields;
+    customFields: CustomFields | null;
+    linkType: string | null;
+    internalLink: string | null;
+    linkNewTab: string | null;
   };
-  linkType: "product" | "category" | "landing_page" | string;
+  linkType: "product" | "category" | "landing_page" | string | null;
   internalLink: string | null;
+  extensions?: unknown;
+  visibleChildCount?: number | null;
+  cmsPageIdSwitched?: boolean;
+  productAssignmentType?: string;
+  customEntityTypeId?: string | null;
 };
diff --git a/packages/types/shopware-6-client/models/content/media/Media.d.ts b/packages/types/shopware-6-client/models/content/media/Media.d.ts
index 96ef1a8f..52ec2c81 100644
--- a/packages/types/shopware-6-client/models/content/media/Media.d.ts
+++ b/packages/types/shopware-6-client/models/content/media/Media.d.ts
@@ -26,12 +26,12 @@ export type Media = {
   fileSize: number;
   title: null | string;
   metaData: {
-    hash: string;
+    hash?: string;
     type: number;
     width: number;
     height: number;
   };
-  uploadedAt: string;
+  uploadedAt: Date | string | null;
   alt: null | string;
   url: string;
   fileName: string;
@@ -39,17 +39,17 @@ export type Media = {
   thumbnails: MediaThumbnail[];
   hasFile: boolean;
   private: boolean;
-  _uniqueIdentifier: string;
-  versionId: null | string;
+  _uniqueIdentifier?: string;
+  versionId?: null | string;
   translated: {
     alt: null | string;
     title: null | string;
-    customFields: CustomFields;
+    customFields: CustomFields | null;
   };
   createdAt: string;
   updatedAt: Date | string | null;
-  extensions: unknown;
+  extensions?: unknown;
   id: string;
-  customFields: CustomFields;
+  customFields: CustomFields | null;
   apiAlias: "media";
 };
diff --git a/packages/types/shopware-6-client/models/content/media/MediaThumbnail.d.ts b/packages/types/shopware-6-client/models/content/media/MediaThumbnail.d.ts
index b759d774..83824644 100644
--- a/packages/types/shopware-6-client/models/content/media/MediaThumbnail.d.ts
+++ b/packages/types/shopware-6-client/models/content/media/MediaThumbnail.d.ts
@@ -5,13 +5,13 @@ export type MediaThumbnail = {
   height: number;
   url: string;
   mediaId: string;
-  _uniqueIdentifier: string;
-  versionId: null | string;
+  _uniqueIdentifier?: string;
+  versionId?: null | string;
   translated: unknown;
   createdAt: string;
   updatedAt: Date | string | null;
-  extensions: unknown;
+  extensions?: unknown;
   id: string;
-  customFields: CustomFields;
+  customFields: CustomFields | null;
   apiAlias: "media_thumbnail";
 };
diff --git a/packages/types/shopware-6-client/models/content/navigation/Navigation.d.ts b/packages/types/shopware-6-client/models/content/navigation/Navigation.d.ts
index 77a195b9..8e0bebd1 100644
--- a/packages/types/shopware-6-client/models/content/navigation/Navigation.d.ts
+++ b/packages/types/shopware-6-client/models/content/navigation/Navigation.d.ts
@@ -33,19 +33,19 @@ export type SeoUrl = {
    * @deprecated removed from 6.5.0
    */
   isValid: null | boolean;
-  language: null | boolean;
+  language?: null | boolean;
   url: null | string;
   customFields: CustomFields | null;
   /**
    * @deprecated removed from 6.5.0
    */
-  error: null | any;
-  _uniqueIdentifier: string;
-  versionId: null | string;
+  error?: null | any;
+  _uniqueIdentifier?: string;
+  versionId?: null | string;
   translated: [];
-  createdAt: Date;
+  createdAt: Date | string;
   updatedAt: Date | string | null;
-  extensions: unknown;
+  extensions?: unknown;
   id: string;
   apiAlias: string;
 };
diff --git a/packages/types/shopware-6-client/models/content/product/Product.d.ts b/packages/types/shopware-6-client/models/content/product/Product.d.ts
index 5776f5c6..0617e3f2 100644
--- a/packages/types/shopware-6-client/models/content/product/Product.d.ts
+++ b/packages/types/shopware-6-client/models/content/product/Product.d.ts
@@ -59,27 +59,28 @@ export type Product = {
   available: boolean;
   availableStock: number | null;
   calculatedCheapestPrice: CalculatedPrice;
-  calculatedListingPrice: ListingPrice;
+  calculatedListingPrice: ListingPrice | null;
   calculatedMaxPurchase: number;
   calculatedPrice: CalculatedPrice;
   calculatedPrices: CalculatedPrice[];
   canonicalProduct: any;
   canonicalProductId: string | null;
-  categories: Category[];
+  categories: Category[] | null;
   categoriesRo: Category[] | null;
   categoryIds: string[];
-  categoryTree: [] | null;
-  cheapestPrice: ProductCheapestPrice;
-  childCount: number;
-  children: Product[];
+  categoryTree: string[] | null;
+  cheapestPrice: ProductCheapestPrice | null;
+  childCount: number | null;
+  children: Product[] | null;
   cmsPage: null | CmsPage;
   cmsPageId: string | null;
   configuratorSettings: PropertyGroup[] | null;
   cover: ProductMedia;
   coverId: string | null;
-  createdAt: Date;
-  crossSellings: CrossSelling[];
+  createdAt: Date | string;
+  crossSellings: CrossSelling[] | null;
   customFields: CustomFields;
+  updatedAt: Date | string | null;
   deliveryTime: DeliveryTime;
   deliveryTimeId: string | null;
   description: string | null;
@@ -94,7 +95,7 @@ export type Product = {
   keywords: string | null;
   length: number | null;
   listingPrices: ListingPrice[] | null;
-  mainCategories: ProductMainCategories;
+  mainCategories: ProductMainCategories | null;
   manufacturer: ProductManufacturer | null;
   manufacturerId: string | null;
   manufacturerNumber: string | null;
@@ -106,15 +107,15 @@ export type Product = {
   minPurchase: number | null;
   name: string | null;
   optionIds?: string[];
-  options: PropertyGroupOption[];
+  options: PropertyGroupOption[] | null;
   packUnit: string | null;
   packUnitPlural: string | null;
-  parent: Product;
+  parent: Product | null;
   parentId: string | null;
-  parentVersionId: string;
+  parentVersionId: string | null;
   price: Price[] | null;
-  prices: ProductPrice[];
-  productManufacturerVersionId: string;
+  prices: ProductPrice[] | null;
+  productManufacturerVersionId: string | null;
   productNumber: string;
   productReviews: ProductReview[] | null;
   properties: PropertyGroupOption[] | null;
@@ -124,23 +125,23 @@ export type Product = {
   purchaseUnit: number | null;
   ratingAverage: number | null;
   referenceUnit: number | null;
-  releaseDate: Date;
+  releaseDate: Date | string | null;
   restockTime: number;
   sales: number;
-  seoCategory: Category;
+  seoCategory: Category | null;
   seoUrls: SeoUrl[] | null;
   shippingFree: boolean | null;
   sortedProperties: PropertyGroup[] | null;
   states: string[];
   stock: number;
   streamIds: string[] | null;
-  streams: ProductStreams;
+  streams: ProductStreams | null;
   tagIds: [] | null;
-  tags: Tag[];
+  tags: Tag[] | null;
   tax: Tax;
   taxId: string | null;
   translated: ProductTranslated;
-  translations: ProductTranslation[];
+  translations: ProductTranslation[] | null;
   unit: Unit | null;
   unitId: string | null;
   updatedAt: Date;
@@ -172,6 +173,8 @@ export type ProductTranslated = {
   keywords: string | null;
   metaTitle: string | null;
   customFields: CustomFields;
+  packUnit: string | null;
+  packUnitPlural: string | null;
 };
 
 export type ProductMainCategories = {
diff --git a/packages/types/shopware-6-client/models/content/product/ProductMedia.d.ts b/packages/types/shopware-6-client/models/content/product/ProductMedia.d.ts
index a722f42b..4c8007dc 100644
--- a/packages/types/shopware-6-client/models/content/product/ProductMedia.d.ts
+++ b/packages/types/shopware-6-client/models/content/product/ProductMedia.d.ts
@@ -11,12 +11,12 @@ export type ProductMedia = {
   position: number;
   media: Media;
   customFields: null | CustomFields;
-  _uniqueIdentifier: string;
+  _uniqueIdentifier?: string;
   versionId: string;
   translated: [];
   createdAt: string;
   updatedAt: Date | string | null;
-  extensions: unknown;
+  extensions?: unknown;
   id: string;
   apiAlias: "product_media";
 };
diff --git a/packages/types/shopware-6-client/models/system/salutation/Salutation.d.ts b/packages/types/shopware-6-client/models/system/salutation/Salutation.d.ts
index bd3ddbc3..ea068f55 100644
--- a/packages/types/shopware-6-client/models/system/salutation/Salutation.d.ts
+++ b/packages/types/shopware-6-client/models/system/salutation/Salutation.d.ts
@@ -1,5 +1,5 @@
 import { SalutationTranslation } from "./SalutationTranslation";
-
+import { CustomFields } from "../models/common/CustomField";
 /**
  * @public
  */
@@ -9,8 +9,10 @@ export type Salutation = {
   displayName: string | null;
   letterName: string | null;
   createdAt: string;
-  translations: SalutationTranslation[] | null;
+  translations?: SalutationTranslation[] | null;
   translated: object;
   updatedAt: Date | string | null;
-  extenstions: object;
+  extensions?: object;
+  customFields: CustomFields;
+  apiAlias: string;
 };
diff --git a/packages/types/shopware-6-client/models/system/tax/CalculatedTax.d.ts b/packages/types/shopware-6-client/models/system/tax/CalculatedTax.d.ts
index 3b0a827d..6d8eb3cf 100644
--- a/packages/types/shopware-6-client/models/system/tax/CalculatedTax.d.ts
+++ b/packages/types/shopware-6-client/models/system/tax/CalculatedTax.d.ts
@@ -2,4 +2,5 @@ export type CalculatedTax = {
   tax: number;
   taxRate: number;
   price: number;
+  apiAlias: "cart_tax_calculated";
 };
diff --git a/packages/types/shopware-6-client/models/system/tax/Tax.d.ts b/packages/types/shopware-6-client/models/system/tax/Tax.d.ts
index 34b6bf74..b8b465ce 100644
--- a/packages/types/shopware-6-client/models/system/tax/Tax.d.ts
+++ b/packages/types/shopware-6-client/models/system/tax/Tax.d.ts
@@ -7,6 +7,12 @@ import { CustomFields } from "../../common/CustomField";
 export type Tax = {
   taxRate: number;
   name: string;
-  products: Product[] | null;
-  customFields: CustomFields;
+  products?: Product[] | null;
+  customFields: CustomFields | null;
+  translated: [];
+  createdAt: Date | string;
+  updatedAt: Date | string | null;
+  position: number;
+  id: string;
+  apiAlias: string;
 };
diff --git a/packages/types/shopware-6-client/models/system/tax/TaxRule.d.ts b/packages/types/shopware-6-client/models/system/tax/TaxRule.d.ts
index c4b4f4fc..101f7951 100644
--- a/packages/types/shopware-6-client/models/system/tax/TaxRule.d.ts
+++ b/packages/types/shopware-6-client/models/system/tax/TaxRule.d.ts
@@ -1,4 +1,5 @@
 export type TaxRule = {
   taxRate: number;
   percentage: number;
+  apiAlias: "cart_tax_rule";
 };
diff --git a/packages/types/shopware-6-client/models/system/unit/Unit.d.ts b/packages/types/shopware-6-client/models/system/unit/Unit.d.ts
index e8e666f6..aed18949 100644
--- a/packages/types/shopware-6-client/models/system/unit/Unit.d.ts
+++ b/packages/types/shopware-6-client/models/system/unit/Unit.d.ts
@@ -8,5 +8,9 @@ export type Unit = {
   shortCode: string | null;
   name: string | null;
   translated: UnitTranslation | null;
-  customFields: CustomFields;
+  customFields: CustomFields | null;
+  createdAt: Date | string;
+  updatedAt: Date | string | null;
+  id: string;
+  apiAlias: string;
 };
diff --git a/packages/types/shopware-6-client/models/system/unit/UnitTranslation.d.ts b/packages/types/shopware-6-client/models/system/unit/UnitTranslation.d.ts
index 41bd4146..e44c2c38 100644
--- a/packages/types/shopware-6-client/models/system/unit/UnitTranslation.d.ts
+++ b/packages/types/shopware-6-client/models/system/unit/UnitTranslation.d.ts
@@ -5,9 +5,9 @@ import { CustomFields } from "../../common/CustomField";
  * @public
  */
 export type UnitTranslation = {
-  unitId: string;
+  unitId?: string;
   shortCode: string | null;
   name: string | null;
-  unit: Unit | null;
+  unit?: Unit | null;
   customFields: CustomFields;
 };
diff --git a/packages/types/shopware-6-client/response/ContextUpdateResult.ts b/packages/types/shopware-6-client/response/ContextUpdateResult.ts
index c8bfdee4..2ac8c97b 100644
--- a/packages/types/shopware-6-client/response/ContextUpdateResult.ts
+++ b/packages/types/shopware-6-client/response/ContextUpdateResult.ts
@@ -4,5 +4,5 @@
 export type ContextUpdateResult = {
   apiAlias: "array_struct";
   contextToken: string;
-  redirectUrl: string;
+  redirectUrl: null | string;
 };
diff --git a/templates/vue-demo-store/app.vue b/templates/vue-demo-store/app.vue
index 0a07029a..7116a217 100644
--- a/templates/vue-demo-store/app.vue
+++ b/templates/vue-demo-store/app.vue
@@ -28,12 +28,18 @@ sessionContextData.value = await getSessionContext(apiInstance);
 //   }
 // );
 
-// read the locale from accept-language header (i.e. en-GB or de-DE)
+// read the locale/lang code from accept-language header (i.e. en, en-GB or de-DE)
 // and set configuration for price formatting globally
 const headers = useRequestHeaders();
+// Extract the first (with highest priority order) locale or lang code from accept-language header
+// for example: "en-US;q=0.7,en;q=0.3" will return "en-US"
 const localeFromHeader = headers?.["accept-language"]
   ?.split(",")
-  ?.find((languageConfig) => languageConfig.match(/([a-z]){2}\-([A-Z]{2})/));
+  ?.map(
+    (languageConfig) => languageConfig.match(/^([a-z]{2}(?:-[A-Z]{2})?)/)?.[0],
+  )
+  .find(Boolean);
+
 usePrice({
   currencyCode: sessionContextData.value?.currency?.isoCode || "",
   localeCode: localeFromHeader,
diff --git a/templates/vue-demo-store/components/account/AccountAddressCard.vue b/templates/vue-demo-store/components/account/AccountAddressCard.vue
index 25b88c4c..fb60c6cf 100644
--- a/templates/vue-demo-store/components/account/AccountAddressCard.vue
+++ b/templates/vue-demo-store/components/account/AccountAddressCard.vue
@@ -83,7 +83,7 @@ const addAddressModalController = useModal();
         @click.prevent="addAddressModalController.open"
       />
       <SharedModal :controller="addAddressModalController">
-        <AccountAddressForm
+        <SharedAccountAddressForm
           :address="address"
           :title="$t('account.editAddress')"
           @success="addAddressModalController.close"
diff --git a/templates/vue-demo-store/components/account/AccountChangePassword.vue b/templates/vue-demo-store/components/account/AccountChangePassword.vue
index 81d9dbea..7c7b8f9e 100644
--- a/templates/vue-demo-store/components/account/AccountChangePassword.vue
+++ b/templates/vue-demo-store/components/account/AccountChangePassword.vue
@@ -1,7 +1,8 @@
 <script setup lang="ts">
 import { useVuelidate } from "@vuelidate/core";
-import { required, minLength, sameAs } from "@vuelidate/validators";
+import { customValidators } from "@/i18n/utils/i18n-validators";
 
+const { required, minLength, sameAs } = customValidators();
 const emits = defineEmits<{
   (e: "success"): void;
 }>();
diff --git a/templates/vue-demo-store/components/account/AccountPersonalData.vue b/templates/vue-demo-store/components/account/AccountPersonalData.vue
index b4195929..5ed3bd64 100644
--- a/templates/vue-demo-store/components/account/AccountPersonalData.vue
+++ b/templates/vue-demo-store/components/account/AccountPersonalData.vue
@@ -1,13 +1,8 @@
 <script setup lang="ts">
 import { useVuelidate } from "@vuelidate/core";
-import {
-  required,
-  minLength,
-  email,
-  sameAs,
-  requiredIf,
-} from "@vuelidate/validators";
 import { ClientApiError } from "@shopware-pwa/types";
+import { customValidators } from "@/i18n/utils/i18n-validators";
+const { required, minLength, requiredIf, email, sameAs } = customValidators();
 
 const { user, refreshUser, updatePersonalInfo, updateEmail } = useUser();
 
diff --git a/templates/vue-demo-store/components/account/AccountRegisterForm.vue b/templates/vue-demo-store/components/account/AccountRegisterForm.vue
index f36b941d..3bdb3ce0 100644
--- a/templates/vue-demo-store/components/account/AccountRegisterForm.vue
+++ b/templates/vue-demo-store/components/account/AccountRegisterForm.vue
@@ -1,14 +1,15 @@
 <script setup lang="ts">
 import { useVuelidate } from "@vuelidate/core";
-import { required, email, minLength, requiredIf } from "@vuelidate/validators";
 import { ClientApiError } from "@shopware-pwa/types";
+import { customValidators } from "@/i18n/utils/i18n-validators";
 
+const { required, minLength, email } = customValidators();
 const props = defineProps<{
   customerGroupId?: string;
 }>();
 
 const { getSalutations } = useSalutations();
-const { getStatesForCountry } = useCountries();
+const { getCountries } = useCountries();
 const { register, isLoggedIn } = useUser();
 const { pushError } = useNotifications();
 
@@ -40,7 +41,6 @@ const initialState = {
     zipcode: "",
     city: "",
     countryId: "",
-    countryStateId: "",
   },
 };
 
@@ -80,11 +80,6 @@ const rules = computed(() => ({
     countryId: {
       required,
     },
-    countryStateId: {
-      required: requiredIf(() => {
-        return !!getStatesForCountry(state.billingAddress.countryId)?.length;
-      }),
-    },
   },
 }));
 
@@ -361,13 +356,40 @@ useBreadcrumbs([
           </span>
         </div>
 
-        <SharedCountryStateInput
-          v-model:countryId="state.billingAddress.countryId"
-          v-model:stateId="state.billingAddress.countryStateId"
-          :country-id-validation="$v.billingAddress.countryId"
-          :state-id-validation="$v.billingAddress.countryStateId"
-          class="col-span-12 md:col-span-4"
-        />
+        <div class="col-span-12 md:col-span-4">
+          <label for="country">{{ $t("form.country") }} *</label>
+          <select
+            id="country"
+            v-model="state.billingAddress.countryId"
+            name="country"
+            class="appearance-none relative block w-full px-3 py-2 border placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-indigo-500 focus:z-10 sm:text-sm"
+            :class="[
+              $v.billingAddress.countryId.$error
+                ? 'border-red-600 focus:border-red-600'
+                : 'border-gray-300 focus:border-indigo-500',
+            ]"
+            :disabled="loading"
+            data-testid="registration-country-select"
+            @blur="$v.billingAddress.countryId.$touch()"
+          >
+            <option disabled selected value="">
+              {{ $t("form.chooseCountry") }}
+            </option>
+            <option
+              v-for="country in getCountries"
+              :key="country.id"
+              :value="country.id"
+            >
+              {{ country.name }}
+            </option>
+          </select>
+          <span
+            v-if="$v.salutationId.$error"
+            class="pt-1 text-sm text-red-600 focus:ring-brand-primary border-gray-300"
+          >
+            {{ $v.salutationId.$errors[0].$message }}
+          </span>
+        </div>
       </div>
       <div class="mb-5 text-right">
         <button
diff --git a/templates/vue-demo-store/components/account/AccountResetPasswordForm.vue b/templates/vue-demo-store/components/account/AccountResetPasswordForm.vue
index a75746fc..c23212ff 100644
--- a/templates/vue-demo-store/components/account/AccountResetPasswordForm.vue
+++ b/templates/vue-demo-store/components/account/AccountResetPasswordForm.vue
@@ -1,9 +1,10 @@
 <script setup lang="ts">
 import { useVuelidate } from "@vuelidate/core";
-import { required, minLength, sameAs } from "@vuelidate/validators";
 import { confirmPasswordReset } from "@shopware-pwa/api-client";
 import { ClientApiError } from "@shopware-pwa/types";
+import { customValidators } from "@/i18n/utils/i18n-validators";
 
+const { required, minLength, sameAs } = customValidators();
 const { apiInstance } = useShopwareContext();
 
 const state = reactive({
diff --git a/templates/vue-demo-store/components/shared/SharedAccountAddressForm.vue b/templates/vue-demo-store/components/shared/SharedAccountAddressForm.vue
new file mode 100644
index 00000000..3abbedf0
--- /dev/null
+++ b/templates/vue-demo-store/components/shared/SharedAccountAddressForm.vue
@@ -0,0 +1,295 @@
+<script setup lang="ts">
+import {
+  CustomerAddress,
+  ClientApiError,
+  ShopwareError,
+} from "@shopware-pwa/types";
+import { useVuelidate } from "@vuelidate/core";
+import { customValidators } from "@/i18n/utils/i18n-validators";
+
+const { required, minLength, requiredIf } = customValidators();
+
+const { createCustomerAddress, updateCustomerAddress, errorMessageBuilder } =
+  useAddress();
+const { getStatesForCountry } = useCountries();
+
+const emits = defineEmits<{
+  (e: "success"): void;
+  (e: "close"): void;
+}>();
+
+const props = withDefaults(
+  defineProps<{
+    address?: CustomerAddress;
+    title?: string;
+  }>(),
+  {
+    title: "Account address",
+    address: undefined,
+  },
+);
+
+const { getSalutations } = useSalutations();
+const { t } = useI18n();
+const { pushError } = useNotifications();
+
+const formData = reactive({
+  countryId: props.address?.countryId ?? "",
+  countryStateId: props.address?.countryStateId ?? "",
+  salutationId: props.address?.salutationId ?? "",
+  firstName: props.address?.firstName ?? "",
+  lastName: props.address?.lastName ?? "",
+  zipcode: props.address?.zipcode ?? "",
+  city: props.address?.city ?? "",
+  street: props.address?.street ?? "",
+  id: props.address?.id ?? "",
+});
+
+const invokeSave = async (): Promise<void> => {
+  try {
+    const saveAddress = formData.id
+      ? updateCustomerAddress
+      : createCustomerAddress;
+
+    $v.value.$touch();
+    const valid = await $v.value.$validate();
+    if (valid) {
+      await saveAddress(formData);
+      emits("success");
+    }
+  } catch (errors) {
+    (errors as ClientApiError).messages.forEach((element: ShopwareError) => {
+      pushError(errorMessageBuilder(element) || t("messages.error"));
+    });
+  }
+};
+
+const firstNameInputElement = ref();
+useFocus(firstNameInputElement, { initialValue: true });
+
+const rules = computed(() => ({
+  salutationId: {
+    required,
+  },
+  firstName: {
+    required,
+    minLength: minLength(3),
+  },
+  lastName: {
+    required,
+    minLength: minLength(3),
+  },
+  zipcode: {
+    required,
+  },
+  street: {
+    required,
+    minLength: minLength(3),
+  },
+  city: {
+    required,
+  },
+  countryId: {
+    required,
+  },
+  countryStateId: {
+    required: requiredIf(() => {
+      return !!getStatesForCountry(formData.countryId)?.length;
+    }),
+  },
+}));
+
+const $v = useVuelidate(rules, formData);
+</script>
+
+<template>
+  <div class="mt-5 md:mt-0 md:col-span-2">
+    <div class="shadow overflow-hidden sm:rounded-md">
+      <form
+        id="account-address"
+        ref="formElement"
+        name="account-address"
+        method="post"
+      >
+        <div class="px-4 py-5 bg-white sm:p-6">
+          <h3 class="text-2xl border-b pb-3">
+            {{ props.title }}
+          </h3>
+          <div class="grid grid-cols-6 gap-6 mt-8">
+            <div class="col-span-6 sm:col-span-6">
+              <label
+                for="country"
+                class="block mb-2 text-sm font-medium text-gray-500"
+              >
+                {{ $t("form.salutation") }}
+              </label>
+              <select
+                id="salutation"
+                v-model="formData.salutationId"
+                required
+                name="salutation"
+                autocomplete="salutation-name"
+                class="mt-1 block w-full py-2.5 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-brand-light focus:border-brand-light sm:text-sm"
+                data-testid="account-address-form-salutation-select"
+              >
+                <option
+                  v-for="salutation in getSalutations"
+                  :key="salutation.id"
+                  :value="salutation.id"
+                  data-testid="account-address-form-salutation-select-option"
+                >
+                  {{ salutation.displayName }}
+                </option>
+              </select>
+              <span
+                v-if="$v.salutationId.$error"
+                class="pt-1 text-sm text-red-600 focus:ring-brand-primary border-gray-300"
+              >
+                {{ $v.salutationId.$errors[0].$message }}
+              </span>
+            </div>
+            <div class="col-span-6 sm:col-span-3">
+              <label
+                for="first-name"
+                class="block mb-2 text-sm font-medium text-gray-500"
+              >
+                {{ $t("form.firstName") }}
+              </label>
+              <input
+                id="first-name"
+                ref="firstNameInputElement"
+                v-model="formData.firstName"
+                type="text"
+                required
+                name="first-name"
+                class="mt-1 block w-full p-2.5 border border-gray-300 text-gray-900 text-sm rounded-md shadow-sm focus:ring-brand-light focus:border-brand-light"
+                data-testid="account-address-form-firstname-input"
+              />
+              <span
+                v-if="$v.firstName.$error"
+                class="pt-1 text-sm text-red-600 focus:ring-brand-primary border-gray-300"
+              >
+                {{ $v.firstName.$errors[0].$message }}
+              </span>
+            </div>
+
+            <div class="col-span-6 sm:col-span-3">
+              <label
+                for="last-name"
+                class="block mb-2 text-sm font-medium text-gray-500"
+              >
+                {{ $t("form.lastName") }}
+              </label>
+              <input
+                id="last-name"
+                v-model="formData.lastName"
+                type="text"
+                required
+                name="last-name"
+                class="mt-1 block w-full p-2.5 border border-gray-300 text-gray-900 text-sm rounded-md shadow-sm focus:ring-brand-light focus:border-brand-light"
+                data-testid="account-address-form-lastname-input"
+              />
+              <span
+                v-if="$v.lastName.$error"
+                class="pt-1 text-sm text-red-600 focus:ring-brand-primary border-gray-300"
+              >
+                {{ $v.lastName.$errors[0].$message }}
+              </span>
+            </div>
+
+            <SharedCountryStateInput
+              v-model:countryId="formData.countryId"
+              v-model:stateId="formData.countryStateId"
+              :country-id-validation="$v.countryId"
+              :state-id-validation="$v.countryStateId"
+              class="col-span-6 sm:col-span-6"
+            />
+            <div class="col-span-6">
+              <label
+                for="street-address"
+                class="block mb-2 text-sm font-medium text-gray-500"
+              >
+                {{ $t("form.streetAddress") }}
+              </label>
+              <input
+                id="street-address"
+                v-model="formData.street"
+                type="text"
+                required
+                name="street-address"
+                autocomplete="street-address"
+                class="mt-1 block w-full p-2.5 border border-gray-300 text-gray-900 text-sm rounded-md shadow-sm focus:ring-brand-light focus:border-brand-light"
+                data-testid="account-address-form-street-input"
+              />
+              <span
+                v-if="$v.street.$error"
+                class="pt-1 text-sm text-red-600 focus:ring-brand-primary border-gray-300"
+              >
+                {{ $v.street.$errors[0].$message }}
+              </span>
+            </div>
+
+            <div class="col-span-6 sm:col-span-6 lg:col-span-4">
+              <label
+                for="city"
+                class="block mb-2 text-sm font-medium text-gray-500"
+              >
+                {{ $t("form.city") }}
+              </label>
+              <input
+                id="city"
+                v-model="formData.city"
+                type="text"
+                required
+                name="city"
+                autocomplete="address-level2"
+                class="mt-1 block w-full p-2.5 border border-gray-300 text-gray-900 text-sm rounded-md shadow-sm focus:ring-brand-light focus:border-brand-light"
+                data-testid="account-address-form-city-input"
+              />
+              <span
+                v-if="$v.city.$error"
+                class="pt-1 text-sm text-red-600 focus:ring-brand-primary border-gray-300"
+              >
+                {{ $v.city.$errors[0].$message }}
+              </span>
+            </div>
+            <div class="col-span-6 sm:col-span-3 lg:col-span-2">
+              <label
+                for="postal-code"
+                class="block mb-2 text-sm font-medium text-gray-500"
+              >
+                {{ $t("form.postalCode") }}
+              </label>
+              <input
+                id="postal-code"
+                v-model="formData.zipcode"
+                type="text"
+                required
+                name="postal-code"
+                autocomplete="postal-code"
+                class="mt-1 block w-full p-2.5 border border-gray-300 text-gray-900 text-sm rounded-md shadow-sm focus:ring-brand-light focus:border-brand-light"
+                data-testid="account-address-form-postal-code-input"
+              />
+              <span
+                v-if="$v.zipcode.$error"
+                class="pt-1 text-sm text-red-600 focus:ring-brand-primary border-gray-300"
+              >
+                {{ $v.zipcode.$errors[0].$message }}
+              </span>
+            </div>
+          </div>
+        </div>
+        <div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
+          <button
+            type="submit"
+            class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-brand-primary hover:bg-brand-dark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-brand-light"
+            data-testid="account-address-form-submit-button"
+            @click.stop.prevent="invokeSave"
+          >
+            {{ $t("form.save") }}
+          </button>
+        </div>
+      </form>
+    </div>
+  </div>
+</template>
diff --git a/templates/vue-demo-store/i18n/de-DE/de-DE.ts b/templates/vue-demo-store/i18n/de-DE/de-DE.ts
index 46f3c756..4eadfc66 100644
--- a/templates/vue-demo-store/i18n/de-DE/de-DE.ts
+++ b/templates/vue-demo-store/i18n/de-DE/de-DE.ts
@@ -8,6 +8,7 @@ import cart from "./cart.json";
 import listing from "./listing.json";
 import product from "./product.json";
 import newsletter from "./newsletter.json";
+import validations from "./validations.json";
 
 export default Object.assign(
   account,
@@ -20,4 +21,5 @@ export default Object.assign(
   listing,
   product,
   newsletter,
+  validations,
 );
diff --git a/templates/vue-demo-store/i18n/de-DE/validations.json b/templates/vue-demo-store/i18n/de-DE/validations.json
new file mode 100644
index 00000000..f7d593ca
--- /dev/null
+++ b/templates/vue-demo-store/i18n/de-DE/validations.json
@@ -0,0 +1,24 @@
+
+{
+  "validations": {
+    "alpha": "Der Wert ist nicht alphabetisch",
+    "alphaNum": "Der Wert muss alphanumerisch sein",
+    "between": "Der Wert muss zwischen {min} und {max} liegen",
+    "decimal": "Der Wert muss dezimal sein",
+    "email": "Der Wert ist keine gültige E-Mail-Adresse",
+    "integer": "Der Wert ist keine ganze Zahl",
+    "ipAddress": "Der Wert ist keine gültige IP-Adresse",
+    "macAddress": "Der Wert ist keine gültige MAC-Adresse",
+    "maxLength": "Die maximale Länge beträgt {max}",
+    "minLength": "Mindestlänge {min}",
+    "minValue": "Der kleinste erlaubte Wert ist {min}",
+    "not": "Der Wert entspricht dem angegebenen Validierer nicht",
+    "numeric": "Der Wert muss numerisch sein",
+    "or": "Der Wert entspricht keinem der angegebenen Validierer",
+    "required": "Der Wert ist erforderlich",
+    "requiredIf": "Der Wert ist erforderlich",
+    "requiredUnless": "Der Wert ist erforderlich",
+    "sameAs": "Der Wert muss dem Wert {otherName} entsprechen",
+    "url": "Der Wert ist keine gültige URL-Adresse"
+  }
+}
diff --git a/templates/vue-demo-store/i18n/en-GB/en-GB.ts b/templates/vue-demo-store/i18n/en-GB/en-GB.ts
index 46f3c756..4eadfc66 100644
--- a/templates/vue-demo-store/i18n/en-GB/en-GB.ts
+++ b/templates/vue-demo-store/i18n/en-GB/en-GB.ts
@@ -8,6 +8,7 @@ import cart from "./cart.json";
 import listing from "./listing.json";
 import product from "./product.json";
 import newsletter from "./newsletter.json";
+import validations from "./validations.json";
 
 export default Object.assign(
   account,
@@ -20,4 +21,5 @@ export default Object.assign(
   listing,
   product,
   newsletter,
+  validations,
 );
diff --git a/templates/vue-demo-store/i18n/en-GB/validations.json b/templates/vue-demo-store/i18n/en-GB/validations.json
new file mode 100644
index 00000000..bc023962
--- /dev/null
+++ b/templates/vue-demo-store/i18n/en-GB/validations.json
@@ -0,0 +1,23 @@
+{
+  "validations": {
+    "alpha": "The value is not alphabetical",
+    "alphaNum": "The value must be alpha-numeric",
+    "between": "The value must be between {min} and {max}",
+    "decimal": "Value must be decimal",
+    "email": "Value is not a valid email address",
+    "integer": "Value is not an integer",
+    "ipAddress": "The value is not a valid IP address",
+    "macAddress": "The value is not a valid MAC Address",
+    "maxLength": "The maximum length allowed is {max}",
+    "minLength": "This minimum length should be at least {min}",
+    "minValue": "The minimum value allowed is {min}",
+    "not": "The value does not match the provided validator",
+    "numeric": "Value must be numeric",
+    "or": "The value does not match any of the provided validators",
+    "required": "Value is required",
+    "requiredIf": "The value is required",
+    "requiredUnless": "The value is required",
+    "sameAs": "The value must be equal to the {otherName} value",
+    "url": "The value is not a valid URL address"
+  }
+}
diff --git a/templates/vue-demo-store/i18n/pl-PL/pl-PL.ts b/templates/vue-demo-store/i18n/pl-PL/pl-PL.ts
index 7a92b29e..f05737cc 100644
--- a/templates/vue-demo-store/i18n/pl-PL/pl-PL.ts
+++ b/templates/vue-demo-store/i18n/pl-PL/pl-PL.ts
@@ -8,6 +8,7 @@ import cart from "../pl-PL/cart.json";
 import listing from "../pl-PL/listing.json";
 import product from "../pl-PL/product.json";
 import newsletter from "../pl-PL/newsletter.json";
+import validations from "../pl-PL/validations.json";
 
 export default Object.assign(
   account,
@@ -20,4 +21,5 @@ export default Object.assign(
   listing,
   product,
   newsletter,
+  validations,
 );
diff --git a/templates/vue-demo-store/i18n/pl-PL/validations.json b/templates/vue-demo-store/i18n/pl-PL/validations.json
new file mode 100644
index 00000000..310996d4
--- /dev/null
+++ b/templates/vue-demo-store/i18n/pl-PL/validations.json
@@ -0,0 +1,23 @@
+{
+  "validations": {
+    "alpha": "Wartość nie jest alfabetyczna",
+    "alphaNum": "Wartość musi być alfanumeryczna",
+    "between": "Wartość musi być między {min} a {max}",
+    "decimal": "Wartość musi być dziesiętna",
+    "email": "Wartość nie jest prawidłowym adresem e-mail",
+    "integer": "Wartość nie jest liczbą całkowitą",
+    "ipAddress": "Wartość nie jest prawidłowym adresem IP",
+    "macAddress": "Wartość nie jest prawidłowym adresem MAC",
+    "maxLength": "Maksymalna dozwolona długość to {max}",
+    "minLength": "Minimalna długość {min}",
+    "minValue": "Minimalna dozwolona wartość to {min}",
+    "not": "Wartość nie pasuje do podanego walidatora",
+    "numeric": "Wartość musi być numeryczna",
+    "or": "Wartość nie pasuje do żadnego z podanych walidatorów",
+    "required": "Wartość jest wymagana",
+    "requiredIf": "Wartość jest wymagana",
+    "requiredUnless": "Wartość jest wymagana",
+    "sameAs": "Wartość musi być równa wartości {otherName}",
+    "url": "Wartość nie jest prawidłowym adresem URL"
+  }
+}
diff --git a/templates/vue-demo-store/i18n/utils/i18n-validators.ts b/templates/vue-demo-store/i18n/utils/i18n-validators.ts
new file mode 100644
index 00000000..dc42bbf2
--- /dev/null
+++ b/templates/vue-demo-store/i18n/utils/i18n-validators.ts
@@ -0,0 +1,31 @@
+import * as validators from "@vuelidate/validators";
+
+export const customValidators = () => {
+  const { $i18n } = useNuxtApp();
+  const { createI18nMessage } = validators;
+  const withI18nMessage = createI18nMessage({ t: $i18n.t.bind($i18n) });
+
+  return {
+    alpha: withI18nMessage(validators.alpha),
+    alphaNum: withI18nMessage(validators.alphaNum),
+    between: withI18nMessage(validators.between, { withArguments: true }),
+    decimal: withI18nMessage(validators.decimal),
+    email: withI18nMessage(validators.email),
+    integer: withI18nMessage(validators.integer),
+    ipAddress: withI18nMessage(validators.ipAddress),
+    macAddress: withI18nMessage(validators.macAddress),
+    maxLength: withI18nMessage(validators.maxLength, { withArguments: true }),
+    minLength: withI18nMessage(validators.minLength, { withArguments: true }),
+    minValue: withI18nMessage(validators.minValue, { withArguments: true }),
+    not: withI18nMessage(validators.not, { withArguments: true }),
+    numeric: withI18nMessage(validators.numeric),
+    or: withI18nMessage(validators.or, { withArguments: true }),
+    required: withI18nMessage(validators.required),
+    requiredIf: withI18nMessage(validators.requiredIf, { withArguments: true }),
+    requiredUnless: withI18nMessage(validators.requiredUnless, {
+      withArguments: true,
+    }),
+    sameAs: withI18nMessage(validators.sameAs, { withArguments: true }),
+    url: withI18nMessage(validators.url),
+  };
+};
diff --git a/templates/vue-demo-store/pages/account/address.vue b/templates/vue-demo-store/pages/account/address.vue
index ea2671f1..ef3fc1d6 100644
--- a/templates/vue-demo-store/pages/account/address.vue
+++ b/templates/vue-demo-store/pages/account/address.vue
@@ -72,7 +72,7 @@ onBeforeMount(async () => {
       {{ $t("account.addressAddNew") }}
     </button>
     <SharedModal :controller="addAddressModalController">
-      <AccountAddressForm @success="addAddressModalController.close" />
+      <SharedAccountAddressForm @success="addAddressModalController.close" />
     </SharedModal>
   </div>
 </template>
diff --git a/templates/vue-demo-store/pages/checkout/index.vue b/templates/vue-demo-store/pages/checkout/index.vue
index 379a66b5..a1c28921 100644
--- a/templates/vue-demo-store/pages/checkout/index.vue
+++ b/templates/vue-demo-store/pages/checkout/index.vue
@@ -5,9 +5,11 @@ export default {
 </script>
 <script setup lang="ts">
 import { useVuelidate } from "@vuelidate/core";
-import { required, email, minLength, requiredIf } from "@vuelidate/validators";
 import { ClientApiError, ShopwareError } from "@shopware-pwa/types";
 import { getShippingMethodDeliveryTime } from "@shopware-pwa/helpers-next";
+import { customValidators } from "@/i18n/utils/i18n-validators";
+
+const { required, minLength, requiredIf, email } = customValidators();
 
 definePageMeta({
   layout: "checkout",
@@ -257,7 +259,7 @@ const addAddressModalController = useModal();
       />
     </SharedModal>
     <SharedModal :controller="addAddressModalController">
-      <AccountAddressForm @success="addAddressModalController.close" />
+      <SharedAccountAddressForm @success="addAddressModalController.close" />
     </SharedModal>
     <div
       v-if="isCheckoutAvailable || isCartLoading"


Test patch:
diff --git a/apps/e2e-tests/playwright.config.ts b/apps/e2e-tests/playwright.config.ts
index 32c71ef1..42fe86da 100644
--- a/apps/e2e-tests/playwright.config.ts
+++ b/apps/e2e-tests/playwright.config.ts
@@ -56,14 +56,14 @@ const config: PlaywrightTestConfig = {
   /* Configure projects for major browsers */
   projects: [
     {
-      name: "Desktop Chrome",
+      name: "chromium",
       use: {
         ...devices["Desktop Chrome"],
       },
     },
 
     // {
-    //   name: "Desktop Firefox",
+    //   name: "firefox",
     //   use: {
     //     ...devices["Desktop Firefox"],
     //   },
diff --git a/apps/e2e-tests/tests/checkCodeExamples.spec.ts b/apps/e2e-tests/tests/checkCodeExamples.spec.ts
index c94379b5..f762ede3 100644
--- a/apps/e2e-tests/tests/checkCodeExamples.spec.ts
+++ b/apps/e2e-tests/tests/checkCodeExamples.spec.ts
@@ -5,6 +5,7 @@ import path from "path";
 const directoryPath = path.join(__dirname, "../../../examples/");
 
 fs.readdirSync(directoryPath).forEach((file) => {
+  test.setTimeout(90000);
   test(`Verify ${file}`, async ({ page }) => {
     const response = await page.goto(
       `https://stackblitz.com/github/shopware/frontends/tree/main/examples/${file}?embed=1&theme=light&ctl=1&initialPath=%2F&view=preview`,
diff --git a/apps/e2e-tests/tests/checkStackblitzTemplates.spec.ts b/apps/e2e-tests/tests/checkStackblitzTemplates.spec.ts
index b730784c..2ccc5b53 100644
--- a/apps/e2e-tests/tests/checkStackblitzTemplates.spec.ts
+++ b/apps/e2e-tests/tests/checkStackblitzTemplates.spec.ts
@@ -2,6 +2,7 @@ import { test, expect } from "@playwright/test";
 import { HomePage } from "../page-objects/HomePage";
 
 test("Verify stackblitz template", async ({ page }) => {
+  test.setTimeout(120000);
   let homePage: HomePage;
   const response = await page.goto("");
   homePage = new HomePage(page);