> Portal Navigation:
>
> - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version.
> - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages).
> - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`).
> - Top-level index of all portals: https://dev.wix.com/docs/llms.txt
> - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt
## Resource: Nest Dynamic Repeaters
## Article: Nest Dynamic Repeaters
## Article Link: https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/cms-collections-in-blocks/nest-dynamic-repeaters.md
## Article Content:
# Nesting Dynamic Repeaters
**Editor compatibility**
Wix Blocks apps aren't supported in the Wix Harmony editor. Existing Blocks apps remain available for purchase on the Wix App Market for Wix Editor and Wix Studio sites. To learn more, see [About Wix Harmony and Blocks](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/about-wix-harmony-and-blocks.md).
[Dynamic repeaters](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/cms-collections-in-blocks/dynamic-repeaters-in-blocks.md) are repeaters that are intended to get their content dynamically. This means that their content can only come through a connection to a CMS collection, or through code. You cannot edit the content of each individual item directly on the canvas.
Example:
Try out the [Coffee catalog tutorial](https://dev.wix.com/docs/build-apps/get-started/tutorials/tutorial-create-a-coffee-catalog-with-blocks.md), which uses nested dynamic repeaters.
There are several ways to nest a dynamic repeater in another dynamic repeater. We recommend using nested widgets and drilling their properties.
This article uses a menu app as an example. Here is the app structure:
- Several menu sections, such as appetizers, main courses, desserts.
- Every section contains several dishes, such as salad, pasta, chocolate cake.
There are two collections in the app:
- `MenuSections`: The outer collection, which stores sections.
- `RestaurantDishes`: The inner one, which stores dishes.
Here's what the general structure of the app looks like:

## Option 1 Recommended | Two nested widgets and prop drilling
In this option uses [nested widgets](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/site-widgets/add-nested-widgets-in-blocks.md). The app has three widgets:
- `menuWidget`: The top level widget, representing the entire menu.
- `sectionWidget`: Represents each section and is nested in `menuWidget`.
- `dishWidget`: Represents each individual dish and is nested in `sectionWidget`
### Top level widget: menuWidget
The top level widget, `menuWidget` holds a repeater with the menu sections. It connects this repeater to the `MenuSections` collection using [no code](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/cms-collections-in-blocks/connect-elements-to-collection-fields-with-no-code.md).
Since `sectionWidget` (the second level widget), has a repeater that connects to the `RestaurantDishes` collection, the top level widget can query both collections at once, using the `include()` method. All the information is then passed to the nested widgets through prop drilling.
Here is the code for `menuWidget`:
```js
import { items } from '@wix/data';
$w.onReady(async function () {
//Passing the data from the repeater to the properties of the nested widget
$w('#sections').onItemReady(($item, data) => {
$item('#sectionWidget').dishes = data.dishes1;
$item('#sectionWidget').sectionTitle = data.title;
});
// Querying both collections using include
const {result} = await items.query('@eg/my-new-app-504/MenuSections').include('dishes1').find();
$w('#sections').data = result.items;
});
```
See deprecated wix-data example
```js
import wixData from 'wix-data';
$w.onReady(async function () {
//Passing the data from the repeater to the properties of the nested widget
$w('#sections').onItemReady(($item, data) => {
$item('#sectionWidget').dishes = data.dishes1;
$item('#sectionWidget').sectionTitle = data.title;
});
// Querying both collections using include()
const {items} = await wixData.query('@eg/my-new-app-504/MenuSections').include('dishes1').find();
$w('#sections').data = items;
});
```
### Second level widget: sectionWidget
The `sectionWidget` has two [widget properties](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/widget-api/blocks-widget-properties.md):
- `dishes [Dish]`: A list of properties of a [custom type](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/widget-api/custom-type-properties-blocks.md) representing a dish.
- `sectionTitle`: A text property for the section's title.

Here is the code for `sectionWidget`:
```js
$w.onReady(() => {
$w('#dishes').onItemReady(($item, data) => {
$item('#dish1').title = data.title;
$item('#dish1').description = data.description;
$item('#dish1').image = data.image;
})
$w('#dishes').data = $widget.props.dishes || [];
});
$widget.onPropsChanged(() => {
$w('#sectionTitle').text = $widget.props.sectionTitle;
$w('#dishes').data = $widget.props.dishes || [];
});
```
### Third level widget: dishWidget
The `dishWidget` has three simple properties:
- `title`: Text property for the dish name.
- `description`: Text property for the dish description.
- `image`: Image property for the dish.
This is the code for `dishWidget`:
```js
const syncWidget = () => {
const { title, description, image } = $widget.props;
$w('#title').text = title;
$w('#description').text = description;
$w('#imageX1').src = image;
}
$w.onReady(function () {
syncWidget()
});
$widget.onPropsChanged(() => {
syncWidget()
});
```
## Option 2 | One nested widget
For this option, the app structure is simplified:
- `menuWidget`: The top-level widget with a repeater connected to the main `MenuSections` collection.
- `sectionWidget`: A nested widget with a repeater connected to the `RestaurantDishes` collection.
- The nested widget has two [widget properties](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/widget-api/blocks-widget-properties.md): `sectionId` and `sectionTitle`.
Both repeaters connect their elements (texts and images) to their respective collections [with no code](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/cms-collections-in-blocks/connect-elements-to-collection-fields-with-no-code.md).
### Top level widget: menuWidget
The `menuWidget` uses code to pass the `sectionId` and `sectionTitle` to the nested widget, as widget properties cannot be connected to data with no code.
Notice that since the repeater is connected to a collection with no code, you can call `onItemReady()` without setting the repeater data explicitly.
Here is the code for `menuWidget`:
```js
$w.onReady(function () {
$w('#sections').onItemReady(($item, {_id, title}) => {
$item('#section').sectionId = _id;
$item('#section').sectionTitle = title;
});
});
```
### Nested widget: sectionWidget
The `sectionWidget` filters the repeater with the `sectionId` and displays only the relevant dishes.
Here is the code for `sectionWidget` (note that to use filter with a dataset, we need to use Velo and not SDK):
```js
import { filter } from 'wix-data';
$widget.onPropsChanged(() => {
const { sectionId, sectionTitle } = $widget.props;
$w('#sectionTitle').text = sectionTitle;
const sectionFilter = filter().hasSome('MenuSections_dishes1', sectionId);
$w('#dataset1').setFilter(sectionFilter);
});
```
Notice that because the repeaters are nested, each of the collections receives a field that references to the dataset of the other collection.

## Option 3 | Code-only solution with one widget
This option uses a single widget with nested repeaters.
This is the widget structure:
- The top level repeater is `sections`. It connects to the `MenuSections` collection.
- The nested repeater is `dishes`. It connects to the `RestaurantDishes` collection.
The following query fetches the data from both collections, using the `include()` method.
Here is the widget code:
```js
import { items } from '@wix/data';
$w.onReady(async function () {
$w('#dishes').onItemReady(($item, data) => {
$item('#dish').title = data.title;
$item('#dish').description = data.description;
$item('#dish').image = data.image;
});
$w('#sections').onItemReady(($item, data) => {
$item('#dishes').data = data.dishes1;
$item('#sectionTitle').text = data.title;
//Set data from the collection to the widget props
});
// Query both collections - dishes1 is the dataset of the RestaurantDishes collection
const {result} = await items.query('@eg/my-new-app-504/MenuSections').include('dishes1').find();
$w('#sections').data = result.items;
});
```
See deprecated wix-data example
```js
import wixData from 'wix-data';
$w.onReady(async function () {
$w('#dishes').onItemReady(($item, data) => {
$item('#dish').title = data.title;
$item('#dish').description = data.description;
$item('#dish').image = data.image;
});
$w('#sections').onItemReady(($item, data) => {
$item('#dishes').data = data.dishes1;
$item('#sectionTitle').text = data.title;
//Set data from the collection to the widget props
});
const {items} = await wixData.query('@eg/my-new-app-504/MenuSections').include('dishes1').find();
$w('#sections').data = items;
// Query both collections. `dishes1` is the dataset of the `RestaurantDishes` collection
});
```