---
schema_version: "1"
id: 6e6e3ac32dde313699bb006019e0ba799a3c0855c4f64a0614685ef397f8b894
title: Dynamic List Container (Developer Preview)
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/lightning-base-components/lightning-design-system/guides/lwc/components/lightning/dynamicListContainer/lightning-dynamic-list-container.md
canonical_url: https://developer.salesforce.com/docs/platform/lightning-component-reference/guide/lightning-dynamic-list-container.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 2ca7e9987d3ca1b37e6dfc6a61ae8d67c4b22000f0bca1ccb6a2f39f1bf7e93a
products:
  - Lightning Component Reference
---

# Dynamic List Container (Developer Preview)

**`lightning-dynamic-list-container`**

Represents a list that renders using virtualization, presenting only a portion of the list at a time. This component requires API version 67.0 or later. To use this component, select the Dev channel in [Salesforce Release Manager](https://help.salesforce.com/s/articleView?id=xcloud.release_manager.htm).

**For Use In**

Lightning Experience, Experience Builder Sites, Salesforce Mobile App, Lightning Out (Beta), Standalone Lightning App, Mobile Offline

::::::tabset{tabs='["Example", "Develop", "Specifications"]'}

:::::tab

::component-playground{component="dynamicListContainer" model="lwc" namespace="lightning"}


:::::

:::::tab

**note:** Working with dynamic lists is available as a developer preview. This feature isn’t generally available unless or until Salesforce announces its general availability in documentation or in press releases or public statements. All commands, parameters, and other features are subject to change or deprecation at any time, with or without notice. Don't implement functionality in production with these commands or tools.

The `lightning-dynamic-list-container` component renders a portion of a list at a time by using intelligent virtualization. This component is useful for large datasets where you don't want to render the entire list all at once in the DOM. It can improve browser performance, reduce memory usage, and speed up user interactions in large lists.

Use `lightning-dynamic-list-container` with the [`lightning-dynamic-list-item` component]().

## Usage

**important:** To use dynamic lists, opt in to the Dev channel in [Salesforce Release Manager](https://help.salesforce.com/s/articleView?id=xcloud.release_manager.htm).

To implement your list using `lightning-dynamic-list-container`, consider the roles of these key wrapper components:

1. `lightning-dynamic-list-container`: the parent wrapper responsible for managing overall list rendering and slicing data based on the user's scroll position.
2. `lightning-dynamic-list-item`: the child wrapper representing each individual row, dynamically positioned by the container based on the current scroll position.

Both wrappers use `<slot>`, allowing them to wrap various list implementations and row types.

To create a dynamic list:

- Enclose all rows with `lightning-dynamic-list-container`.
- Enclose each row with `lightning-dynamic-list-item`, passing a unique identifier using the `item-id` attribute.
- Place both `lightning-dynamic-list-container` and `lightning-dynamic-list-item` in the same LWC template.
- Pass the full list data to `lightning-dynamic-list-container` using the `list-items` attribute.

<!-- prettier-ignore -->
```html
<template>
    <!--
        Scrollable behavior is managed by dynamicListContainer.
        Don't add scrollable classes, such as slds-scrollable_y.
    -->
    <div class="list-container">
        <lightning-dynamic-list-container
            lwc:ref="dynamicListContainer"
            list-items={listItems}
            onrenderlistitems={handleRenderListItems}
        >
            <template for:each={listItemsToRender} for:item="item">
                <lightning-dynamic-list-item key={item.id} item-id={item.id}>
                    <div>Your Custom Row Content</div>
                </lightning-dynamic-list-item>
            </template>
            <footer slot="footer">
                <div>Your Custom List Footer</div>
            </footer>
        </lightning-dynamic-list-container>
    </div>
</template>
```

Make sure that there are no components or elements between adjacent `lightning-dynamic-list-item` components, or between the container and the first `lightning-dynamic-list-item`. You don't need to configure custom scrolling such as `overflow: scroll` or similar styles from your list container. Scrolling is handled by `lightning-dynamic-list-container`.

To manage rendering of lists as you scroll, handle the `renderlistitems` event from `lightning-dynamic-list-container`. Extract `listItemsToRender` from the event detail to get the subset of list data to render in the DOM. The component automatically positions each row.

```javascript
import { LightningElement, api } from "lwc";

export default class MyDynamicList extends LightningElement {
  _listItemsToRender = [];

  // The full list data
  @api listItems;

  get listItemsToRender() {
    return this._listItemsToRender;
  }

  handleRenderListItems(event) {
    // The component tells you which items to render
    this._listItemsToRender = event.detail.listItemsToRender;
  }
}
```

`lightning-dynamic-list-container` requires a bounded height for the list. Make sure that at least one ancestor of `lightning-dynamic-list-container` has an explicit height in pixels, percentage, or viewport units. The scrollable viewport expands to fill the height of its nearest ancestor with a defined height.

```css
.list-container {
  height: 400px; /* fixed and bounded  */
}

.list-container {
  max-height: 80vh; /* bounded by the viewport height */
}
```

When building your lists, avoid padding on elements between `lightning-dynamic-list-container` and `lightning-dynamic-list-item`. Use margin on rows wrapped by `lightning-dynamic-list-item` for spacing between rows and between rows and container.

## Virtualization

The `lightning-dynamic-list-container` component implements intelligent virtualization with these behaviors.

- **Renders only visible items**: Only the rows currently visible in the viewport with a small buffer are rendered in the DOM. The component adds rows and removes them from the DOM as you scroll.
- **Supports variable row heights**: Rows can have different heights, and the component automatically recalculates positions as needed.
- **Maintains smooth scrolling**: Uses scroll anchoring to ensure a smooth scrolling experience during virtualization.
- **Handles dynamic list changes efficiently:**
  - Rows can be resized individually or collectively.
  - Rows can be added or removed at any position in the list.
  - The list container itself can be resized.

## Load More Rows

To load more rows when the user scrolls to the end of the list, you can either add a `load more` button using the `footer` slot or listen for the `loadmore` event dispatched by the `lightning-dynamic-list-container`. If you append new list items to the existing list, reassign the list to trigger reactivity.

<!-- prettier-ignore -->
```html
<template>
    <div class="list-container">
        <!--
            Display the spinner above the DynamicList.
            Don't remove or re-create DynamicListContainer when loading more rows.
        -->
        <template if:true={isLoading}>
            <lightning-spinner></lightning-spinner>
        </template>
        <lightning-dynamic-list-container
            lwc:ref="dynamicListContainer"
            list-items={listItems}
            onrenderlistitems={handleRenderListItems}
            onloadmore={handleLoadMore}
        >
            <template for:each={listItemsToRender} for:item="item">
                <lightning-dynamic-list-item key={item.id} item-id={item.id}>
                    <div>Your Custom Row Content</div>
                </lightning-dynamic-list-item>
            </template>
        </lightning-dynamic-list-container>
    </div>
</template>
```

The example uses static content for the list items. For an example that loads record data from your org, see the [`lightning-dynamic-list-item` documentation](/docs/platform/lightning-component-reference/guide/lightning-dynamic-list-item.html).

To add a loading screen while loading more rows, such as with `lightning-spinner`, display the spinner above the `lightning-dynamic-list-container` rather than replacing it. Don't remove or re-create the `lightning-dynamic-list-container` when loading more rows.

```javascript
import { LightningElement, api } from "lwc";

export default class MyDynamicList extends LightningElement {
  _listItems = [];
  _listItemsToRender = [];
  _isLoading = false;

  get listItemsToRender() {
    return this._listItemsToRender;
  }

  get isLoading() {
    return this._isLoading;
  }

  handleRenderListItems(event) {
    this._listItemsToRender = event.detail.listItemsToRender;
  }

  handleLoadMore(event) {
    const startOffset = event.detail.startOffset;
    this._generateListItems();
    // Make sure to reassign to listItems for reactivity
    this._listItems = [...this._listItems];
  }

  connectedCallback() {
    this._generateListItems();
  }

  _generateListItems() {
    this._isLoading = true;
    for (let i = 0; i < 500; i++) {
      this._listItems.push({
        id: this._listItems.length,
      });
    }
    this._isLoading = false;
  }
}
```

**note:** This example uses a mock list. For an example that uses record data, see the [`lightning-dynamic-list-item` documentation](/docs/platform/lightning-component-reference/guide/lightning-dynamic-list-item.html).

Make sure that the component defines an explicit height.

```css
.list-container {
  height: 400px; /* or any bounded value */
  position: relative; /* ensure spinner is positioned correctly */
}
```

## List Filtering and Search

If the list is filtered, such as after a search, call the `reset()` method on `lightning-dynamic-list-container` before updating the list data. This ensures the internal cache is cleared and new rows are rendered from the beginning.

```javascript
import { LightningElement, api } from "lwc";

export default class MyDynamicList extends LightningElement {
  _listData;
  _filteredListData = [];
  _listItemsToRender = [];

  @api
  get listData() {
    return this._filteredListData;
  }

  set listData(value) {
    if (Array.isArray(value)) {
      this._listData = value;
      this._filteredListData = value;
    }
  }

  get listItemsToRender() {
    return this._listItemsToRender;
  }

  handleRenderListItems(event) {
    this._listItemsToRender = event.detail.listItemsToRender;
  }

  handleSearch(event) {
    // Call the reset method before setting the new list data
    this.refs.dynamicListContainer.reset();
    this._filteredListData = this._listData.filter((data) => {
      // Custom filter logic
    });
  }
}
```

## Scroll a Row Into View

To scroll a specific row into view, use the `scrollRowIntoView()` method on `lightning-dynamic-list-container`. Pass the target row index as the first argument and an optional config object as the second. By default, scrolling is instant and focus remains unchanged. To enable smooth scrolling and move focus to the row, set `behavior: 'smooth'` and `focus: true` in the config.

```javascript
import { LightningElement, api } from "lwc";

export default class MyDynamicList extends LightningElement {
  _listItemsToRender = [];

  // The full list data
  @api listItems;

  get listItemsToRender() {
    return this._listItemsToRender;
  }

  handleRenderListItems(event) {
    this._listItemsToRender = event.detail.listItemsToRender;
  }

  handleScrollRowIntoView(targetRowIndex) {
    this.refs.dynamicListContainer.scrollRowIntoView(targetRowIndex, {
      behavior: "smooth",
      focus: true,
    });
  }
}
```

## Configure ARIA Role Assignment

By default, `lightning-dynamic-list-container` follows standard list semantics to ensure accessibility for screen readers. When `disableAutoListSemantics` is `false` (default), the component automatically assigns these roles:

- Container Level: The viewport or main container is assigned `role="list"`.
- Item Level: Each list item is assigned `role="listitem"`.

To change the role to `presentation`, set `disableAutoListSemantics` to `true`. This configuration is useful when the `lightning-dynamic-list-container` component is nested inside other components that already provide their own ARIA context, preventing redundant or conflicting screen reader announcements.

## Configure Keyboard Navigation Support

By default, `lightning-dynamic-list-container` handles keydown events. To disable keyboard support, set `disableKeyboardSupport = true`. When `disableKeyboardSupport = true`, these features are deactivated:

- Arrow Key Navigation: Users can't move focus between list items using the Up Arrow and Down Arrow keys.
- Home and End Keys: Shortcuts to jump to the first or last item in the list are disabled.
- Page Up and Down Keys: The ability to scroll through the list in "pages" via the keyboard is removed.
- Focus Tracking: The internal keyboard state doesn't update the index for focused item based on user key presses.

When `disableKeyboardSupport` is `true`, screen reader users can still navigate the list using their standard virtual cursor when `disableAutoListSemantics` remains `false`. This property only affects the active keyboard event listeners managed by the component. This configuration is useful in these use cases:

- Custom Key Handlers: If your application requires specific, non-standard keyboard interactions that conflict with the default list navigation, you can disable the internal support and implement your own listener on a wrapper element.
- Read-Only Lists: In scenarios where the list is decorative or informational and doesn't contain interactive elements, disabling keyboard support can prevent accidental focus traps.
- Nested Interactivity: If the list items themselves contain complex widgets that manage their own internal focus and key events, you can disable the container-level support to avoid "bubbling" conflicts.

## Focus Tracking and Preservation

Unlike other virtualization frameworks, `lightning-dynamic-list-container` ensures that system focus is always preserved, even if the row with system focus is no longer visible in the viewport. This critical feature provides:

- **Focus Tracking**: Keeps track of which row has focus even when it's not rendered.
- **Focus Restoration**: Ensures the row with focus is rendered in the DOM after a repaint, and programmatically restores focus to the row.

## Usage Considerations

1. If a user focuses on any element within a row—other than the first focusable element—then scrolls the row out of view and later scrolls back, the component restores focus to the first focusable element in that row, not the originally focused element. The same behavior occurs if the user presses the Tab or Shift+Tab keys while the focused row is out of view.
2. When a user scrolls quickly, multiple scroll events are fired in rapid succession. To improve performance, `lightning-dynamic-list` processes only the last event captured. This can result in a temporary blank screen during fast scrolling, with content appearing only after scrolling stops.

## Accessibility

`lightning-dynamic-list-container` provides comprehensive accessibility and keyboard navigation support out of the box.

- **Arrow Key Navigation**: Use the Up Arrow and Down Arrow keys to navigate between rows, even if the focused row isn't currently visible.
- **Home/End Key Navigation**: Jump to the first or last row in the list, even if those rows are not currently visible.
- **Semantic List Support**: Automatically adds appropriate ARIA roles (`list`, `listitem`, `presentation`) to maintain semantic structure and provides `aria-setsize` and `aria-posinset` attributes for proper list item positioning information.
- **Browse Mode Detection**: Detects when users navigate using screen reader browse mode (where system focus and cursor aren't synchronized) and provides live announcements to suggest switching to focus mode.
- **Screen Reader Support**: Supports JAWS, NVDA, and VoiceOver screen readers.

## Custom Events

**`loadmore`**

The event that's fired when the user scrolls to the end of the list.

The `loadmore` event returns this parameter.

| Parameter   | Type   | Description                                                              |
| ----------- | ------ | ------------------------------------------------------------------------ |
| startOffset | number | The index in the list where the next batch of data should begin loading. |

The event properties are as follows.

| Property   | Value | Description                                                                                               |
| ---------- | ----- | --------------------------------------------------------------------------------------------------------- |
| bubbles    | false | This event doesn’t bubble.                                                                                |
| cancelable | false | This event has no default behavior that can be canceled. You can't call `preventDefault()` on this event. |
| composed   | false | This event doesn’t propagate outside the template in which it was dispatched.                             |

**`renderlistitems`**

The event that's fired when the component determines which items should be rendered.

The `renderlistitems` event returns this parameter.

| Parameter         | Type  | Description                                                                  |
| ----------------- | ----- | ---------------------------------------------------------------------------- |
| listItemsToRender | array | The list items to be rendered, which are the only items rendered in the DOM. |

The event properties are as follows.

| Property   | Value | Description                                                                                               |
| ---------- | ----- | --------------------------------------------------------------------------------------------------------- |
| bubbles    | false | This event doesn’t bubble.                                                                                |
| cancelable | false | This event has no default behavior that can be canceled. You can't call `preventDefault()` on this event. |
| composed   | false | This event doesn’t propagate outside the template in which it was dispatched.                             |


:::::

:::::tab
::component-specification{component="dynamicListContainer" model="lwc" namespace="lightning"}

:::::

::::::
