diff --git a/apps/docs/src/getting-started/e-commerce/product-listing.md b/apps/docs/src/getting-started/e-commerce/product-listing.md
index 82acced42..c5933d0cd 100644
--- a/apps/docs/src/getting-started/e-commerce/product-listing.md
+++ b/apps/docs/src/getting-started/e-commerce/product-listing.md
@@ -7,7 +7,7 @@ nav:
In this chapter you will learn how to
-- Initialize the `useListing` composable
+- Use the modular listing composables (`useListingCore`, `useProductListingFilters`, `useProductListingPagination`, `useProductListingSorting`)
- Search for products
- Display products in a listing
- Implement a pagination
@@ -15,6 +15,60 @@ In this chapter you will learn how to
- Use the `helpers` package
- Configure variants presentation for store API
+## Modular listing composables
+
+The listing logic is split into focused, modular composables that can be used independently:
+
+| Composable | Responsibility |
+| -------------------------------- | --------------------------------------------- |
+| `useListingCore` | Core state, search, loadMore, initial listing |
+| `useProductListingFilters` | Filter management (get, set, reset) |
+| `useProductListingPagination` | Page navigation |
+| `useProductListingSorting` | Sort order management |
+
+These composables work via Vue's `provide`/`inject`. A parent component sets up the listing context, and child components consume specific concerns.
+
+**Parent component** — creates the listing context (e.g. `CmsPage`):
+
+```vue
+
+```
+
+**Child component** — uses the modular composables to access specific concerns:
+
+```vue
+
+```
+
+**Search page** — for product search, use the shared composable:
+
+```vue
+
+```
+
## Listing context
Product listing is a structure related to the predefined areas and it has always the same interface: `ProductListingResult`:
@@ -25,6 +79,10 @@ Product listing is a structure related to the predefined areas and it has always
## Listing type and context
+:::warning Deprecated
+`useListing` is deprecated. Use `useListingCore` with the modular composables (`useProductListingFilters`, `useProductListingPagination`, `useProductListingSorting`) instead.
+:::
+
Before using the composable, define the type related to the context:
- `categoryListing` for navigation/category/cms pages
@@ -105,11 +163,28 @@ search({ // invoke search() method
## Sorting
-Available methods of `useListing` to manage sorting order:
+Available methods to manage sorting order:
+
+- `getSortingOrders` - returns all available sorting options
+- `getCurrentSortingOrder` - returns the current order, available in the response
+- `changeCurrentSortingOrder` - sets the new order, invoking a `search` method internally
+
+Using the modular composable (recommended):
+
+```ts
+// part of
{{ getCurrentFilters.navigationId }}
diff --git a/packages/cms-base-layer/app/components/SwProductListingFilters.vue b/packages/cms-base-layer/app/components/SwProductListingFilters.vue
index f102bba42..5b3001569 100644
--- a/packages/cms-base-layer/app/components/SwProductListingFilters.vue
+++ b/packages/cms-base-layer/app/components/SwProductListingFilters.vue
@@ -3,12 +3,16 @@ import type {
CmsElementProductListing,
CmsElementSidebarFilter,
} from "@shopware/composables";
-import { useCmsTranslations } from "@shopware/composables";
+import {
+ useCmsTranslations,
+ useListingCoreContext,
+ useProductListingFilters,
+ useProductListingSorting,
+} from "@shopware/composables";
import { defu } from "defu";
import { computed, reactive } from "vue";
import type { ComputedRef, UnwrapNestedRefs } from "vue";
import { type LocationQueryRaw, useRoute, useRouter } from "vue-router";
-import { useCategoryListing } from "#imports";
import type { Schemas, operations } from "#shopware";
const props = defineProps<{
@@ -46,14 +50,10 @@ translations = defu(useCmsTranslations(), translations) as Translations;
const route = useRoute();
const router = useRouter();
-const {
- changeCurrentSortingOrder,
- getCurrentFilters,
- getCurrentSortingOrder,
- getInitialFilters,
- getSortingOrders,
- search,
-} = useCategoryListing();
+const { search } = useListingCoreContext();
+const { getInitialFilters, getCurrentFilters } = useProductListingFilters();
+const { getSortingOrders, getCurrentSortingOrder, changeCurrentSortingOrder } =
+ useProductListingSorting();
const sidebarSelectedFilters: UnwrapNestedRefs =
reactive({
diff --git a/packages/cms-base-layer/app/components/SwProductListingFiltersHorizontal.vue b/packages/cms-base-layer/app/components/SwProductListingFiltersHorizontal.vue
index a2152d6ea..48f5b360b 100644
--- a/packages/cms-base-layer/app/components/SwProductListingFiltersHorizontal.vue
+++ b/packages/cms-base-layer/app/components/SwProductListingFiltersHorizontal.vue
@@ -3,12 +3,16 @@ import type {
CmsElementProductListing,
CmsElementSidebarFilter,
} from "@shopware/composables";
-import { useCmsTranslations } from "@shopware/composables";
+import {
+ useCmsTranslations,
+ useListingCoreContext,
+ useProductListingFilters,
+ useProductListingSorting,
+} from "@shopware/composables";
import { defu } from "defu";
import { computed, reactive } from "vue";
import type { ComputedRef, UnwrapNestedRefs } from "vue";
import { type LocationQueryRaw, useRoute, useRouter } from "vue-router";
-import { useCategoryListing } from "#imports";
import type { Schemas, operations } from "#shopware";
const props = defineProps<{
@@ -46,13 +50,10 @@ translations = defu(useCmsTranslations(), translations) as Translations;
const route = useRoute();
const router = useRouter();
-const {
- changeCurrentSortingOrder,
- getCurrentSortingOrder,
- getInitialFilters,
- getSortingOrders,
- search,
-} = useCategoryListing();
+const { search } = useListingCoreContext();
+const { getInitialFilters } = useProductListingFilters();
+const { getSortingOrders, getCurrentSortingOrder, changeCurrentSortingOrder } =
+ useProductListingSorting();
const sidebarSelectedFilters: UnwrapNestedRefs =
reactive({
diff --git a/packages/cms-base-layer/app/components/public/cms/element/CmsElementProductListing.vue b/packages/cms-base-layer/app/components/public/cms/element/CmsElementProductListing.vue
index c0d174eba..1f1201f9f 100644
--- a/packages/cms-base-layer/app/components/public/cms/element/CmsElementProductListing.vue
+++ b/packages/cms-base-layer/app/components/public/cms/element/CmsElementProductListing.vue
@@ -1,10 +1,14 @@