diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 5894b3113..211601d10 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -16,3 +16,37 @@ jobs:
branch: gh-pages
folder: redirect
clean: true
+
+ create-docs-admin-sdk:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout the repository
+ uses: actions/checkout@v2
+
+ - uses: pnpm/action-setup@v2
+ with:
+ version: 8
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile --prefer-offline
+
+ - name: Test to see if the project compiles
+ run: pnpm --filter @shopware-ag/meteor-admin-sdk run lint:all
+
+ - name: Create the docs directory locally in CI
+ run: |
+ cd packages/admin-sdk
+ pnpm run doc:install-dependencies
+ pnpm run doc
+
+ - name: Deploy ð
+ if: github.ref == 'refs/heads/trunk'
+ uses: JamesIves/github-pages-deploy-action@4.1.4
+ with:
+ branch: gh-pages
+ folder: packages/admin-sdk/docs/build
diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml
index 2d74e8196..5d1cf04f0 100644
--- a/.github/workflows/preview.yml
+++ b/.github/workflows/preview.yml
@@ -27,7 +27,7 @@ jobs:
node-version: '20'
- name: Install main dependencies
- run: pnpm install
+ run: pnpm install --frozen-lockfile --prefer-offline
- name: Create the static pages directory locally in CI
run: pnpm --prefix ./packages/component-library run build-storybook
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index b69e35290..fd4675405 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -61,7 +61,68 @@ jobs:
node-version: '20'
- name: Install dependencies
- run: pnpm install
+ run: pnpm install --frozen-lockfile --prefer-offline
- name: unit
run: pnpm run test:unit
+
+ circular-dependencies:
+ name: Check for circular dependencies (Madge)
+ runs-on: ubuntu-latest
+ env:
+ TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
+ TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - uses: pnpm/action-setup@v2
+ with:
+ version: 8
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile --prefer-offline
+
+ - name: madge
+ run: pnpm --filter @shopware-ag/meteor-admin-sdk run circular-dependencies
+
+ playwright-run:
+ name: Playwright Integration Tests
+ timeout-minutes: 20
+ runs-on: ubuntu-latest
+ needs:
+ - circular-dependencies
+ - unit-tests
+ - static-analysis
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - uses: pnpm/action-setup@v2
+ with:
+ version: 8
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile --prefer-offline
+
+ - name: Install Playwright
+ run: npx playwright install
+
+ - name: Run Playwright tests
+ run: pnpm --filter @shopware-ag/meteor-admin-sdk run test:e2e
+
+ - uses: actions/upload-artifact@v2
+ if: always()
+ with:
+ name: meteor-admin-sdk--playwright-test-results
+ path: packages/admin-sdk/playwright-report/
diff --git a/.github/workflows/update-icons.yml b/.github/workflows/update-icons.yml
index 0634f3c63..18ed850b1 100644
--- a/.github/workflows/update-icons.yml
+++ b/.github/workflows/update-icons.yml
@@ -25,7 +25,7 @@ jobs:
node-version: '20'
- name: Install dependencies
- run: pnpm install
+ run: pnpm install --frozen-lockfile --prefer-offline
- name: Build
run: pnpm --prefix ./packages/icon-kit run build
diff --git a/.github/workflows/visual-tests.yml b/.github/workflows/visual-tests.yml
index 4c77bf535..47fee067d 100644
--- a/.github/workflows/visual-tests.yml
+++ b/.github/workflows/visual-tests.yml
@@ -29,7 +29,7 @@ jobs:
node-version: '20'
- name: Install dependencies
- run: pnpm install
+ run: pnpm install --frozen-lockfile --prefer-offline
- name: Install Playwright
run: pnpm dlx playwright install
diff --git a/package.json b/package.json
index 9cce88c30..04e707f68 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,8 @@
"lint:eslint": "turbo run lint:eslint",
"format": "turbo run format",
"format:check": "turbo run format:check",
- "test:unit": "turbo run test:unit"
+ "test:unit": "turbo run test:unit",
+ "test:e2e": "turbo run test:e2e"
},
"keywords": [],
"license": "MIT",
diff --git a/packages/admin-sdk/.envrc b/packages/admin-sdk/.envrc
new file mode 100644
index 000000000..5dae8de00
--- /dev/null
+++ b/packages/admin-sdk/.envrc
@@ -0,0 +1,4 @@
+watch_file devenv.nix
+watch_file devenv.yaml
+watch_file devenv.lock
+eval "$(devenv print-dev-env)"
\ No newline at end of file
diff --git a/packages/admin-sdk/.eslintignore b/packages/admin-sdk/.eslintignore
new file mode 100644
index 000000000..f5c2b1fca
--- /dev/null
+++ b/packages/admin-sdk/.eslintignore
@@ -0,0 +1,11 @@
+node_modules
+dist
+es
+umd
+example-dist
+docs
+example
+coverage
+cypress
+*.spec.ts
+e2e
\ No newline at end of file
diff --git a/packages/admin-sdk/.eslintrc.js b/packages/admin-sdk/.eslintrc.js
new file mode 100644
index 000000000..82208d8a2
--- /dev/null
+++ b/packages/admin-sdk/.eslintrc.js
@@ -0,0 +1,80 @@
+module.exports = {
+ root: true,
+ parser: '@typescript-eslint/parser',
+ parserOptions: {
+ tsconfigRootDir: __dirname,
+ project: ['./tsconfig.json'],
+ },
+ plugins: [
+ '@typescript-eslint',
+ 'import',
+ ],
+ extends: [
+ 'eslint:recommended',
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:@typescript-eslint/recommended-requiring-type-checking',
+ ],
+ rules: {
+ 'no-prototype-builtins': 'off',
+ 'comma-dangle': 'off',
+ 'no-irregular-whitespace': 'error',
+ 'no-multiple-empty-lines': ['error', { max: 1}],
+ '@typescript-eslint/comma-dangle': ['error', 'always-multiline'],
+ '@typescript-eslint/explicit-function-return-type': ['error'],
+ '@typescript-eslint/consistent-type-imports': ['error'],
+ '@typescript-eslint/member-delimiter-style': ['error', {
+ multiline: {
+ delimiter: 'comma',
+ requireLast: true,
+ },
+ singleline: {
+ delimiter: 'comma',
+ requireLast: false,
+ },
+ }],
+ 'capitalized-comments': [
+ 'error',
+ 'always',
+ {
+ 'ignorePattern': 'pragma|ignored',
+ 'ignoreInlineComments': true,
+ },
+ ],
+ semi: [
+ 'error',
+ 'always',
+ ],
+ 'no-console': [
+ 'error',
+ {
+ allow: [
+ 'warn',
+ 'error',
+ ],
+ },
+ ],
+ 'indent': [
+ 'error',
+ 2,
+ ],
+ 'no-debugger': 'error',
+ 'no-unreachable': 'error',
+ 'consistent-return': 'error',
+ camelcase: 'error',
+ curly: 'error',
+ eqeqeq: 'error',
+ 'multiline-comment-style': [
+ 'error',
+ 'starred-block',
+ ],
+ 'no-iterator': 'error',
+ 'import/no-cycle': [
+ 2,
+ {
+ maxDepth: 1,
+ },
+ ],
+ quotes: ['error', 'single'],
+ 'eol-last': ['error', 'always'],
+ },
+};
diff --git a/packages/admin-sdk/.gitignore b/packages/admin-sdk/.gitignore
new file mode 100644
index 000000000..b36bd238d
--- /dev/null
+++ b/packages/admin-sdk/.gitignore
@@ -0,0 +1,23 @@
+node_modules
+.DS_Store
+dist
+dist-ssr
+dist-example
+*.local
+.idea
+coverage
+docs/docs/api
+es
+umd
+example-dist
+cdn
+test-results/
+playwright-test-results/
+playwright-report/
+testpageDist
+dependency-graph.png
+.vscode
+# Devenv
+.devenv*
+devenv.local.nix
+
diff --git a/packages/admin-sdk/.madgerc b/packages/admin-sdk/.madgerc
new file mode 100644
index 000000000..60cfac040
--- /dev/null
+++ b/packages/admin-sdk/.madgerc
@@ -0,0 +1,13 @@
+{
+ "detectiveOptions": {
+ "ts": {
+ "skipTypeImports": true
+ }
+ },
+ "baseDir": "./src",
+ "fileExtensions": [
+ "ts",
+ "js"
+ ],
+ "tsConfig": "tsconfig.json"
+}
\ No newline at end of file
diff --git a/packages/admin-sdk/.nvmrc b/packages/admin-sdk/.nvmrc
new file mode 100644
index 000000000..53d838af2
--- /dev/null
+++ b/packages/admin-sdk/.nvmrc
@@ -0,0 +1 @@
+lts/gallium
diff --git a/packages/admin-sdk/CHANGELOG.md b/packages/admin-sdk/CHANGELOG.md
new file mode 100644
index 000000000..4870e3118
--- /dev/null
+++ b/packages/admin-sdk/CHANGELOG.md
@@ -0,0 +1,138 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+## [4.0.0] - 07.02.2024
+
+## Changed
+- Changed this version is not compatible with the previous versions
+
+## Fixed
+- Fixed an issue with circular references in json structures causing pages to freeze
+
+## [3.0.17] - 19.01.2024
+
+## Added
+- Added `showFooter` to `ui.modal` to allow toggling the modal footer
+
+## [3.0.15] - 09.10.2023
+
+## Changed
+- Changed `handle` of `channel.ts` to only validate dataset collections and entities
+
+## [3.0.13] - 21.07.2023
+
+## Fixed
+- Fixed invalid URL type error
+
+## [3.0.12] - 21.07.2023
+
+## Fixed
+- Fixed permission handling for plugin usage with same origin
+
+## [3.0.11] - 20.07.2023
+
+## Fixed
+- Fixed permission handling for `data.get` and `data.subscribe`
+
+### Added
+
+- Added `selectors` to `data.get` and `data.subscribe` to allow extension developer to reduce the payload and minimize the needed privileges
+
+## [3.0.10] - 06.06.2023
+
+### Added
+
+- Added `location.updateUrl`, `location.startAutoUrlUpdater` and `location.stopAutoUrlUpdater` to allow extension developer to update the URL of the iframe so that even after reload the correct sub-route inside the iFrame gets opened
+
+## [3.0.9] - 01.06.2023
+
+### Added
+
+- Added `composables.useSharedState` for maintaining persistent, shared state across several iFrames and windows
+
+## [3.0.7] - 25.05.2023
+
+### Added
+
+- Added `context.getUserInformation` to allow extension developer to get access to the current user
+
+## [3.0.6] - 24.05.2023
+
+### Bugfix
+
+- Fixed the serialization of Entities and EntityCollections with reactive Vue objects which previously could lead to errors like e.g. "*.has is not a function"
+
+## [3.0.4] - 03.02.2023
+
+### Changed
+
+- Added language switch and smart bar buttons into main module.
+- Added `tabs` prop to component section to provide the ability to use tabs inside a card.
+
+## [3.0.3] - 25.01.2023
+- Added the method `location.get` for getting the actual location ID inside the app
+
+## [3.0.2] - 05.01.2023
+
+### Bugfix
+
+- Added two placeholder entities to the global `EntitySchema.Entities` types.
+ This avoids the automatic conversion of an empty interface to the type `never`
+
+## [3.0.1] - 29.12.2022
+
+### Changed
+
+- Improved general performance of the channel communication by improving the early return method for stopping the execution
+
+## [3.0.0] - 23.12.2022
+
+### Added
+
+- Added type safety to all repository methods and the general data handling.
+
+### Breaking Changes
+
+- Removed the `any` type as a return value from the `repository` methods
+
+### Upgrade Guide
+
+You can get back the original behavior by adding the `any` type to the global `Entities` interface. You can
+see the guide in Getting started â Installation â Adding types for Entities (TS only) â Using "any" fallback.
+
+An additional package with auto-generated types will be released soon.
+
+## [2.3.0] - 27.06.2022
+
+### Added
+
+- Added `ui.paymentOverviewCard`
+
+## [2.1.0] - 20.05.2022
+
+### Added
+
+- Added `context.getModuleInformation`
+- Added `window.routerPush`
+
+## [2.0.0] - 16.05.2022
+
+### Changed
+
+- Changed `data.get` to `data.subscribe`
+
+### Added
+
+- Added `data.get`
+- Added `data.handleGet`
+
+## [1.0.0] - 12.05.2022
+
+### Changed
+
+- Changed default constructor values of Criteria.
+
+### Added
+
+- Added `setDefaultValues` function to Criteria.
diff --git a/packages/admin-sdk/README.md b/packages/admin-sdk/README.md
new file mode 100644
index 000000000..fb6dbd9c5
--- /dev/null
+++ b/packages/admin-sdk/README.md
@@ -0,0 +1,78 @@
+# meteor-admin-sdk
+[![Tests](https://github.com/shopware/meteor-admin-sdk/actions/workflows/tests.yml/badge.svg)](https://github.com/shopware/meteor-admin-sdk/actions/workflows/tests.yml)
+[![NPM Package](https://img.shields.io/npm/v/@shopware-ag/meteor-admin-sdk)](https://www.npmjs.com/package/@shopware-ag/meteor-admin-sdk)
+
+The `meteor-admin-sdk` is a JavaScript library for all [Shopware 6](https://github.com/shopware/platform) App and Plugin developer which want an easy way to extend and customize the administration.
+
+[See Documentation](https://shopware.github.io/meteor-admin-sdk/)
+
+## Installation
+#### Using NPM:
+Install it to your `package.json`
+```
+npm i --save @shopware-ag/meteor-admin-sdk
+```
+
+and import it in your app:
+```js
+// import everything
+import * as sw from '@shopware-ag/meteor-admin-sdk';
+
+// or import only needed functionality
+import { notification } from '@shopware-ag/meteor-admin-sdk';
+```
+
+#### Using CDN:
+Import the source from the CDN
+
+```js
+// use the latest version available
+
+
+// use a fix version (example here: 1.2.3)
+
+```
+
+and then you can access it with the global variable `sw`.
+
+```js
+sw.notification.dispatch({
+ title: 'My first notification',
+ message: 'This was really easy to do'
+})
+```
+
+## Features
+- ð **Works with Shopware 6 Apps and Plugins:** you can use the SDK for your plugins or apps. API usage is identical.
+- ðĒ **Shallow learning curve:** you don't need to have extensive knowledge about the internals of the Shopware 6 Administration. Our SDK hides the complicated stuff behind a beautiful API.
+- 𧰠**Many extension capabilities:** from throwing notifications, accessing context information or extending the current UI. The feature set of the SDK will gradually be extended, providing more possibilities and flexibility for your ideas and solutions.
+- ðŠĻ **A stable API with great backwards compatibility:** don't fear Shopware updates anymore. Breaking changes in this SDK are an exception. If you use the SDK, your apps and plugins will stay stable for a longer time, without any need for code maintenance.
+- ð§ **Type safety:** the whole SDK is written in TypeScript which provides great autocompletion support and more safety for your apps and plugins.
+- ð **Developer experience:** have a great development experience right from the start. And it will become better and better in the future.
+- ðŠķ **Lightweight:** the whole library is completely tree-shakable and dependency-free. Every functionality can be imported granularly to keep your bundle as small and fast as possible.
+
+## Examples
+
+Throw a notification:
+```js
+sw.notification.dispatch({
+ title: 'My first notification',
+ message: 'This was really easy to do'
+})
+```
+
+Get the system currency:
+```js
+const currency = await sw.context.getCurrency();
+```
+
+Subscribe for UI locale changes:
+```js
+let currentLocale = 'en-GB';
+
+sw.context.subscribeLocale(({ locale }) => {
+ currentLocale = locale;
+})
+```
+
+See more examples in the [Documentation](https://shopware.github.io/meteor-admin-sdk/).
diff --git a/packages/admin-sdk/devenv.lock b/packages/admin-sdk/devenv.lock
new file mode 100644
index 000000000..021070eb6
--- /dev/null
+++ b/packages/admin-sdk/devenv.lock
@@ -0,0 +1,156 @@
+{
+ "nodes": {
+ "devenv": {
+ "locked": {
+ "dir": "src/modules",
+ "lastModified": 1685013540,
+ "narHash": "sha256-UM9tPy9fyfXs+knxwk/rCIaNfVC7ggwzbLcY8lkOr+E=",
+ "owner": "cachix",
+ "repo": "devenv",
+ "rev": "5ff14a8f2828a2e607a65e2b16650a8cf950515b",
+ "type": "github"
+ },
+ "original": {
+ "dir": "src/modules",
+ "owner": "cachix",
+ "repo": "devenv",
+ "type": "github"
+ }
+ },
+ "flake-compat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1673956053,
+ "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1685518550,
+ "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "gitignore": {
+ "inputs": {
+ "nixpkgs": [
+ "pre-commit-hooks",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1660459072,
+ "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1684973047,
+ "narHash": "sha256-ZLnSr35L6C49pCZS9fZCCqkIKNAeQzykov2QfosNG9w=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "21eb6c6ba74dcbe3ea5926ee46287300fb066630",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-stable": {
+ "locked": {
+ "lastModified": 1678872516,
+ "narHash": "sha256-/E1YwtMtFAu2KUQKV/1+KFuReYPANM2Rzehk84VxVoc=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "9b8e5abb18324c7fe9f07cb100c3cd4a29cda8b8",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-23.05",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "pre-commit-hooks": {
+ "inputs": {
+ "flake-compat": "flake-compat",
+ "flake-utils": "flake-utils",
+ "gitignore": "gitignore",
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "nixpkgs-stable": "nixpkgs-stable"
+ },
+ "locked": {
+ "lastModified": 1684842236,
+ "narHash": "sha256-rYWsIXHvNhVQ15RQlBUv67W3YnM+Pd+DuXGMvCBq2IE=",
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
+ "rev": "61e567d6497bc9556f391faebe5e410e6623217f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "devenv": "devenv",
+ "nixpkgs": "nixpkgs",
+ "pre-commit-hooks": "pre-commit-hooks"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/packages/admin-sdk/devenv.nix b/packages/admin-sdk/devenv.nix
new file mode 100644
index 000000000..c090978cc
--- /dev/null
+++ b/packages/admin-sdk/devenv.nix
@@ -0,0 +1,6 @@
+{ pkgs, lib, ... }:
+
+{
+ languages.javascript.enable = lib.mkDefault true;
+ languages.javascript.package = lib.mkDefault pkgs.nodejs-18_x;
+}
diff --git a/packages/admin-sdk/devenv.yaml b/packages/admin-sdk/devenv.yaml
new file mode 100644
index 000000000..9860f4276
--- /dev/null
+++ b/packages/admin-sdk/devenv.yaml
@@ -0,0 +1,3 @@
+inputs:
+ nixpkgs:
+ url: github:NixOS/nixpkgs/nixpkgs-unstable
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/.gitignore b/packages/admin-sdk/docs/.gitignore
new file mode 100644
index 000000000..e6e9ac43d
--- /dev/null
+++ b/packages/admin-sdk/docs/.gitignore
@@ -0,0 +1,20 @@
+# Dependencies
+/node_modules
+
+# Production
+/build
+
+# Generated files
+.docusaurus
+.cache-loader
+
+# Misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/README.md b/packages/admin-sdk/docs/README.md
new file mode 100644
index 000000000..55d0c3ef4
--- /dev/null
+++ b/packages/admin-sdk/docs/README.md
@@ -0,0 +1,33 @@
+# Website
+
+This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
+
+### Installation
+
+```
+$ yarn
+```
+
+### Local Development
+
+```
+$ yarn start
+```
+
+This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
+
+### Build
+
+```
+$ yarn build
+```
+
+This command generates static content into the `build` directory and can be served using any static contents hosting service.
+
+### Deployment
+
+```
+$ GIT_USER= USE_SSH=true yarn deploy
+```
+
+If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
diff --git a/packages/admin-sdk/docs/babel.config.js b/packages/admin-sdk/docs/babel.config.js
new file mode 100644
index 000000000..e00595dae
--- /dev/null
+++ b/packages/admin-sdk/docs/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
+};
diff --git a/packages/admin-sdk/docs/docs/.gitkeep b/packages/admin-sdk/docs/docs/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/packages/admin-sdk/docs/docs/guide/1_getting-started/_category_.yml b/packages/admin-sdk/docs/docs/guide/1_getting-started/_category_.yml
new file mode 100644
index 000000000..c45b63abc
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/1_getting-started/_category_.yml
@@ -0,0 +1,2 @@
+label: "Getting started"
+position: 10
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/1_getting-started/assets/devtools-plugin.png b/packages/admin-sdk/docs/docs/guide/1_getting-started/assets/devtools-plugin.png
new file mode 100644
index 000000000..6041d15ea
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/1_getting-started/assets/devtools-plugin.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/1_getting-started/assets/devtools-usage.png b/packages/admin-sdk/docs/docs/guide/1_getting-started/assets/devtools-usage.png
new file mode 100644
index 000000000..7c86844ca
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/1_getting-started/assets/devtools-usage.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/1_getting-started/devTools.md b/packages/admin-sdk/docs/docs/guide/1_getting-started/devTools.md
new file mode 100644
index 000000000..5eec0f712
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/1_getting-started/devTools.md
@@ -0,0 +1,30 @@
+---
+title: "Vue dev tools"
+sidebar_position: 2
+---
+
+# Vue dev tools
+
+## Prerequisites
+We assume that you got the [Vue dev tools](https://devtools.vuejs.org/) installed for your browser.
+The extension is available for Chrome, Firefox, Edge and as a standalone app.
+
+## Development setup
+Furthermore you should have [Shopware](https://github.com/shopware/platform) setup.
+To make use of the Extension API plugin for the Vue dev tools start the watcher of the administration:
+
+```bash
+$ composer run watch:admin
+```
+
+## Vue dev tool plugin
+Once you logged into your administration, open up the development tools of your browser and choose the Vue tab.
+Inside the Vue tab choose the Shopware Extension API plugin.
+
+![Devtools plugin](./assets/devtools-plugin.png)
+
+## Usage
+The plugin will show you all extension points for the current page you visit.
+Once you select an extension point it will highlight the corresponding area in the viewport and give detailed information how to extend the highlighted property.
+
+![Devtools usage](./assets/devtools-usage.png)
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/1_getting-started/installation.md b/packages/admin-sdk/docs/docs/guide/1_getting-started/installation.md
new file mode 100644
index 000000000..29bb5a982
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/1_getting-started/installation.md
@@ -0,0 +1,175 @@
+---
+title: "Installation"
+sidebar_position: 1
+---
+
+# Installation
+
+## Prerequisites:
+
+You need to have an working [app](https://developer.shopware.com/docs/guides/plugins/apps/app-base-guide) or [plugin](https://developer.shopware.com/docs/guides/plugins/plugins/plugin-base-guide) installed on your Shopware 6 instance.
+
+## Prepare your app or plugin
+
+### App:
+
+You need to create a HTML page with an JS file for your app. This page needs to be served by your app-server as it needs to be accesible via URL.
+For development purposes you can use [App server sdk](https://github.com/FriendsOfShopware/app-server-sdk-js).
+
+Once you got the registration/ handshake working you need to add the `` field to the `` section of the [manifest](https://developer.shopware.com/docs/guides/plugins/apps/app-base-guide#manifest-file) file. This field should contain the public URL of your app. Let's assume your app HTML page is served under `http://localhost/my-example-app.html`:
+
+```xml
+
+
+
+ MyExampleApp
+
+
+
+
+ http://link-to-your-local-app-server/register
+ S3cr3tf0re$t
+
+
+
+
+ http://localhost/my-example-app.html
+
+
+```
+
+In your new HTML file you need inject a JS file. This file can use the Meteor Admin SDK via CDN or if you want to use a build tools then you
+can use the NPM package.
+
+### Plugin:
+**Notice:** Plugins will work on self-hosted instances only. You won't be able to use a Shopware 6 cloud instance with plugins.
+
+Open the path `custom/plugins/yourPlugin/src/Resources/app/administration`. This is the base path for all new admin files.
+
+Create a new base `index.html` file. This file will be automatically injected to the administration when the plugin is activated. Then you need to create a JavaScript file in the subfolder `src/main.js`. This file will be automatically injected into the created HTML file.
+
+For plugins the best way is to install the SDK via NPM. But first you need to initialize a new NPM project in your plugin folder with
+`npm init --yes`.
+
+## Installing the SDK:
+
+The preferred way of using the library is with a NPM package. This guarantees the smallest bundle size for your apps and plugins, since this way only necessary functions are bundled together.
+
+The CDN method is easy to use and fast to implement. It is best used for quick prototyping or if you don't want to work with building tools.
+
+### Using NPM (require bundling):
+Install it to your `package.json`
+```
+npm i --save @shopware-ag/meteor-admin-sdk
+```
+
+and import it into your app or plugin:
+```js
+// import everything as one big object
+import * as sw from '@shopware-ag/meteor-admin-sdk';
+
+// or import only needed functionality scope
+import { notification } from '@shopware-ag/meteor-admin-sdk';
+
+// or the direct method (here with an alias)
+import { dispatch as dispatchNotification } from '@shopware-ag/meteor-admin-sdk/es/notification'
+
+```
+
+### Using CDN:
+Import the source from the CDN
+
+```js
+// use the latest version available
+
+
+// use a fix version (example here: 1.2.3)
+
+```
+
+and access it with the global variable `sw`.
+
+```js
+sw.notification.dispatch({
+ title: 'My first notification',
+ message: 'This was really easy to do'
+})
+```
+
+## Adding types for Entities (TS only)
+
+The data management inside the SDK supports complete TypeScript support. This allows complete type safety when getting
+entities, editing or saving them.
+
+For adding the types you need to create a global type definition file like `global.d.ts`. Inside this file you can
+add the types for the entities by extending the global namespace.
+
+### Using auto-generated types from Shopware
+This is the easiest solution. Just install the correct type definition for the matching shopware version:
+
+`npm install @shopware-ag/entity-schema-types@5.0.0`
+
+The version number should match the Shopware version number without the `6.` in the beginning. Examples:
+
+`Shopware 6.5.0.0` â `@shopware-ag/entity-schema-types@5.0.0`
+`Shopware 6.5.1.2` â `@shopware-ag/entity-schema-types@5.1.2`
+`Shopware 6.6.3.1` â `@shopware-ag/entity-schema-types@6.3.1`
+
+```ts
+// global.d.ts
+import '@shopware-ag/entity-schema-types';
+```
+
+### Using "any" fallback
+
+This is the easiest solution. You set the type to `any` for every entity. The downside of this is the missing type safety.
+
+```ts
+// global.d.ts
+declare namespace EntitySchema {
+ interface Entities {
+ [entityName: string]: any;
+ }
+}
+```
+
+### Using custom types
+
+This is the safest solution. You define for every needed entity every property and association. The downside of this is
+that it takes time to write the definitions.
+
+```ts
+// global.d.ts
+declare namespace EntitySchema {
+ interface Entities {
+ // using product_manufacturer as an example
+ product_manufacturer: product_manufacturer;
+ // in this case 'media', 'product' and 'product_manufacturer_translation' is also needed
+ ...
+ }
+
+ interface product_manufacturer {
+ id: string;
+ versionId: string;
+ mediaId?: string;
+ link?: string;
+ name: string;
+ description?: string;
+ customFields?: unknown;
+ /*
+ * Entity and EntityCollection is defined in the namespace and can directly be used.
+ * The value in the generic (here 'media', 'product' and 'product_manufacturer_translation') need
+ * also to be defined in this file.
+ */
+ media?: Entity<'media'>;
+ products?: EntityCollection<'product'>;
+ translations: EntityCollection<'product_manufacturer_translation'>;
+ createdAt: string;
+ updatedAt?: string;
+ translated?: {name?: string, description?: string, customFields?: unknown};
+ }
+
+ // 'media', 'product' and 'product_manufacturer_translation' also needs to be added
+ ...
+}
+```
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/1_getting-started/usage.md b/packages/admin-sdk/docs/docs/guide/1_getting-started/usage.md
new file mode 100644
index 000000000..09db0849c
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/1_getting-started/usage.md
@@ -0,0 +1,119 @@
+---
+sidebar_position: 3
+---
+
+# Usage
+
+After [installing](./installation) the Meteor Admin SDK successfully you can use it in your apps and plugins.
+
+## Adding functionality to new apps or plugins
+You can use the SDK features directly in your JS file. Just import the specific feature (NPM method) or use the method in the
+`sw` object (CDN method). You can find all features in the API reference documentation.
+
+### NPM example:
+```js
+// import notification toolkit from the SDK
+import { notification } from '@shopware-ag/meteor-admin-sdk';
+
+// dispatch a new notification
+notification.dispatch({
+ title: 'My first notification',
+ message: 'This was really easy to do'
+})
+```
+
+### CDN example:
+```js
+// access the "notification" toolkit in the global "sw" object and dispatch a new notification
+sw.notification.dispatch({
+ title: 'My first notification',
+ message: 'This was really easy to do'
+})
+```
+
+
+## Adding functionality to existing plugins
+Shopware 6 has a rich plugin extension system for the Admin based on Twig and the concepts of component overriding and component extending. These
+concepts are very powerful, but may also come with a steep learning curve. That's why you can migrate gradually to the new Meteor Admin SDK, if you want.
+Both approaches can work together. This way you can start by converting only parts of your plugins at first and then gradually converting more and more of your plugins as new features are added to the SDK.
+This approach is also going to help with simplifying your plugins and preparing them for long term usage.
+
+#### Example:
+
+```js
+// Use existing extension capabilties
+Shopware.Component.override('sw-dashboard-index', {
+ methods: {
+ async createdComponent() {
+ // Can also use Meteor Admin SDK features
+ await sw.notification.dispatch({
+ title: 'Hello from the plugin',
+ message: 'I am combining the existing approach with the new SDK approach',
+ })
+
+ this.$super('createdComponent');
+ }
+ }
+});
+```
+
+### Using locations with normal Vue components without iFrame rendering
+
+**This feature is not yet released in Shopware.
+It's only available with the development enviroment or `dev-trunk` version of Shopware.**
+
+It is useful when you want to migrate partially from the twig plugin system to the SDK extension system that you use both systems together. To make this happen you can render normal Vue components in the Shopware administration for the locations instead of your iFrame view.
+
+To do this you need to register the component in the existing plugin system:
+
+```js
+Shopware.Component.register('your-component-name', {
+ // your component
+})
+```
+
+Now if you want to render the component in a location you need to add the name of the component to the current location. This can be done with the `sdkLocation` store:
+```js
+Shopware.State.commit('sdkLocation/addLocation', {
+ locationId: 'your-location-id',
+ componentName: 'your-component-name'
+})
+```
+
+With this feature you can create mix the usage of the SDK and the existing plugin system. A complete example could be looking like this. It creates a new tab item in the product detail page, renders a card with the componentSection renderer and inside the card it renders the location. But instead of the traditional location it renders a Vue component which was registered in the Shopware Component Factory.
+
+```js
+// in a normal plugin js file without a HTML file
+import { ui, location } from '@shopware-ag/meteor-admin-sdk';
+
+if (!location.isIframe()) {
+ const myLocationId = 'my-example-location-id';
+
+ // Create a new tab entry
+ ui.tabs('sw-product-detail').addTabItem({
+ label: 'Example tab',
+ componentSectionId: 'example-product-detail-tab-content'
+ })
+
+ // Add a new card to the tab content which renders a location
+ ui.componentSection.add({
+ component: 'card',
+ positionId: 'example-product-detail-tab-content',
+ props: {
+ title: 'Component section example',
+ locationId: myLocationId
+ }
+ })
+
+ // Register your component which should be rendered inside the location
+ Shopware.Component.register('your-component-name', {
+ // your component
+ })
+
+ // Add the component name to the specific location
+ Shopware.State.commit('sdkLocation/addLocation', {
+ locationId: myLocationId,
+ componentName: 'your-component-name'
+ })
+}
+```
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/_category_.yml b/packages/admin-sdk/docs/docs/guide/2_api-reference/_category_.yml
new file mode 100644
index 000000000..1a58cd9ba
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/_category_.yml
@@ -0,0 +1,2 @@
+label: "API Reference"
+position: 50
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/assets/notification-example.jpg b/packages/admin-sdk/docs/docs/guide/2_api-reference/assets/notification-example.jpg
new file mode 100644
index 000000000..d666767b0
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/assets/notification-example.jpg differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/assets/register-cms-element-example.png b/packages/admin-sdk/docs/docs/guide/2_api-reference/assets/register-cms-element-example.png
new file mode 100644
index 000000000..68c32b586
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/assets/register-cms-element-example.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/assets/useSharedState-demo.gif b/packages/admin-sdk/docs/docs/guide/2_api-reference/assets/useSharedState-demo.gif
new file mode 100644
index 000000000..e00ca4946
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/assets/useSharedState-demo.gif differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/cms/_category_.yml b/packages/admin-sdk/docs/docs/guide/2_api-reference/cms/_category_.yml
new file mode 100644
index 000000000..5890ed709
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/cms/_category_.yml
@@ -0,0 +1,2 @@
+label: "CMS"
+position: 300
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/cms/registerCmsElement.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/cms/registerCmsElement.md
new file mode 100644
index 000000000..c18b584fa
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/cms/registerCmsElement.md
@@ -0,0 +1,29 @@
+# Register CMS element
+
+> Available since Shopware v6.4.17.0
+
+With `cms.registerCmsElement` you can register CMS elements to use in the Shopping Experiences Module.
+More information on how to develop CMS elements can be found in [this guide](https://developer.shopware.com/docs/guides/plugins/plugins/content/cms/add-cms-element).
+
+![Register a CMS element in your Shopping Experiences Module via App](../assets/register-cms-element-example.png)
+
+#### Usage:
+```ts
+void cms.registerCmsElement({
+ name: 'dailymotionElement',
+ label: 'Dailymotion Video',
+ defaultConfig: {
+ dailyUrl: {
+ source: 'static',
+ value: '',
+ },
+ },
+});
+```
+
+#### Parameters
+| Name | Required | Description |
+|:----------------|:---------|:---------------------------------------------------------------------------------------------------------|
+| `name` | true | The name of the cms element, which will also be used to generate locationIds - Should have vendor prefix |
+| `label` | true | The label, which is visible when selecting the cms element - Use snippet keys here! |
+| `defaultConfig` | true | Object containing the defaultConfig; same like in plugin development. |
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/composables/_category_.yml b/packages/admin-sdk/docs/docs/guide/2_api-reference/composables/_category_.yml
new file mode 100644
index 000000000..c8d1b65a8
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/composables/_category_.yml
@@ -0,0 +1,2 @@
+label: "Vue Composables"
+position: 400
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/composables/useSharedState.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/composables/useSharedState.md
new file mode 100644
index 000000000..cdaa9ce1d
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/composables/useSharedState.md
@@ -0,0 +1,24 @@
+# useSharedState
+
+The `composables.useSharedState` function allows you to create globally accessible state in your app. The state defined within this composable has a unique key, and any other part of the app that uses the same composable with the same key will access the same data.
+
+The shared state is reactive, meaning that when you update the data in one place, all other places that access the same shared state will be automatically updated as well. This feature is particularly useful when you need to pass data to different locations, such as modals or locations outside the current iFrame. The shared state is also saved locally to the user's machine using IndexedDB, ensuring persistence even after refreshes or when the user is using multiple tabs.
+
+The value stored within the shared state can be any data type that can be serialized to JSON. Additionally, we have added support for Entities and EntityCollections.
+
+![useShardState demo](../assets/useSharedState-demo.gif)
+
+#### Usage:
+```ts
+// Inside a Vue component setup
+import { composables } from '@shopware-ag/meteor-admin-sdk';
+const { useSharedState } = composables;
+
+const mySharedStateValue = useSharedState('myUniqueKeyForTheSharedState', 'myInitialDataValue');
+```
+
+#### Parameters
+| Name | Required | Description |
+| :------------- | :------- | :------------------------------------------------------------------------ |
+| `key` | true | The unique key used to share the state across different places |
+| `initial data` | true | The initial data value used when no data exists in the local shared state |
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/context.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/context.md
new file mode 100644
index 000000000..d7329c513
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/context.md
@@ -0,0 +1,320 @@
+# Context
+
+## Language
+
+### Get current language
+
+#### Usage:
+```ts
+const language = await sw.context.getLanguage();
+```
+
+#### Parameters
+No parameters needed.
+
+#### Return value:
+```ts
+Promise<{
+ languageId: string,
+ systemLanguageId: string
+}>
+```
+
+#### Example value:
+```ts
+{
+ languageId: '2fbb5fe2e29a4d70aa5854ce7ce3e20b',
+ systemLanguageId: '2fbb5fe2e29a4d70aa5854ce7ce3e20b'
+}
+```
+
+### Subscribe on language changes
+
+#### Usage:
+```ts
+sw.context.subscribeLanguage(({ languageId, systemLanguageId }) => {
+ // do something with the callback data
+});
+```
+
+#### Parameters
+| Name | Description |
+| :------ | :------ |
+| `callbackMethod` | Called every-time the language changes |
+
+#### Callback value:
+```ts
+{
+ languageId: string,
+ systemLanguageId: string
+}
+```
+
+#### Example callback value:
+```ts
+{
+ languageId: '2fbb5fe2e29a4d70aa5854ce7ce3e20b',
+ systemLanguageId: '2fbb5fe2e29a4d70aa5854ce7ce3e20b'
+}
+```
+
+## Environment
+
+### Get current environment
+
+#### Usage:
+```ts
+const environment = await sw.context.getEnvironment();
+```
+
+#### Parameters
+No parameters needed.
+
+#### Return value:
+```ts
+Promise<'development' | 'production' | 'testing'>
+```
+
+#### Example value:
+```ts
+'development'
+```
+
+## Locale
+
+### Get current locale
+
+#### Usage:
+```ts
+const locale = await sw.context.getLocale();
+```
+
+#### Parameters
+No parameters needed.
+
+#### Return value:
+```ts
+Promise<{
+ locale: string,
+ fallbackLocale: string
+}>
+```
+
+#### Example value:
+```ts
+{
+ locale: 'de-DE',
+ fallbackLocale: 'en-GB'
+}
+```
+
+### Subscribe on locale changes
+
+#### Usage:
+```ts
+sw.context.subscribeLocale(({ locale, fallbackLocale }) => {
+ // do something with the callback data
+});
+```
+
+#### Parameters
+| Name | Description |
+| :------ | :------ |
+| `callbackMethod` | Called every-time the locale changes |
+
+#### Callback value:
+```ts
+{
+ locale: string,
+ fallbackLocale: string
+}
+```
+
+#### Example callback value:
+```ts
+{
+ locale: 'de-DE',
+ fallbackLocale: 'en-GB'
+}
+```
+
+## Currency
+
+### Get current currency
+
+#### Usage:
+```ts
+const currency = await sw.context.getCurrency();
+```
+
+#### Parameters
+No parameters needed.
+
+#### Return value:
+```ts
+Promise<{
+ systemCurrencyId: string,
+ systemCurrencyISOCode: string
+}>
+```
+
+#### Example value:
+```ts
+{
+ systemCurrencyId: 'b7d2554b0ce847cd82f3ac9bd1c0dfca',
+ systemCurrencyISOCode: 'EUR'
+}
+```
+
+## Shopware version
+
+### Get current Shopware version
+
+#### Usage:
+```ts
+const shopwareVersion = await sw.context.getShopwareVersion();
+```
+
+#### Parameters
+No parameters needed.
+
+#### Return value:
+```ts
+string
+```
+
+#### Example value:
+```ts
+'6.4.0.0'
+```
+
+## App information
+
+### Get app information
+
+#### Usage:
+```ts
+const { name, version, type } = await sw.context.getAppInformation();
+```
+
+#### Parameters
+No parameters needed.
+
+#### Return value:
+```ts
+Promise<{ name: string ; version: string ; type: 'app' | 'plugin' }>
+```
+
+#### Example value:
+```ts
+{
+ name: 'my-extension',
+ version: '1.2.3',
+ type: 'app'
+}
+```
+
+## User information
+
+### Get user information
+
+:::caution
+Do not use this feature yet. It is not implemented in a Shopware release yet.
+:::
+
+#### Usage:
+```ts
+const userInformation = await sw.context.getUserInformation();
+```
+
+#### Parameters
+No parameters needed.
+
+#### Return value:
+```ts
+Promise<{
+ aclRoles: Array<{
+ name: string,
+ type: string,
+ id: string,
+ privileges: Array,
+ }>,
+ active: boolean,
+ admin: boolean,
+ avatarId: string,
+ email: string,
+ firstName: string,
+ id: string,
+ lastName: string,
+ localeId: string,
+ title: string,
+ type: string,
+ username: string,
+}>
+```
+
+#### Example value:
+```ts
+{
+ "aclRoles": [],
+ "active": true,
+ "admin": true,
+ "avatarId": "",
+ "email": "info@shopware.com",
+ "firstName": "",
+ "id": "e2a77f4c718d407591b4826222aa3546",
+ "lastName": "admin",
+ "localeId": "35bbb8c4305c47ec88b13ab30c0c5c5a",
+ "title": "",
+ "type": "user",
+ "username": "admin"
+}
+```
+
+## Module information
+
+### Get module information
+Get information about all registered modules. These modules are created by adding new menu items, setting items, etc.
+
+The ID can be used to change the current route to the module.
+
+#### Usage:
+```ts
+const { modules } = await sw.context.getModuleInformation();
+
+sw.window.routerPush({
+ name: 'sw.extension.sdk.index',
+ params: {
+ id: modules[0].id // get the ID of the wanted module
+ }
+})
+```
+
+#### Parameters
+No parameters needed.
+
+#### Return value:
+```ts
+Promise<{
+ modules: Array<{
+ displaySearchBar: boolean,
+ heading: string,
+ id: string,
+ locationId: string
+ }>
+}}>
+```
+
+#### Example value:
+```ts
+{
+ modules: [
+ {
+ displaySearchBar: true,
+ heading: 'My module',
+ id: 'sd5aasfsdfas',
+ locationId: 'my-location-id'
+ }
+ ]
+}
+```
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/data/_category_.yml b/packages/admin-sdk/docs/docs/guide/2_api-reference/data/_category_.yml
new file mode 100644
index 000000000..13f108ed8
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/data/_category_.yml
@@ -0,0 +1,2 @@
+label: "Data"
+position: 200
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/data/get.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/data/get.md
new file mode 100644
index 000000000..c3cef48bb
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/data/get.md
@@ -0,0 +1,22 @@
+# Get
+
+With `data.get` you can receive datasets from the Shopware administration.
+More information on how to find the unique identifiers can be found in [this guide](../../5_internals/datahandling.md).
+
+Compared to data.subscribe, data.get only gives you the current state of the data. If the data is not available yet,
+such as when opening a page, you won't receive any data. In these cases, it's better to subscribe to data changes instead.
+
+#### Usage:
+```ts
+data.get({
+ id: 'sw-product-detail__product',
+ selectors: ['name', 'manufacturer.name'],
+}).then((product) => {
+ console.log(product);
+});
+```
+
+#### Parameters
+| Name | Required | Description |
+| :-------- | :------- | :--------------------------------------------------------------------------------------------------------- |
+| `options` | true | Options containing the unique `id` and optional `selectors` for minimizing the payload and needed privileges |
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/data/repository.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/data/repository.md
new file mode 100644
index 000000000..f65c745ff
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/data/repository.md
@@ -0,0 +1,241 @@
+# Repository
+
+The data handling of the SDK allows you to fetch and write nearly everything in the database. The behavior matches the data handling in the main administration. The only difference is the implementation details because the data handling don't request the server directly. It communicates with the admin which handles the requests, changesets, saving and more.
+
+The data handling implements the repository pattern. You can create a repository for an entity simply like this:
+
+```ts
+sw.data.repository('your_entity_name')
+```
+
+With this repository you can search for data, save it, delete it, create it or check for changes.
+
+
+### Permissions
+For every action on the repository, your app will need the matching permissions.
+Permissions are set in the app manifest file and are grouped by action.
+For actions you can choose between `create`, `read`, `update` and `delete`.
+Remember everytime you adjust the permissions in your manifest you need to increase the app version and update it.
+
+```xml
+
+
+
+
+
+
+ product
+ product
+ product
+ product
+
+
+
+```
+
+### Criteria
+
+For requesting data you need to create a Criteria class which contains all information for the request:
+
+```ts
+const criteria = new sw.data.Classes.Criteria();
+
+criteria.setPage(1);
+criteria.setLimit(10);
+criteria.setTerm('foo');
+criteria.setIds(['some-id', 'some-id']); // Allows to provide a list of ids which are used as a filter
+
+/**
+ * Configures the total value of a search result.
+ * 0 - no total count will be selected. Should be used if no pagination required (fastest)
+ * 1 - exact total count will be selected. Should be used if an exact pagination is required (slow)
+ * 2 - fetches limit * 5 + 1. Should be used if pagination can work with "next page exists" (fast)
+*/
+criteria.setTotalCountMode(2);
+
+criteria.addFilter(
+ Criteria.equals('product.active', true)
+);
+
+criteria.addSorting(
+ Criteria.sort('product.name', 'DESC')
+);
+
+criteria.addAggregation(
+ Criteria.avg('average_price', 'product.price')
+);
+
+criteria.getAssociation('categories')
+ .addSorting(Criteria.sort('category.name', 'ASC'));
+```
+
+
+### Search
+Sends a search request for the repository entity.
+
+#### Usage:
+```ts
+const exampleRepository = sw.data.repository('your_entity');
+
+const yourEntities = await exampleRepository.search(yourCriteria);
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :--------- | :------- | :------ | :--------------------------------------------- |
+| `criteria` | true | | Your criteria object |
+| `context` | false | {} | Change the [request context](#request-context) |
+
+#### Return value:
+The return value is a EntityCollection which contains all entities matching the criteria.
+
+### Get
+Short hand to fetch a single entity from the server
+
+#### Usage:
+```ts
+const exampleRepository = sw.data.repository('your_entity');
+
+const yourEntity = await exampleRepository.get('theEntityId');
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :--------- | :------- | :------ | :--------------------------------------------- |
+| `id` | true | | The id of the entity |
+| `context` | false | {} | Change the [request context](#request-context) |
+| `criteria` | true | | Your criteria object |
+
+#### Return value:
+The return value is the entity result when a matching entity was found.
+
+### Save
+Detects all entity changes and send the changes to the server.
+If the entity is marked as new, the repository will send a POST create. Updates will be send as PATCH request.
+Deleted associations will be send as additional request
+
+#### Usage:
+```ts
+const exampleRepository = sw.data.repository('your_entity');
+
+await exampleRepository.save(yourEntityObject);
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :-------- | :------- | :------ | :--------------------------------------------- |
+| `entity` | true | | The entity object |
+| `context` | false | {} | Change the [request context](#request-context) |
+
+#### Return value:
+This method does not have a return value. It just returns a Promise which is resolved when it was saved successfully.
+
+### Clone
+Clones an existing entity
+
+#### Usage:
+```ts
+const exampleRepository = sw.data.repository('your_entity');
+
+const clonedEntityId = await exampleRepository.clone('theEntityIdToClone');
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :--------- | :------- | :------ | :--------------------------------------------- |
+| `entityId` | true | | The entity id which should be cloned |
+| `context` | false | {} | Change the [request context](#request-context) |
+
+#### Return value:
+This method returns the id of the cloned entity.
+
+### Has changes
+Detects if the entity or the relations has remaining changes which are not synchronized with the server
+
+#### Usage:
+```ts
+const exampleRepository = sw.data.repository('your_entity');
+
+const hasChanges = await exampleRepository.hasChanges(yourEntityObject);
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :------- | :------- | :------ | :---------------- |
+| `entity` | true | | The entity object |
+
+#### Return value:
+This method returns a boolean value. If the entity has changes then it returns `true`. Otherwise it returns `false`.
+
+### Save all
+Detects changes of all provided entities and send the changes to the server
+
+#### Usage:
+```ts
+const exampleRepository = sw.data.repository('your_entity');
+
+await exampleRepository.saveAll(yourEntityCollection);
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :--------- | :------- | :------ | :--------------------------------------------- |
+| `entities` | true | | Your entity collection which should be saved |
+| `context` | false | {} | Change the [request context](#request-context) |
+
+#### Return value:
+This method does not have a return value. It just returns a Promise which is resolved when it was saved successfully.
+
+### Delete
+Sends a delete request for the provided id.
+
+#### Usage:
+```ts
+const exampleRepository = sw.data.repository('your_entity');
+
+await exampleRepository.delete('yourEntityId');
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :--------- | :------- | :------ | :--------------------------------------------- |
+| `entityId` | true | | The id of the entity which should be deleted |
+| `context` | false | {} | Change the [request context](#request-context) |
+
+#### Return value:
+This method does not have a return value. It just returns a Promise which is resolved when it was deleted successfully.
+
+### Create
+Creates a new entity for the local schema. To Many association are initialed with a collection with the corresponding remote api route. This entity is not saved to the database yet.
+
+#### Usage:
+```ts
+const exampleRepository = sw.data.repository('your_entity');
+
+const yourNewEntity = await exampleRepository.create();
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :--------- | :------- | :------ | :--------------------------------------------- |
+| `context` | false | {} | Change the [request context](#request-context) |
+| `id` | false | | You can provide a id of the new entity if wanted |
+
+#### Return value:
+This method returns the newly created entity.
+
+### Request Context
+You can optionally change the context of the request. It will be merged together with the base API context.
+
+```ts
+const exampleContext = {
+ // Load also inherited data (example from parent product in variant)
+ inheritance: true,
+ // Change the language context of the entity to change data in different languages
+ languageId: 'theLanguageId',
+ // If you are working with versioned entities you can change the current live version id
+ liveVersionId: 'yourLiveVersionId'
+}
+```
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/data/subscribe.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/data/subscribe.md
new file mode 100644
index 000000000..bd30a67ae
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/data/subscribe.md
@@ -0,0 +1,22 @@
+# Subscribe
+
+With `data.subscribe` you can subscribe to dataset changes. The callback will be called every time, the dataset with the matching id is changed.
+More information on how to find the unique identifiers can be found in [this guide](../../5_internals/datahandling.md).
+
+#### Usage:
+```ts
+data.subscribe(
+ 'sw-product-detail__product',
+ ({id, data}) => {
+ console.log(data);
+ },
+ selectors: ['name', 'manufacturer.name'],
+);
+```
+
+#### Parameters
+| Name | Required | Description |
+| :---------- | :------- | :---------------------------------------------------------------------------------------------------- |
+| `id` | true | The unique id of the dataset you want to receive |
+| `callback` | true | A callback function which will be called every time the Shopware Administration publishes the dataset |
+| `selectors` | false | Selectors for reducing the payload and minimizing the needed privileges |
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/data/update.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/data/update.md
new file mode 100644
index 000000000..19bd5c7bb
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/data/update.md
@@ -0,0 +1,17 @@
+# Update
+
+With `data.update` you can update datasets from the Shopware administration.
+More information on how to find the unique identifiers can be found in [this guide](../../5_internals/datahandling.md).
+
+#### Usage:
+```ts
+data.update({
+ id: 'sw-example-component__string',
+ data: 'your-value',
+});
+```
+
+#### Parameters
+| Name | Required | Description |
+| :-------- | :------- | :------------------------------------------------- |
+| `options` | true | An object containing the id and the data to update |
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/location.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/location.md
new file mode 100644
index 000000000..8f0175c72
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/location.md
@@ -0,0 +1,162 @@
+# Location
+
+## Prerequisites
+We recommend you read the [concept](../4_concepts/locations.md) of locations first.
+## Location checks
+
+### Check the current location id
+
+Check if the current location matches the given location Id.
+
+#### Usage:
+
+```ts
+if (sw.location.is('my-location-id')) {
+ // Render view for location
+}
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :----------- | :------- | :------ | :----------------------- |
+| `locationId` | true | | The location Id to check |
+
+#### Return value:
+Returns a boolean. It is `true` if the location Id matches the current location.
+
+### Get the current location id
+
+Get the name of the current location ID
+
+#### Usage:
+
+```ts
+const currentLocation = sw.location.get()
+```
+
+#### Return value:
+Returns a string with the name of the current location.
+
+### Check if current location is inside iFrame
+
+Useful for hybrid extensions which are using plugin and Extension SDK functionalities together. You can use this
+check to separate code which should be executed inside the Extension SDK context and the plugin context.
+
+#### Usage:
+
+```ts
+if (location.isIframe()) {
+ // Execute the code which uses the meteor-admin-sdk context
+ import('./extension-code');
+} else {
+ // Execute the plugin code
+ import('./plugin-code');
+}
+```
+
+## iFrame Heights
+
+#### Parameters:
+No parameters needed.
+
+#### Return value:
+Returns a boolean. If it is executed inside a iFrame it returns `true`.
+
+### Update the height of the location iFrame
+
+You can update the height of the iFrame with this method.
+
+#### Usage:
+
+```ts
+sw.location.updateHeight(750);
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :-------------- | :------- | :------------- | :------------------------------------------------------------------------------------------------------------- |
+| `iFrame height` | false | Auto generated | The height of the iFrame. If no value is provided it will be automatically calculated from the current height. |
+
+#### Return value:
+This method does not have a return value.
+
+### Start auto resizing of the iFrame height
+
+This methods starts the auto resizer of the iFrame height.
+
+![Auto resizing example](../4_concepts/assets/auto-resizer.gif)
+
+#### Usage:
+
+```ts
+sw.location.startAutoResizer();
+```
+
+#### Parameters:
+No parameters needed.
+
+#### Return value:
+This method does not have a return value.
+
+### Stop auto resizing of the iFrame height
+
+This methods stops the auto resizer of the iFrame height.
+
+#### Usage:
+
+```ts
+sw.location.stopAutoResizer();
+```
+
+#### Parameters:
+No parameters needed.
+
+#### Return value:
+This method does not have a return value.
+
+## URL changes inside your app
+
+:::caution
+Do not use this feature yet. It is not implemented in a Shopware release yet.
+:::
+
+Important: You can track and emit your URL changes only inside your own main module or settings page.
+
+### Update URL
+
+Send the current URL of your iFrame to the administration. When the user reloads the whole page your iFrame will get the
+last page you sent to the administration.
+
+#### Usage:
+
+```ts
+const currentUrl = window.location.href;
+
+sw.location.updateUrl(new URL(currentUrl))
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :-------------- | :------- | :------ | :------------------------------------ |
+| First parameter | true | | An URL object which contains your URL |
+
+### Start automatic URL updates
+
+To avoid manually sending URL changes you can use this helper methods. It sends automatically changes in your URL to the
+administration.
+
+#### Usage:
+
+```ts
+sw.location.startAutoUrlUpdater();
+```
+
+### Stop automatic URL updates
+
+If you had started an automatic URL updater before then you can stop it by calling this method.
+
+#### Usage:
+
+```ts
+sw.location.stopAutoUrlUpdater();
+```
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/notification.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/notification.md
new file mode 100644
index 000000000..1bd4fbb59
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/notification.md
@@ -0,0 +1,50 @@
+# Notification
+
+### Dispatch a notification
+
+![notification example](./assets/notification-example.jpg)
+
+#### Usage:
+```ts
+function alertYes() {
+ alert('Yes');
+}
+
+sw.notification.dispatch({
+ title: 'Your title',
+ message: 'Your message',
+ variant: 'success',
+ appearance: 'notification',
+ growl: true,
+ actions: [
+ {
+ label: 'Yes',
+ method: alertYes
+ },
+ {
+ label: 'No',
+ method: () => {
+ alert('No')
+ }
+ },
+ {
+ label: 'Cancel',
+ route: 'https://www.shopware.com',
+ disabled: false,
+ }
+ ]
+})
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+|:-------------|:---------|:---------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `title` | true | | Defines a notification's **title**. |
+| `message` | true | | Defines a notification's main expression or message to the user. |
+| `variant` | false | `info` | Defines the notification type. Available `variant` types are `success`, `info`, `warning` and `error`. |
+| `appearance` | false | `notification` | Changes the style of a notification. Use `system` for technical notifications thrown by the application. Otherwise keep the default value `notification`. |
+| `growl` | false | `true` | Displays a notification that is overlaying any module. Use `false` to display the notification in the notification center (bell symbol) only. |
+| `actions` | false | `[]` | Adds clickable buttons to the notification. Each button with a `label` can trigger a `method` or open a `route` (internal route or external link). Buttons can also be disabled using the attribute `disabled`. |
+
+#### Return value:
+Returns a promise without data.
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/_category_.yml b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/_category_.yml
new file mode 100644
index 000000000..4dc285165
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/_category_.yml
@@ -0,0 +1,2 @@
+label: "UI"
+position: 100
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/actionButton.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/actionButton.md
new file mode 100644
index 000000000..1982cd5c7
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/actionButton.md
@@ -0,0 +1,55 @@
+# Action button
+
+#### Usage:
+```ts
+import { location, ui } from '@shopware-ag/meteor-admin-sdk';
+
+if (location.is(sw.location.MAIN_HIDDEN)) {
+ ui.actionButton.add({
+ action: 'your-app_customer-detail-action',
+ entity: 'customer',
+ view: 'detail',
+ label: 'Test action',
+ callback: (entity, entityIds) => {
+ // TODO: do something
+ },
+ });
+}
+```
+
+#### Parameters
+| Name | Required | Description |
+| :------------------- | :------- | :--------------------------------------------------------------------------------------------------------- |
+| `action` | true | A unique name of your action |
+| `entity` | true | The entity this action is for possible values: `product`, `order`, `category`, `promotion` or `customer` |
+| `view` | true | Determines if the action button appears on the listing or detail page, possible values: `detail` or `list` |
+| `label` | true | The label of your action button |
+| `callback` | true | The callback function where you receive the entity and the entityIds for further processing |
+
+### Calling app actions
+As an app developer you may want to receive the information of the callback function server side.
+The following example will render the same action button as the above example but once it gets clicked you will receive a POST request to your app server.
+**This will only work for apps. Plugin developers need to use a api client directly in there callback.**.
+
+```ts
+import { location, ui } from '@shopware-ag/meteor-admin-sdk';
+
+if (location.is(sw.location.MAIN_HIDDEN)) {
+ ui.actionButton.add({
+ action: 'your-app_customer-detail-action',
+ entity: 'customer',
+ view: 'detail',
+ label: 'Test action',
+ callback: (entity /* "customer" */, entityIds /* ["..."] */) => {
+ app.webhook.actionExecute({
+ url: 'http://your-app.com/customer-detail-action',
+ entityIds,
+ entity,
+ })
+ },
+ });
+}
+```
+
+#### Example
+![Action button example](./assets/add-action-button-example.png)
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-action-button-example.png b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-action-button-example.png
new file mode 100644
index 000000000..a60208a37
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-action-button-example.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-main-module-example.png b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-main-module-example.png
new file mode 100644
index 000000000..9b9c0c278
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-main-module-example.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-menu-item-example.png b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-menu-item-example.png
new file mode 100644
index 000000000..1466de52b
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-menu-item-example.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-payment-overview-card-example.png b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-payment-overview-card-example.png
new file mode 100644
index 000000000..371499086
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-payment-overview-card-example.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-settings-item-example.png b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-settings-item-example.png
new file mode 100644
index 000000000..ef57c4541
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-settings-item-example.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-tab-item-example.png b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-tab-item-example.png
new file mode 100644
index 000000000..71e57e3d1
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/add-tab-item-example.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/example-card-with-tabs.png b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/example-card-with-tabs.png
new file mode 100644
index 000000000..50a4846a6
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/example-card-with-tabs.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/example-card.png b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/example-card.png
new file mode 100644
index 000000000..67dcea0f1
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/example-card.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/modal-example.png b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/modal-example.png
new file mode 100644
index 000000000..7f2cc3b17
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/assets/modal-example.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/component-section.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/component-section.md
new file mode 100644
index 000000000..380d1d2c8
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/component-section.md
@@ -0,0 +1,88 @@
+# Component Section
+
+## Add
+Add a new component to a component section.
+
+### General usage
+
+#### Usage:
+```ts
+import { ui } from '@shopware-ag/meteor-admin-sdk';
+
+ui.componentSection.add({
+ component: 'the-component', // Choose the component which you want to render at the component section
+ positionId: 'the-position-id-of-the-component-section', // Select the positionId where you want to render the component
+ props: {
+ ... // The properties are depending on the component
+ }
+})
+```
+
+#### Parameters
+| Name | Required | Default | Description |
+| :---------- | :------- | :------ | :--------------------------------------------- |
+| `component` | true | | Choose the component which you want to render. |
+
+#### Return value:
+This method does not have a return value.
+
+## Available components
+
+### Card
+
+#### Properties:
+| Name | Required | Default | Description |
+|:-------------|:---------|:--------|:-----------------------------------|
+| `title` | false | | The main title of the card |
+| `subtitle` | false | | The subtitle of the card |
+| `locationId` | true | | The locationId for the custom view |
+| `tabs` | false | | Render different content with tabs |
+
+#### Usage:
+```js
+import { ui } from '@shopware-ag/meteor-admin-sdk';
+
+ui.componentSection.add({
+ component: 'card',
+ positionId: 'sw-product-properties__before',
+ props: {
+ title: 'Hello from plugin',
+ subtitle: 'I am before the properties card',
+ locationId: 'my-awesome-app-card-before'
+ }
+})
+```
+
+#### Example
+![Card component example](./assets/example-card.png)
+
+#### With tabs:
+```js
+import { ui } from '@shopware-ag/meteor-admin-sdk';
+
+ui.componentSection.add({
+ component: 'card',
+ positionId: 'sw-product-properties__before',
+ props: {
+ title: 'Hello from plugin',
+ subtitle: 'I am before the properties card',
+ locationId: 'my-awesome-app-card-before',
+ // Render tabs and custom tab content with the provided location id
+ tabs: [
+ {
+ name: 'example-tab-1',
+ label: 'First tab',
+ locationId: 'example-tab-1'
+ },
+ {
+ name: 'example-tab',
+ label: 'Second tab',
+ locationId: 'example-tab-2'
+ }
+ ],
+ }
+})
+```
+
+#### Example
+![Card component with tabs example](./assets/example-card-with-tabs.png)
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/mainModule.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/mainModule.md
new file mode 100644
index 000000000..627df818a
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/mainModule.md
@@ -0,0 +1,50 @@
+# Main module
+
+### Add main module
+Add a main module to your extension. The content of the main module is determined by your `locationId`.
+A specific view or a set of actions can be triggered based on the `locationId`.
+
+#### Usage:
+```ts
+ui.mainModule.addMainModule({
+ heading: 'My App',
+ locationId: 'main-location-id',
+});
+```
+
+#### Parameters
+| Name | Required | Default | Description |
+|:------------------------|:---------|:--------|:---------------------------------------|
+| `heading` | true | | The heading displayed in your module |
+| `locationId` | true | | The Id for the content of the module |
+| `displaySearchBar` | false | true | Toggles the sw-page search bar on/off |
+| `displayLanguageSwitch` | false | false | Toggles sw-page language switch on/off |
+
+#### Example
+![Main module example](./assets/add-main-module-example.png)
+```ts
+import { location, ui } from '@shopware-ag/meteor-admin-sdk';
+
+// General commands
+if (location.is(location.MAIN_HIDDEN)) {
+ // Add the main module
+ ui.mainModule.addMainModule({
+ heading: 'My App',
+ locationId: 'main-location-id',
+ });
+
+ // If you want to provide some buttons for the smart bar of your main module
+ ui.mainModule.addSmartbarButton({
+ locationId: 'main-location-id', // locationId of your main module
+ buttonId: 'test-button', // The button id
+ label: 'Click me', // The button label
+ variant: 'primary', // The button variant
+ onClickCallback: () => {}
+ });
+}
+
+// Render your custom view
+if (location.is('main-location-id')) {
+ document.body.innerHTML = '
Hello from your main module
';
+}
+```
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/menuItem.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/menuItem.md
new file mode 100644
index 000000000..c0e9a8d8c
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/menuItem.md
@@ -0,0 +1,46 @@
+# Menu Item
+
+### Add menu item
+Add a new menu item to the Shopware admin menu. The content of the menu item module is determined by your `locationId`.
+A specific view or a set of actions can be triggered based on the `locationId`.
+
+#### Usage:
+```ts
+ui.menu.addMenuItem({
+ label: 'Test item',
+ locationId: 'your-location-id',
+ displaySearchBar: true,
+ parent: 'sw-catalogue',
+})
+```
+
+#### Parameters
+| Name | Required | Default | Description |
+| :------------------- | :------- | :------------- | :------------------------------------------------------------ |
+| `label` | true | | The label of the tab bar item |
+| `locationId` | true | | The id for the content of the menu item module |
+| `displaySearchBar` | false | true | Toggles the sw-page search bar on/off |
+| `parent` | false | 'sw-extension' | Determines under which main menu entry your item is displayed |
+| `position` | false | 110 | Determines the position of your menu item |
+
+#### Example
+![Menu item example](./assets/add-menu-item-example.png)
+```ts
+import { location, ui } from '@shopware-ag/meteor-admin-sdk';
+
+// General commands
+if (location.is(sw.location.MAIN_HIDDEN)) {
+ // Add the menu item to the catalogue module
+ ui.menu.addMenuItem({
+ label: 'Test item',
+ displaySearchBar: true,
+ locationId: 'your-location-id',
+ parent: 'sw-catalogue',
+ });
+}
+
+// Render your custom view
+if (location.is('your-location-id')) {
+ document.body.innerHTML = '
Hello from your menu item
';
+}
+```
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/modals.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/modals.md
new file mode 100644
index 000000000..3bf0f03d0
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/modals.md
@@ -0,0 +1,94 @@
+# Modals
+
+A modal can be displayed in front of all other elements. To return to the main content the user must engage
+with the modal by completing an action or by closing it. It should be mainly opened when the user interacts with something.
+We recommend that no modal gets opened without context. As an example, it would be bad practice if the user gets logged
+in and directly see some modals (e.g. changelogs of extensions) which all need to be closed manually.
+
+### Open modal
+Open a new modal in the current view. The content of the modal is determined by your `locationId`.
+
+#### Usage:
+```ts
+ui.modal.open({
+ title: 'Your modal title',
+ locationId: 'your-location-id',
+ variant: 'large',
+ showHeader: true,
+ showFooter: false,
+ closable: true
+ buttons: [
+ {
+ label: 'Dispatch notification',
+ method: () => {
+ notification.dispatch({
+ message: 'Hello from the modal',
+ title: 'Modal example'
+ })
+ }
+ },
+ {
+ label: 'Close modal',
+ variant: 'primary',
+ method: () => {
+ ui.modal.close({
+ locationId: 'your-location-id'
+ })
+ }
+ }
+ ],
+})
+```
+
+#### Parameters
+| Name | Required | Default | Description | Available at Shopware |
+| :----------- | :------- | :-------- | :--------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------|
+| `title` | true | | The title of the modal | |
+| `locationId` | true | | The id for the content of the modal | |
+| `variant` | false | 'default' | Determine the size of the modal. Possible values are 'default', 'small', 'large' and 'full' | |
+| `showHeader` | false | true | Enable the header in the modal which contains the title | |
+| `showFooter` | false | true | Enable the modal footer | v6.5.8 |
+| `closable` | false | true | If this is set to `false` then the modal can only be closed programmatically | |
+| `buttons` | false | [] | This array contains [button configurations](../../../api/modules/ui_modal.md#buttonprops) which will render buttons in the footer of the modal | |
+
+#### Example
+![Menu item example](./assets/modal-example.png)
+```ts
+ui.modal.open({
+ title: 'Hello from the plugin',
+ locationId: 'my-awesome-app-hello-world-modal',
+ buttons: [
+ {
+ label: 'Dispatch notification',
+ method: () => {
+ notification.dispatch({
+ message: 'Hello from the modal',
+ title: 'Modal plugin'
+ })
+ }
+ },
+ {
+ label: 'Close modal',
+ variant: 'primary',
+ method: () => {
+ ui.modal.close({
+ locationId: 'my-awesome-app-hello-world-modal'
+ })
+ }
+ }
+ ]
+})
+```
+
+### Close modal
+Closes an opened modal. You need use the correct `locationId` of the modal which should get closed.
+
+#### Usage:
+```ts
+ui.modal.close({ locationId: 'your-location-id' })
+```
+
+#### Parameters
+| Name | Required | Default | Description |
+| :----------- | :------- | :------ | :-------------------------------------------------- |
+| `locationId` | true | | The locationId of the modal which should get closed |
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/module/_category_.yml b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/module/_category_.yml
new file mode 100644
index 000000000..997c8a642
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/module/_category_.yml
@@ -0,0 +1 @@
+label: "Extending modules"
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/module/paymentOverviewCard.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/module/paymentOverviewCard.md
new file mode 100644
index 000000000..252f22451
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/module/paymentOverviewCard.md
@@ -0,0 +1,81 @@
+# Payment Overview Cards
+
+### Add a custom payment method overview card in settings
+
+Starting with Shopware 6.4.14.0, you can render a custom card in the new payment method overview.
+With that, you can replace the default card, where you can toggle the active state of a payment method, with your own component.
+This allows you, for example, to require an onboarding to your payment provider before activating the payment method.
+
+### Parameters
+| Name | Required | Default | Description |
+|:------------------------|:---------| :------------- |:------------------------------------------------------------------------------------------------------------------------------------|
+| `positionId` | true | | The position id that is created in the payment overview, where you can add a component section to |
+| `paymentMethodHandlers` | true | | A list of formatted payment method handlers, which are handled by your component and where the default card should not be rendered. |
+| `component` | false | | The component name of you custom payment overview card. Only useful, if you have a plugin with a registered component |
+
+### Extension example
+```ts
+import { ui } from '@shopware-ag/meteor-admin-sdk';
+
+if (sw.location.is(sw.location.MAIN_HIDDEN)) {
+ // create the position
+ ui.module.payment.overviewCard.add({
+ positionId: 'my-custom-payment-overview-position',
+ paymentMethodHandlers: [
+ 'handler_my_custom_payment_method_one',
+ 'handler_my_custom_payment_method_two',
+ // ...
+ ],
+ });
+
+ // add your component to that position
+ ui.componentSection.add({
+ component: 'card',
+ positionId: 'my-custom-payment-overview-position',
+ props: {
+ title: 'My payment provider',
+ subtitle: 'We have all the methods that exist',
+ locationId: 'my-custom-payment-overview-position-before'
+ }
+ })
+}
+
+// render your view to that location
+if (sw.location.is('my-custom-payment-overview-position-before')) {
+ // your content here
+}
+```
+
+### Custom plugin component example
+```ts
+import { ui } from '@shopware-ag/meteor-admin-sdk';
+
+// register a custom component
+Component.register('my-custom-payment-overview-card', {
+ template: ``,// your template here
+ props: {
+ paymentMethods: {
+ type: Array,
+ required: true,
+ },
+ },
+ methods: {
+ async changePaymentMethodActive(paymentMethod) {
+ paymentMethod.active = !paymentMethod.active;
+
+ this.$emit('set-payment-active', paymentMethod);
+ },
+ },
+});
+
+// add that component to the payment overview
+ui.module.payment.overviewCard.add({
+ component: 'my-custom-payment-overview-card',
+ positionId: 'my-custom-payment-overview-position',
+ paymentMethodHandlers: [
+ 'handler_my_custom_payment_method_one',
+ 'handler_my_custom_payment_method_two',
+ // ...
+ ],
+});
+```
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/settingsItem.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/settingsItem.md
new file mode 100644
index 000000000..30261ea58
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/settingsItem.md
@@ -0,0 +1,52 @@
+# Settings Item
+
+### Add settings item
+Add a new settings item to the Shopware settings. The content of the settings item module is determined by your `locationId`.
+A specific view or a set of actions can be triggered based on the `locationId`.
+
+#### Usage:
+```ts
+ui.settings.addSettingsItem({
+ label: 'App Settings',
+ locationId: 'settings-location-id',
+ icon: 'default-object-books',
+ displaySearchBar: true,
+ tab: 'plugins',
+});
+```
+
+#### Parameters
+| Name | Required | Default | Description |
+| :------------------- | :------- | :------------- | :------------------------------------------------------------ |
+| `label` | true | | The label of the tab bar item |
+| `locationId` | true | | The id for the content of the settings item module |
+| `icon` | true | | The icon to display in your settings item |
+| `displaySearchBar` | false | true | Toggles the sw-page search bar on/off |
+| `tab` | false | 'plugins' | Determines in which tab your settings item will be displayed |
+
+### Getting the right icon
+Assuming that your editor supports TypeScript, you should get auto-completion for valid `icon` values.
+In case that doesn't work take a look at the list [here](https://github.com/shopware/meteor-admin-sdk/blob/trunk/src/icons.ts).
+
+#### Example
+![Settings item example](./assets/add-settings-item-example.png)
+```ts
+import { location, ui } from '@shopware-ag/meteor-admin-sdk';
+
+// General commands
+if (location.is(location.MAIN_HIDDEN)) {
+ // Add the settings item to the plugins tab
+ ui.settings.addSettingsItem({
+ label: 'App Settings',
+ locationId: 'settings-location-id',
+ icon: 'default-object-books',
+ displaySearchBar: true,
+ tab: 'plugins',
+ });
+}
+
+// Render your custom view
+if (location.is('settings-location-id')) {
+ document.body.innerHTML = '
Hello from your settings item
';
+}
+```
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/tabs.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/tabs.md
new file mode 100644
index 000000000..df99219e0
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/ui/tabs.md
@@ -0,0 +1,58 @@
+# Tabs
+
+### Add tab item
+Add a new tab item to an existing tab bar. The content of the the new tab item
+contains a component section. This works with tab bar's which have routing and
+also static tab bars. If the tab bar has routing then the route for the tab item
+will be generated automatically.
+
+#### Usage:
+```ts
+import { ui } from '@shopware-ag/meteor-admin-sdk';
+
+ui.tabs('sw-product-detail' /* The positionId of the tab bar*/).addTabItem({
+ label: 'Example tab',
+ componentSectionId: 'example-product-detail-tab-content'
+})
+```
+
+#### Parameters
+| Name | Required | Default | Description |
+| :------------------- | :------- | :------ | :------------------------------------------------------ |
+| `label` | true | | The label of the tab bar item |
+| `componentSectionId` | true | | The Id for for the component section in the tab content |
+
+#### Example
+![Tab item example](./assets/add-tab-item-example.png)
+```ts
+import { ui, location } from '@shopware-ag/meteor-admin-sdk';
+
+// For general commands
+if (location.is(location.MAIN_HIDDEN)) {
+ // Add tab bar item
+ ui.tabs('sw-product-detail').addTabItem({
+ label: 'Example',
+ componentSectionId: 'my-awesome-app-example-product-view'
+ })
+
+ // Add component to the new created section
+ ui.componentSection.add({
+ component: 'card',
+ positionId: 'my-awesome-app-example-product-view',
+ props: {
+ title: 'Hello in the new tab',
+ locationId: 'my-example-product-view-tab-card'
+ }
+ })
+}
+
+// Render custom view of the component
+if (location.is('my-example-product-view-tab-card')) {
+ document.body.innerHTML = '
+
Hello in the example card
+
+ ';
+}
+```
diff --git a/packages/admin-sdk/docs/docs/guide/2_api-reference/window.md b/packages/admin-sdk/docs/docs/guide/2_api-reference/window.md
new file mode 100644
index 000000000..2599b31cf
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/2_api-reference/window.md
@@ -0,0 +1,67 @@
+# Window
+
+### Redirect to another URL
+
+#### Usage:
+```ts
+sw.window.redirect({
+ url: 'https://www.shopware.com,
+ newTab: true
+})
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :------ | :------ | :------ | :------ |
+| `url` | true | | The title of the notification |
+| `newTab` | false | false | The message of the notification |
+
+#### Return value:
+Returns a promise without data.
+
+### Push to another page
+For redirecting to other pages in the admin.
+
+#### Usage:
+The usage matches the Vue Router push capabilities. Here are two examples how to use it for redirecting to your own modules:
+
+```ts
+sw.window.routerPush({
+ name: 'sw.extension.sdk.index',
+ params: {
+ id: 'the_id_of_the_module' // can be get with context.getModuleInformation
+ }
+})
+```
+
+```ts
+sw.window.routerPush({
+ path: `/extension/${the_id_of_the_module}` // id can be get with context.getModuleInformation
+})
+```
+
+#### Parameters:
+| Name | Required | Default | Description |
+| :------ | :------ | :------ | :------ |
+| `name` | false | undefined | The name of the route |
+| `path` | false | undefined | The path of the route |
+| `params` | false | undefined | Additional params for the new route |
+| `replace` | false | false | Should not change the browser history |
+
+#### Return value:
+Returns a promise without data.
+
+### Reload page
+
+Useful for development. You can trigger a page reload on file changes.
+
+#### Usage:
+```ts
+sw.window.reload()
+```
+
+#### Parameters:
+No parameters required.
+
+#### Return value:
+Returns a promise without data.
diff --git a/packages/admin-sdk/docs/docs/guide/3_tooling/_category_.yml b/packages/admin-sdk/docs/docs/guide/3_tooling/_category_.yml
new file mode 100644
index 000000000..546266fb5
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/3_tooling/_category_.yml
@@ -0,0 +1,2 @@
+label: "Tooling"
+position: 75
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-extension-point-selection.png b/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-extension-point-selection.png
new file mode 100644
index 000000000..134cba6a7
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-extension-point-selection.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-settings-list.png b/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-settings-list.png
new file mode 100644
index 000000000..d2abf8c9c
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-settings-list.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-settings.png b/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-settings.png
new file mode 100644
index 000000000..fed98a9aa
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-settings.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-tab-shopware-extension.png b/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-tab-shopware-extension.png
new file mode 100644
index 000000000..abedb68e3
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/3_tooling/assets/devtools-plugin-tab-shopware-extension.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/3_tooling/vue-devtools.md b/packages/admin-sdk/docs/docs/guide/3_tooling/vue-devtools.md
new file mode 100644
index 000000000..d73127c2a
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/3_tooling/vue-devtools.md
@@ -0,0 +1,34 @@
+---
+title: "Vue Devtools"
+sidebar_position: 1
+---
+
+# Vue Devtools
+The administration has many extension capabilties. Many of them are components with an unique positionId. It can be
+difficult to find out their id to extend them. You need to manually look in the core source code to find out the id.
+
+The better way is using the Vue devtools plugin. It is preinstalled in every Shopware administration so that you can
+find out the ids in an interactive and visual way.
+
+## Prerequisites:
+You need to have the Vue Devtools installed. The plugin API for the Vue Devtools is only available in the versions 6+ (Currently only in the [beta channel](https://chrome.google.com/webstore/detail/vuejs-devtools/ljjemllljcmogpfapbkkighbhhppjdbg). You can install both parallel.). If you are using an older version then this plugin will not work.
+
+After installing the browser extensions you should be able to open the devtools in the development/watch mode of the administration. To check if the admin plugin works you can go to the settings and check if the Shopware Admin plugin is installed and enabled:
+
+![Vue Devtools plugin settings](./assets/devtools-plugin-settings.png)
+
+![Vue Devtools plugin settings list](./assets/devtools-plugin-settings-list.png)
+
+## Finding extension capabilites
+Navigate to the page which you want to extend. In our example we go to the product detail page in the tab specifications.
+
+Now you can open the plugin in the top dropdown menu:
+
+![Vue Devtools plugin tab Shopware extension](./assets/devtools-plugin-tab-shopware-extension.png)
+
+You should see a list on the left side where all extension capabilities are listed. If you click on any of them you will directly see them highlighted in the administration.
+
+![Vue Devtools plugin extension point selection](./assets/devtools-plugin-extension-point-selection.png)
+
+In the inspector of the devtools you will see more information about the extension point. You can see the `Property` value which you can look in the API Reference documentation. Then you know how to use your selected extension point and which capabilities are available. And in most cases you need the `positionId` which is also shown in the inspector. The positionId is a unique identifer so that you extend not every area but only your selected one.
+
diff --git a/packages/admin-sdk/docs/docs/guide/4_concepts/_category_.yml b/packages/admin-sdk/docs/docs/guide/4_concepts/_category_.yml
new file mode 100644
index 000000000..9b30a37fa
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/4_concepts/_category_.yml
@@ -0,0 +1,2 @@
+label: "Concepts"
+position: 500
\ No newline at end of file
diff --git a/packages/admin-sdk/docs/docs/guide/4_concepts/assets/auto-resizer.gif b/packages/admin-sdk/docs/docs/guide/4_concepts/assets/auto-resizer.gif
new file mode 100644
index 000000000..c20bc19f4
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/4_concepts/assets/auto-resizer.gif differ
diff --git a/packages/admin-sdk/docs/docs/guide/4_concepts/assets/component-sections-example.png b/packages/admin-sdk/docs/docs/guide/4_concepts/assets/component-sections-example.png
new file mode 100644
index 000000000..912dfde74
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/4_concepts/assets/component-sections-example.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/4_concepts/assets/component-sections-with-tabs-example.png b/packages/admin-sdk/docs/docs/guide/4_concepts/assets/component-sections-with-tabs-example.png
new file mode 100644
index 000000000..6668c0abb
Binary files /dev/null and b/packages/admin-sdk/docs/docs/guide/4_concepts/assets/component-sections-with-tabs-example.png differ
diff --git a/packages/admin-sdk/docs/docs/guide/4_concepts/component-sections.md b/packages/admin-sdk/docs/docs/guide/4_concepts/component-sections.md
new file mode 100644
index 000000000..232222905
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/4_concepts/component-sections.md
@@ -0,0 +1,74 @@
+# Component sections
+
+In most cases extension developers will directly use the extension capabilities of the UI components (e.g. adding tab items, adding button to grid, ...). This will cover most needs of many extensions. But in cases where a extension need special solutions which aren't feasible with the given extension they can use a feature named `Component Sections`. These are sections where any extension developer can inject components.
+
+These components are prebuilt (like cards) and contain in most cases custom [location](./locations.md) where the extension has the full freedom to render anything.
+
+### Example:
+
+```js
+if (location.is(location.MAIN_HIDDEN)) {
+ // Choose a position id where you want to render a custom component
+ sw.ui.componentSection('sw-manufacturer-card-custom-fields__before').add({
+ // The Component Sections provides different components out of the box
+ component: 'card',
+ // Props are depending on the type of component
+ props: {
+ title: 'Hello from plugin',
+ subtitle: 'I am before the properties card',
+ // Some components can render a custom view. In this case the extension can render custom content in the card.
+ locationId: 'my-app-card-before-properties'
+ }
+ })
+}
+
+// Render the custom UI when the iFrame location matches your defined location
+if (sw.location.is('my-app-card-before-properties')) {
+ document.body.innerHTML = '
Hello World before
';
+ document.body.style.background = 'blue';
+}
+```
+
+![Component Sections screenshot example](./assets/component-sections-example.png)
+
+If you want to render tabs inside the `card` component section, we provide a way to do so:
+```js
+if (location.is(location.MAIN_HIDDEN)) {
+ // Choose a position id where you want to render a custom component
+ sw.ui.componentSection.add({
+ // The Component Sections provides different components out of the box
+ component: 'card',
+ // Props are depending on the type of component
+ props: {
+ title: 'Hello from plugin',
+ subtitle: 'I am before the properties card',
+ // Render tabs and custom tab content with the provided location id
+ tabs: [
+ {
+ name: 'example-tab-1',
+ label: 'First tab',
+ locationId: 'example-tab-1'
+ },
+ {
+ name: 'example-tab',
+ label: 'Second tab',
+ locationId: 'example-tab-2'
+ }
+ ],
+ }
+ })
+}
+
+// Render the custom UI for different tab with the location id
+if (sw.location.is('example-tab-1')) {
+ document.body.innerHTML = '
';
+ document.body.style.background = 'yellow';
+}
+```
+
+![Component Sections screenshot example](./assets/component-sections-with-tabs-example.png)
diff --git a/packages/admin-sdk/docs/docs/guide/4_concepts/locations.md b/packages/admin-sdk/docs/docs/guide/4_concepts/locations.md
new file mode 100644
index 000000000..343096684
--- /dev/null
+++ b/packages/admin-sdk/docs/docs/guide/4_concepts/locations.md
@@ -0,0 +1,120 @@
+# Locations
+
+Extensions can render custom views via iFrames. To support multiple views in different places every `location` of the iFrame gets a unique ID. These can be defined by the extension developer itself.
+
+*Example:*
+
+A extension wants to render a custom iFrame in a card in the dashboard. The `location` of the iFrame has then a specific `locationId` like `sw-dashboard-example-app-dashboard-card`. The app can also render another iFrames which also get `locationId`s. In our example it is a iFrame in a custom modal: `example-app-example-modal-content`.
+
+The extension want to render different views depending on the `location` of the iFrame. So the extension developer can render the correct view depending on the `locationId`:
+```js
+// Add the ui extensions when your extension is loaded in the hidden iFrame
+if (location.is(location.MAIN_HIDDEN)) {
+ ui.componentSection.add({
+ component: 'card',
+ positionId: 'sw-product-properties__before',
+ props: {
+ title: 'Hello from plugin',
+ subtitle: 'I am before the properties card',
+ /**
+ * The locationId:
+ **/
+ locationId: 'my-app-card-before-properties'
+ }
+ })
+}
+
+// Render the custom UI when the iFrame location matches your defined location
+if (sw.location.is('my-app-card-before-properties')) {
+ document.body.innerHTML = '
I am the in the location "my-app-card-before-properties"