> For the complete documentation index, see [llms.txt](https://docs.beefree.io/beefree-sdk/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.beefree.io/beefree-sdk/~/changes/3EjxmC5rAYEIQ0JKR16k/rows/custom-rows/how-it-works.md).

# How it works

## Overview <a href="#overview" id="overview"></a>

When the builder starts, you can feed to it multiple lists of *custom rows*, which will display in the rows selector:

<figure><img src="https://806400411-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8c7XIQHfAtM23Dp3ozIC%2Fuploads%2FCDPJ7ROso9yyFhVl2TBt%2FCR_config_list-1024x405.jpg?alt=media&amp;token=600a2eb5-cf10-4184-83b8-407eeeab177f" alt=""><figcaption></figcaption></figure>

Each list is an array of objects (JSON) describing the rows and must be returned by a URL that the builder will call when the user selects its name.\
These objects may be [Saved Rows](/beefree-sdk/~/changes/3EjxmC5rAYEIQ0JKR16k/rows/saved-rows.md) or [Simplified Rows](/beefree-sdk/~/changes/3EjxmC5rAYEIQ0JKR16k/rows/custom-rows/generating-custom-rows-from-existing-content.md) (a JSON schema that allows you to generate rows from existing contents through an API).

When the user selects the list name, the builder will call the given URL to retrieve the rows and display them:

<figure><img src="https://806400411-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8c7XIQHfAtM23Dp3ozIC%2Fuploads%2FOFjFnEQ6WRedlCx2WSbO%2F2rows_displaying-442x1024.jpeg?alt=media&amp;token=72f3c2ef-12fe-4b85-b4a8-abcd01340a79" alt=""><figcaption></figcaption></figure>

If the URL is not available, a warning message will be displayed in the bottom right, and the builder will display the next set of rows or fallback to *empty rows* or *default rows*(depending on your configuration):

<figure><img src="https://806400411-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8c7XIQHfAtM23Dp3ozIC%2Fuploads%2FAl66aWUIgURcx3eQd5k5%2F3Error-warning-300x61.jpeg?alt=media&amp;token=7414a0d7-115e-4592-8a31-7071d8eb2e1c" alt=""><figcaption></figcaption></figure>

## **List limits**

There is no limit to the number of rows passed to the builder in each array of *custom rows*.

However, the builder UI will only display the first **30 items** (i.e., the first 30 rows in the array).

The rest of them will not show until the user performs a search that matches them. If the search matches over 30 items, the first 30 are displayed.

This filtering is applied to prevent performance degradation in the browser.

## **Search**

The search field allows users to narrow down the content shown after they select a list of *custom rows*.

The search is performed against all elements of the array (i.e., both visible and hidden), and the first 30 items (i.e., the first 30 rows in the array that match the search criteria) are shown.

All textual content included in the selected array – including image file names – is used to find a match.

<figure><img src="https://806400411-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8c7XIQHfAtM23Dp3ozIC%2Fuploads%2FkThABDJNSrBf65eGewUP%2F4CR_search.png?alt=media&amp;token=c1047f53-0806-4669-ae14-3207b4c66edc" alt=""><figcaption></figcaption></figure>

## Rows configuration <a href="#rows-configuration" id="rows-configuration"></a>

Defines the usage of *custom rows* in the *beeConfig* object when you start the builder:

```json

rowsConfiguration: {
  emptyRows: true,
  defaultRows: true,
  selectedRowType: 'my_saved_rows', // pre-select this item in the Rows select
  externalContentURLs: [
    {
      name: "Rows list 01",
      value: "https://URL-01"
    },
    {
      name: "Rows list 02",
      value: "https://URL-02"
    }
  ]
}

```

## **Rows Configuration Parameters**

This section explains each of the parameters listed in the JSON `rowConfiguration` code snippet displayed in the previous section.

These parameters are the following:

* [`emptyRows`](#emptyrows): Set of empty rows. The same rows available when no *rowsConfiguration* is included.
* [`defaultRows`](#defaultrows): A set of rows that contain sample content.
* [`selectedRowType`](#selectedrowtype): Specify which type of row should be pre-selected when the end user opens the Rows selection in the visual builder.&#x20;
* [`externalContentURLs`](#externalcontenturls): Each item in this list defines an option available in the *Rows* drop-down.

### **emptyRows**

Set of empty rows. The same rows available when no *rowsConfiguration* is included.

**Allowed values:** true / false

**Default value:** true

Will always be included as the last element if omitted in the configuration.

They are presented as follows in the builder’s default theme (the screenshot shows the first 4 empty rows):

<figure><img src="https://806400411-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8c7XIQHfAtM23Dp3ozIC%2Fuploads%2FuVeV6D6mzm8YhVzV436c%2F5rows_empty.png?alt=media&amp;token=a472bdb4-104f-4804-a099-20db7ca58c58" alt=""><figcaption></figcaption></figure>

### **defaultRows**

A set of rows that contain sample content. That’s why we also call them *sample rows*. They may be used as a supporting feature for starting templates or to speed up the process of building a message from scratch.

**Allowed values:** true / false

**Default value:** false

They are presented as follows in the builder’s default theme (the screenshot shows the first 2 default rows):

<figure><img src="https://806400411-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8c7XIQHfAtM23Dp3ozIC%2Fuploads%2FrtcF6QKySIwpoIwJKmqL%2F6rows_default.png?alt=media&amp;token=5e799c5e-8065-4d08-8593-5d312b494f94" alt=""><figcaption></figcaption></figure>

### **selectedRowType**

This parameter is used to specify which type of row should be pre-selected when the end user opens the Rows selection in the visual builder. You have several options for what value to assign to this parameter, and its role is to simplify the end user's interaction with the builder by focusing their attention on a specific type of row by default.

**Possible values for `selectedRowType`:**

1. **`'defaultRows'`**:
   * This value will automatically select the default rows that come with the builder, which usually contain pre-designed content that users can easily modify and adapt. It helps users start with a pre-configured structure and quickly adjust it to meet their needs.
2. **`'emptyRows'`**:
   * This value pre-selects an option for the user to start with empty rows. This is useful for users who prefer to build their layouts entirely from scratch, without any predefined content or structure.
3. **The handle of a row in `externalContentURLs`**:
   * You can also pass the handle of a row that is listed in `externalContentURLs` to pre-select a row from an external source. A **handle** in this context refers to the **unique identifier** or **name** used to reference a specific row from an external list. Think of it as a unique key that allows the system to identify which external row to load or pre-select.
   * For example, if you have external content rows listed in `externalContentURLs`, such as "Rows list 01" or "Rows list 02," you can pass their respective handle (typically a string like `"Rows list 01"`) as the value for `selectedRowType`. This will automatically load and pre-select that specific external row, saving the user the step of manually selecting it from the list.

#### **How a Handle Works**

A **handle** acts like a reference key to point to a specific row in an external list. Handles are typically unique names or identifiers that can be used to quickly access specific rows from an external content source, ensuring that the correct row is fetched and displayed to the user. For instance, in the following configuration:

```json
externalContentURLs: [
  {
    name: "Rows list 01",
    value: "https://URL-01"
  },
  {
    name: "Rows list 02",
    value: "https://URL-02"
  }
]
```

If you want to pre-select "Rows list 01" from the external content list, you would set `selectedRowType: 'Rows list 01'`, where `'Rows list 01'` is the handle of that specific external content row. The handle here refers to the **name** or a unique identifier that the system recognizes and uses to select the correct row from the external content list.

### **externalContentURLs**

Each item in this list defines an option available in the *Rows* drop-down.

**name:** the text displayed in the *Rows* drop-down

**value:** URL that will be called by the builder when the user selects the corresponding *name* in the drop-down. The URL must return a set of rows as a JSON object.

Here is an example of how the *Rows* drop-down looks when the application configuration includes:

* **Empty** rows (see above)
* **Default** rows (see above)
* **Saved** rows (l[earn about displaying Saved rows](/beefree-sdk/~/changes/3EjxmC5rAYEIQ0JKR16k/rows/custom-rows/displaying-saved-rows.md))
* 3 additional arrays for **Custom** rows

<figure><img src="https://806400411-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8c7XIQHfAtM23Dp3ozIC%2Fuploads%2FFe4qy0sUwelqFbN90pYt%2F7rows_custom.png?alt=media&amp;token=9ff24720-782a-418a-9af8-2b9dfc5b9030" alt=""><figcaption></figcaption></figure>

## **Display order**

The order of the JSON nodes in *rowsConfiguration* defines the order in which the lists of *custom rows* will display in the drop-down. It also determines which list of rows will be used as default (selected) when the user clicks on the *Rows* tab for the first time during the session.

## **Row type order**

The first ordering factor refers to the **type of row** (empty, default, custom). That’s defined by how the following parameters are listed in *rowsConfiguration*:

* *emptyRows*
* *defaultRows*
* *externalContentURLs*

So obtain the order shown in this screenshot…

<figure><img src="https://806400411-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8c7XIQHfAtM23Dp3ozIC%2Fuploads%2FrqfnZHGZTqJZSs0w0AN1%2F8rows_custom.png?alt=media&amp;token=c35c7295-42dd-42c4-9f56-cc60488c7c12" alt=""><figcaption></figcaption></figure>

… you would list *defaultRows* before *emptyRows*:

* *defaultRows*
* *emptyRows*
* *externalContentURLs*

## **External content order**

The order inside the *externalContentURLs* node defines the order of the *Custom rows*.

In the above example configuration:

1. *emptyRows* will be the first item in the drop-down and the default selection when clicking on the *Rows* tab
2. *defaultRows* will be the second item in the drop-down
3. The lists of rows defined in *externalContentURLs* will follow their ordering in the drop-down

It’s up to you – the host application – to decide what’s available and in which order.

## **Row type requirements**

* *emptyRows* and *defaultRows* are **not** required
* this allows you to load just *Custom rows*, if needed, controlling which content users can drag and drop into the builder


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.beefree.io/beefree-sdk/~/changes/3EjxmC5rAYEIQ0JKR16k/rows/custom-rows/how-it-works.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
