---
title: Developing page builder sections
related:
  - https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties.md
  - https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md
  - https://docs.kentico.com/13/developing-websites/page-builder-development/creating-pages-with-editable-areas.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

Sections are components which define the layout of widget zones within editable areas. You can define any number of different sections and allow content editors to [choose them](https://docs.kentico.com/13/managing-website-content/adding-page-content-using-widgets.md) in the _Pages_ application.

The system provides a built-in **Default** section containing a single widget zone. If you wish to use more advanced layouts in the page builder, you need to develop and register your own sections.

## On this page

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

- [Developing sections](#developing-sections)
- [Basic sections](#basic-sections)
- [Sections based on a view component](#sections-based-on-a-view-component)
- [Registering sections](#registering-sections)
- [Limiting widgets allowed in zones](#limiting-widgets-allowed-in-zones)
- [Ensuring correct transfer of widgets between section types](#ensuring-correct-transfer-of-widgets-between-section-types)
- [Storing files for use in the page builder](#storing-files-for-use-in-the-page-builder)
- [Adding scripts and styles for sections](#adding-scripts-and-styles-for-sections)

<!-- dev-model:core end -->

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

- [Developing sections](#developing-sections)
- [Basic sections](#basic-sections)
- [Sections with a custom controller](#sections-with-a-custom-controller)
- [Registering sections](#registering-sections)
- [Limiting widgets allowed in zones](#limiting-widgets-allowed-in-zones)
- [Ensuring correct transfer of widgets between section types](#ensuring-correct-transfer-of-widgets-between-section-types)
- [Storing files for use in the page builder](#storing-files-for-use-in-the-page-builder)
- [Adding scripts and styles for sections](#adding-scripts-and-styles-for-sections)

<!-- dev-model:mvc end -->

## Developing sections

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

On a basic level, page builder sections are pieces of HTML output code containing widget zones. The main step in the development of a section is to create a  **partial view**  that defines the output.

Within the MVC architecture, the section partial view is served by a controller and a model is used to pass any required data. In many cases, sections can utilize a default controller and view model provided by the Xperience API. See the following scenarios for more information:

- [Basic sections](#basic-sections)
- [Sections with a custom controller](#sections-with-a-custom-controller)

In both cases you can develop sections with properties, which allow content editors to adjust the section appearance or behavior directly in the administration interface. For sections with configurable properties, you need to create an additional model class that represents the section properties. For information about this more advanced scenario, see [Defining section properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties.md).

> **Note:** **MVC Areas**
>
> Sections are designed to be used in the global scope and their code files must be placed in the application root of your MVC project (not in an MVC Area). Creating sections in MVC Areas may lead to unexpected behavior.

<!-- dev-model:mvc end -->

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

On a basic level, page builder sections are pieces of HTML output code containing widget zones. You can develop two types of sections:

- [Basic sections](#basic-sections) – define their layout in a single partial view.
- [Sections based on a view component](#sections-based-on-a-view-component) – define their logic in an ASP.NET Core [view component](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components) . Recommended for more complex sections that require non-trivial interactions with the application's business layer.

In both cases you can develop sections with properties, which allow content editors to adjust the section appearance or behavior directly in the administration interface. For sections with configurable properties, you need to create an additional model class that represents the section properties. For information about this more advanced scenario, see [Defining section properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties.md).

> **Note:** **Areas**
>
> Sections are designed to be used in the global scope and their code files must be placed in the application root of your Core project (not in an [Area](https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/areas)). Creating sections in Areas may lead to unexpected behavior.

<!-- dev-model:core end -->

## Basic sections

Use the following process to develop a page builder section:

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

1. Create a partial view with code that defines the required layout.

   - Use the **WidgetZone** extension method to identify locations where widgets can be placed. Every section must contain at least one widget zone – sections without widget zones are not supported.
   - We recommend storing section views in the _\~/Views/Shared/Sections_ folder, and using a view name that matches the **identifier** assigned to the section [upon its registration](#registering-sections) prefixed with the underscore (_'\_'_) character. Replace any period characters ('.') in the identifier with underscores ('\_') in your view name.
   - Alternatively, you can use any required view location or name, and then specify it when registering the section.

   ```xml title="Example"

   @using Kentico.PageBuilder.Web.Mvc
   @using Kentico.Web.Mvc

   <div>
       @Html.Kentico().WidgetZone()
   </div>

   ```

   > **Tip:** **Accessing the section's page**
   >
   > If you need to work with the data of the page containing the currently processed section, use the **ComponentViewModel** class as the view's model and access its **Page** property. The property returns a _TreeNode_ object representing the given page. If you need to load values from the fields of a specific page type, you can convert the _TreeNode_ object to an instance of a specific [page type wrapper class](https://docs.kentico.com/13/developing-websites/generating-classes-for-xperience-objects.md) (the page containing the section must then be of the given page type).

2. Register the section into the system. See [Registering sections](#registering-sections).

With this approach, the section's view is automatically displayed using a default controller provided by the Xperience API. The values of any [properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties.md) defined for the section can be passed to the view by using the default _ComponentViewModel_ class as the model.

<!-- dev-model:mvc end -->

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

1. Create a partial view with code that defines the required layout.

   - Use the **WidgetZoneAsync** extension method (or the method's **** [Tag Helper alternative](https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/reference-xperience-tag-helpers.md#widget-zone)) to identify locations where widgets can be placed. Every section must contain at least one widget zone – sections without widget zones are not supported.
   - We recommend storing section views in the _\~/Components/Sections/_ folder, and using a view name that matches the **identifier** assigned to the section [upon its registration](#registering-sections) prefixed with the underscore (_'\_'_) character.
   - Alternatively, you can use any required view location or name, and then specify it when registering the section.

   ```xml title="Example"

   @using Kentico.Web.Mvc
   @using Kentico.PageBuilder.Web.Mvc 

   <div>
       @await Html.Kentico().WidgetZoneAsync()
   </div>

   ```

   > **Info:** If you plan to use [Blazor components](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/) for page builder components, add the widget zone using the [Widget zone Tag Helper](https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/reference-xperience-tag-helpers.md#widget-zone).

   > **Tip:** **Accessing the section's page**
   >
   > If you need to work with the data of the page containing the currently processed section, use the **ComponentViewModel** class as the view's model and access its **Page** property. The property returns a _TreeNode_ object representing the given page. If you need to load values from the fields of a specific page type, you can convert the _TreeNode_ object to an instance of a specific [page type wrapper class](https://docs.kentico.com/13/developing-websites/generating-classes-for-xperience-objects.md) (the page containing the section must then be of the given page type).

2. Register the section into the system. See [Registering sections](#registering-sections).

With this approach, the section's view is automatically displayed using logic provided by the Xperience API. The values of any [properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties.md) defined for the section can be passed to the view by using the default _ComponentViewModel_ class as the model.

<!-- dev-model:core end -->

> **Info:** **Example of section development**
>
> To see a scenario with full code samples which will guide you through the process of developing a simple section, visit [Example - Developing a section with a configurable property](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties.md#example---developing-a-section-with-a-configurable-property).

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

## Sections with a custom controller

When developing sections with advanced functionality, you may need to take full control over the section's logic. You can do this by implementing the section's controller and view model, in addition to the partial view. This allows you to run any custom code within the section's controller, pass any type of required data to the view, or even switch between completely different views based on the current scenario.

The following steps describe the advanced development process for sections:

1. Create a controller class for the section.
   - We recommend storing section controllers in the _\~/Controllers/Sections_ folder.

2. Make the controller inherit from the **SectionController** base class (available in the _Kentico.PageBuilder.Web.Mvc_ namespace).

3. Implement the default **Index** action in the controller, which is used to retrieve the section markup. The action must return the section's HTML content, typically a partial view.

   - Do not disable POST requests for the _Index_ action (e.g., by using the _HttpGet_ attribute). POST requests to the _Index_ action are used in the page builder feature.
   - Section controller actions used to retrieve the markup cannot be asynchronous (cannot use the _asyn&#x63;_&#x66;unction declaration). Actions that render section markup are called as child actions when rendering the markup of an editable area, but MVC 5 does not support asynchronous child controller actions.

   ```csharp

   public class DefaultSectionController : SectionController
   {
       // GET action used to retrieve the section markup
       public ActionResult Index()
       {
           return PartialView("Sections/_DefaultSection");
       }
   }

   ```

4. Create any required view model classes used to pass data from the section controller to the partial view.
   - We recommend storing section models in the _\~/Models/Sections/_ folder.

5. Prepare a **partial view** that defines the output of the section.
   - Use the **WidgetZone** extension method to identify locations where widgets can be placed. Every section must contain at least one widget zone – sections without widget zones are not supported.
   - We recommend storing section views in the _\~/Views/Shared/Sections_ folder.

6. Register the section into the system. See [Registering sections](#registering-sections).

With this advanced development approach, you have full responsibility and control over the section's controller, view model, and partial view.

### Accessing the data of the current page

If you need to access fields of the page containing the currently processed section, obtain an instance of the **IPageDataContextRetriever** service (we recommend using [dependency injection](https://docs.kentico.com/13/developing-websites/initializing-xperience-services-with-dependency-injection.md)) and call its **Retrieve** method. Specify either a _TreeNode_ object or a [page type wrapper class](https://docs.kentico.com/13/developing-websites/generating-classes-for-xperience-objects.md) as the generic parameter. The method returns an _IPageDataContext_ object with the following properties:

- **Page** – object representing the page, of the type provided in the generic parameter.
- **Metadata** – provides access to the [metadata](https://docs.kentico.com/13/managing-website-content/working-with-pages/editing-metadata-of-pages.md) of the page.
- **Security** – allows you to evaluate the [permissions and authentication requirements](https://docs.kentico.com/13/managing-users/configuring-permissions/configuring-page-permissions/page-level-permissions-acls.md) of the page. See [Implementing page permission checks](https://docs.kentico.com/13/managing-users/configuring-permissions/configuring-page-permissions/implementing-page-permission-checks.md) for details.

```csharp

// Contains an instance of the IPageDataContextRetriever service (e.g., obtained via dependency injection)
private readonly IPageDataContextRetriever pageDataContext;

// Gets the page of the Article page type where the currently processed section is placed
var article = pageDataContext.Retrieve<Article>().Page;

```

### Accessing the data of the current page in POST actions

Fields of the page the section is rendered on are by default not accessible in controller actions that handle POST requests. Such requests do not contain sufficient information to identify the page from which they originate.

To access page data in POST actions, you need to include information about the current page into the data submitted by the corresponding form in the section's output – call the   **Html.Kentico().PageData**  extension method within the given form tag in your section view.

```csharp title="Example"

using System.Web.Mvc.Ajax
using Kentico.Web.Mvc
using Kentico.PageBuilder.Web.Mvc

...

@using (Ajax.BeginForm("PostAction", "CustomSection", null, new AjaxOptions
{
    HttpMethod = "POST",
    UpdateTargetId = "sectionForm"
}, new { id = "sectionForm" }))
{
    @Html.Kentico().AntiForgeryToken()
    @Html.Kentico().PageData()
    ...
    <input type="submit" value="Submit" />
}

```

The method renders a hidden form field that persists information about the current page. The page data can be retrieved via [IPageDataContextRetriever.Retrieve\<TPageType>](#accessing-the-data-of-the-current-page) in the corresponding POST action.

<!-- dev-model:mvc end -->

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

## Sections based on a view component

The basic implementation of a section consists of only a partial view (and possibly a [properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties.md) class). You may need additional logic, for example if you need to:

- react to the configuration of the section's properties
- perform interactions based on the page where the section is rendered
- execute general business logic not suitable for views (e.g., database operations)

For this purpose, you can develop sections based on ASP.NET Core [view components](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components). Such sections consist of a view component class and the corresponding partial view it renders.

Implementing a section based on a view component follows this general process:

1. Create a view component class for the section.
   - We recommend storing section view components in the _\~/Components/Sections/_ folder together with other files required by the section.
2. Implement the component's _Invoke_ or _InvokeAsync_ method (the synchronous and asynchronous approaches are both supported, this choice depends solely on your requirements).
   - The system invokes the view component when the section is inserted via the page builder. During the invocation, the system passes the section's [properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties.md) (the _ComponentViewModel_ class) into the component's _Invoke_ method. For this reason, the method's signature **needs to** declare the **ComponentViewModel** parameter. For sections with custom properties, you need to specify the properties class as the generic parameter.

     ```csharp

     // The signature of a view component's InvokeAsync method for sections without custom properties
     public async Task<IViewComponentResult> InvokeAsync(ComponentViewModel sectionProperties)

     // The signature of a view component's InvokeAsync method for sections with custom properties
     public async Task<IViewComponentResult> InvokeAsync(ComponentViewModel<TSectionPropertiesClass> sectionProperties)

     ```
3. To the return statement of the component's _Invoke_ method, add the full relative path to the component's partial view. For example:

   ```csharp

   return View("~/Components/Sections/MySection/_MySection.cshtml", model);

   ```
4. Create any required view model classes used to pass data from the section view component to the partial view.
   - We recommend storing section models in the _\~/Components/Sections/_ folder together with other files required by the section.
5. Prepare a **partial view** that defines the layout of the section.
   - Use the **WidgetZoneAsync** extension method (or the method's  ****   [Tag Helper alternative](https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/reference-xperience-tag-helpers.md#widget-zone) ) to mark locations within the layout where widgets can be placed. Every section must contain at least one widget zone – sections without widget zones are not supported.
   - We recommend storing section views in the _\~/Components/Sections/_ folder together with other files required by the section.
   > **Info:** If you plan to use [Blazor components](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/) for page builder components, add the widget zone using the [Widget zone Tag Helper](https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/reference-xperience-tag-helpers.md#widget-zone).
6. Register the section into the system. See [Registering sections](#registering-sections).

When the section is inserted using the page builder, the system invokes the corresponding view component and renders its partial view. Using this approach, you can decouple business and view-layer code, maintaining separation of concerns.

### Accessing the data of the current page

If you need to access fields of the page where the section is currently rendered, use the **Page** property of the _ComponentViewModel_ class (from the component's _Invoke_ method).

```csharp

// Retrieves the name of the page on which the section is currently rendered
string name = sectionProperties.Page.DocumentName;

```

### Handling POST actions

If your section needs to communicate with the server using POST actions, create a custom controller class containing the required action methods and logic. We recommend storing the class in the _\~/Components/Sections/_ folder together with other files required by the section.

Fields of the page the section is rendered on are by default not accessible in controller actions that handle POST requests. Such requests do not contain sufficient information to identify the page from which they originate. To access page data in POST actions, you need to include information about the current page into the data submitted by the corresponding form in the section's output – call the **Html.Kentico().PageData**  extension  method (or the method's [Tag Helper alternative](https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/reference-xperience-tag-helpers.md)) within the given form tag in your section view.

```csharp

@using Kentico.Web.Mvc
@using Kentico.PageBuilder.Web.Mvc

<form asp-controller="SectionPostActionsController" asp-action="HandlePost" id="form">

    ...

    @Html.Kentico().PageData()

    <input type="submit" value="Submit" />
</form>

```

The method renders a hidden form field that persists information about the current page. The page data can be retrieved via the **IPageDataContextRetriever**  service in the corresponding controller action.

Obtain an instance of the **IPageDataContextRetriever** service (we recommend using dependency injection) and call its **Retrieve** method. Specify either a _TreeNode_ object or a [page type wrapper class](https://docs.kentico.com/13/developing-websites/generating-classes-for-xperience-objects.md) as the generic type parameter. The method returns an _IPageDataContext_ object that contains the current page object in its _Page_ property. You can also access the [metadata](https://docs.kentico.com/13/managing-website-content/working-with-pages/editing-metadata-of-pages.md) and evaluate the [permissions and authentication requirements](https://docs.kentico.com/13/managing-users/configuring-permissions/configuring-page-permissions/page-level-permissions-acls.md) of the page via the object's _Metadata_ and _Security_ properties.

```csharp

// Contains an instance of the IPageDataContextRetriever service (e.g., obtained via dependency injection)
private readonly IPageDataContextRetriever pageDataContext;

// Gets the page of the Article page type where the currently processed section is placed
var article = pageDataContext.Retrieve<Article>().Page;

```

<!-- dev-model:core end -->

## Registering sections

For sections to become available in the page builder, they need to be registered into the system. Register sections using the **RegisterSection** assembly attribute (available in the _Kentico.PageBuilder.Web.Mvc_ namespace).

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

To register  [basic sections](#basic-sections)  (without a custom controller class), we recommend adding the assembly attributes to a dedicated code file. For example, you can create a file named  **PageBuilderComponentRegister.cs**  in your project's  _\~/App\_Start_  folder and use it to register your page builder components. For basic sections, specify the following attribute parameters:

- **Identifier** – the unique identifier of the section. We recommend using a unique prefix in your section identifiers to prevent conflicts when deploying sections to other projects, for example matching your company's name.
- **Name** – the name used to identify the section when displayed in the administration interface.
- **PropertiesType** – only required for [sections with properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties.md). Specifies the _System.Type_ of the section's property model class.
- (Optional) **CustomViewName** – specifies the name and location of the view that defines the section's output. If not set, the system searches for a corresponding _\_.cshtml_ view in the _\~/Views/Shared/Sections_ folder (any period characters '.' in the identifier are replaced by underscores '\_').

  ```csharp title="Basic section registration example"

  [assembly: RegisterSection("CompanyName.DefaultSection", "Default section", typeof(CustomSectionProperties), "Sections/_DefaultSection")]

  ```

For [sections with a custom controller](#sections-with-a-custom-controller), you can add the assembly attribute directly into the controller code file (above the controller class). In this case, specify the following attribute parameters:

- **Identifier** – the unique identifier of the section. We recommend using a unique prefix in your section identifiers to prevent conflicts when deploying sections to other projects, for example matching your company's name.
- **ControllerType** – the _System.Type_ of the section's controller class.
- **Name** – the name used to identify the section when displayed in the administration interface.

  ```csharp title="Controller section registration example"

  [assembly: RegisterSection("CompanyName.DefaultSection", typeof(DefaultSectionController), "Default section")]

  ```

When registering any type of section, you can also set the following optional attribute properties:

- **Description** – the description of the section displayed as a tooltip.
- **IconClass** – the [font icon](https://docs.kentico.com/13/custom-development/extending-the-administration-interface/working-with-font-icons.md) class displayed when viewing the sections in the section list.

```csharp

[assembly: RegisterSection("CompanyName.DefaultSection", typeof(DefaultSectionController), "Default section", Description = "A default section with one widget zone.", IconClass="icon-box")]

```

<!-- dev-model:mvc end -->

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

To register [basic sections](#basic-sections) (without a view component class), we recommend adding the assembly attributes to a dedicated code file. For example, you can create a file named **ComponentRegister.cs** in your project's  _\~/Components_  folder and use it to register your page builder components. For basic sections, specify the following attribute parameters:

- **Identifier** – the unique identifier of the section. We recommend using a unique prefix in your section identifiers to prevent conflicts when deploying sections to other projects, for example matching your company's name.
- **Name** – the name used to identify the section when displayed in the administration interface.
- **PropertiesType** – only required for [sections with properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties.md). Specifies the _System.Type_ of the section's property model class.
- **CustomViewName** – specifies the name and location of the view that defines the section's output. If not set, the system searches for a corresponding  _\_.cshtml_  view in the  _\~/Views/Shared/Sections_  folder (any period characters '.' in the identifier are replaced by underscores '\_').

  ```csharp title="Basic section registration example"

  [assembly: RegisterSection("CompanyName.DefaultSection", "Default section", typeof(CustomSectionProperties), "~/Components/Sections/_MySection.cshtml")]

  ```

For [sections based on a view component](#sections-based-on-a-view-component), you can add the assembly attribute directly into the view component code file. In this case, specify the following attribute parameters:

- **Identifier** – the unique identifier of the section. We recommend using a unique prefix in your section identifiers to prevent conflicts when deploying sections to other projects, for example matching your company's name.
- **ViewComponentType** – the _System.Type_ of the section's view component class.
- **Name** – the name used to identify the section when displayed in the administration interface.
- **PropertiesType** – only required for [sections with properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties.md). Specifies the _System.Type_ of the section's property model class.

  ```csharp title="View component section registration example"

  [assembly: RegisterSection("CompanyName.DefaultSection", typeof(DefaultSectionViewComponent), "Default section", typeof(CustomSectionProperties))]

  ```

When registering any type of section, you can also set the following optional attribute properties:

- **Description** – the description of the section displayed as a tooltip.
- **IconClass** – the [font icon](https://docs.kentico.com/13/custom-development/extending-the-administration-interface/working-with-font-icons.md) class displayed when viewing the sections in the section list.

```csharp

[assembly: RegisterSection("CompanyName.DefaultSection", typeof(DefaultSectionViewComponent), "Default section", Description = "A default section with one widget zone.", IconClass="icon-box")]

```

<!-- dev-model:core end -->

> **Tip:** **Localizing section metadata**
>
> To allow content editors to experience the page builder in their preferred UI culture, you can [localize](https://docs.kentico.com/13/multilingual-websites/setting-up-a-multilingual-user-interface/localizing-builder-components.md) the **Name** and **Description** values of sections.

## Assigning a default section

Editable areas in the page builder have a default section, which is automatically added when the area is empty. This includes new areas where content editors have not yet placed any other section, and scenarios where an editor removes the last section from an area.

By default, the system's built-in _Default_ section is used for this purpose. For most websites, we recommend replacing the default section with your own to ensure that the page builder output code exactly matches the requirements of your website's styling and design.

To specify a global default section, extend the code that [registers the page builder feature](https://docs.kentico.com/13/developing-websites/page-builder-development.md) in your live site project:

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

1. Create a **PageBuilderOptions** object and set its **DefaultSectionIdentifier** property to the _identifier_ of the appropriate section.
2. To disable the system's built-in _Default_ section, also set the **RegisterDefaultSection** property to _false_.

   > **Note:** **Warning**: If your site already has existing pages that use the page builder, replace all occurrences of the _Default_ section in page content before you disable it. Otherwise an error will occur on the given pages.
3. Pass the _PageBuilderOptions_ object as the parameter of the **UsePageBuilder** method.

   ```csharp

   var options = new PageBuilderOptions()
   {
       // Specifies a default section for the page builder feature
       DefaultSectionIdentifier = "CompanyName.DefaultSection",
       // Disables the system's built-in 'Default' section
       RegisterDefaultSection = false
   };

   // Enables the page builder feature
   builder.UsePageBuilder(options);


   ```

<!-- dev-model:mvc end -->

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

1. Create a **PageBuilderOptions** object and set its **DefaultSectionIdentifier** property to the _identifier_ of the appropriate section.
2. To disable the system's built-in _Default_ section, also set the **RegisterDefaultSection** property to _false_.

   > **Note:** **Warning**: If your site already has existing pages that use the page builder, replace all occurrences of the _Default_ section in page content before you disable it. Otherwise, accessing the pages will result in an error.
3. Pass the _PageBuilderOptions_ object as the parameter of the **UsePageBuilder** method.

   ```csharp

           public void PageBuilderAssignDefaultSection(IServiceCollection services)
           {
               PageBuilderOptions options = new PageBuilderOptions()
               {
                   DefaultSectionIdentifier = "CompanyName.DefaultSection",
                   // Disables the system's built-in 'Default' section
                   RegisterDefaultSection = false
               };

               services.AddKentico(features =>
                   features.UsePageBuilder(options));
           }


   ```

<!-- dev-model:core end -->

Empty editable areas now use the new default section. The change does NOT modify the sections within existing page builder content.

You can also override the global default section for individual [editable areas](https://docs.kentico.com/13/developing-websites/page-builder-development/creating-pages-with-editable-areas.md):

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

1. Prepare an **EditableAreaOptions** object.
2. Set the object's **DefaultSectionIdentifier** property to match the _identifier_ of the section which you want to use as default.
3. Assign the object as a parameter of **EditableArea** methods in your views.

```xml

<div>
    @{
        var optionsDefaultSection = new EditableAreaOptions
        {
            DefaultSectionIdentifier = "LearningKit.Sections.Col5050"
        };
    }
    @Html.Kentico().EditableArea("areaWithSection", optionsDefaultSection)
</div>


```

<!-- dev-model:mvc end -->

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

1. Prepare an **EditableAreaOptions** object.
2. Set the object's **DefaultSectionIdentifier** property to match the _identifier_ of the section which you want to use as default.
3. Assign the object as a parameter of **EditableAreaAsync** extension methods (or the [Tag Helper alternative](https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/reference-xperience-tag-helpers.md)) in your views.

```xml

<div>
    @{
        var optionsDefaultSection = new EditableAreaOptions
        {
            DefaultSectionIdentifier = "LearningKit.Sections.Col5050"
        };
    }
    @await Html.Kentico().EditableAreaAsync("areaWithSection", optionsDefaultSection)
</div>


```

<!-- dev-model:core end -->

## Limiting widgets allowed in zones

You can define widget restrictions for individual zones defined within sections. To limit which widgets can be added to a specific zone:

1. Edit the partial view of the section where the widget zone is defined.
2. Create a list of strings containing the identifiers of widgets you want to allow in the zone. See [Developing widgets](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md) to learn more about widget identifiers. For identifiers of the default system widgets, check [the system widget reference](https://docs.kentico.com/13/developing-websites/page-builder-development/reference-system-widgets.md).
3. Assign the list of identifiers to the **allowedWidgets** named parameter of the widget zone extension method.

The allowed widgets parameter works as a whitelist – you list widgets that you want to allow in the zone, and all others are automatically excluded. When the allowed widgets parameter is not specified, all registered widgets can be added to the zone.

The widget limiting feature is intended as a way to set guidelines for content editors, not as a security measure. When you limit a zone, existing instances of widgets placed in the zone are not validated or removed.

> **Note:** **Editable area restrictions**
>
> Widget zone restrictions are combined with any widget restrictions set for the [Page Builder editable area](https://docs.kentico.com/13/developing-websites/page-builder-development/creating-pages-with-editable-areas.md) containing the section. Both sets of restrictions apply to create the final list of allowed widgets for the zone.

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

```csharp title="Example - Limiting widgets in a zone"

<div>
    @{
        var widgetsWhitelist = new[] { Kentico.Content.Web.Mvc.SystemComponentIdentifiers.FORM_WIDGET_IDENTIFIER,
                                       "LearningKit.Widgets.NumberWidget",
                                       "LearningKit.Widgets.SomeOtherWidget" };
    }
    @Html.Kentico().WidgetZone(allowedWidgets: widgetsWhitelist)
</div>

```

<!-- dev-model:mvc end -->

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

```csharp title="Example - Limiting widgets in a zone"

<div>
    @{
        var widgetsWhitelist = new[] { Kentico.Content.Web.Mvc.SystemComponentIdentifiers.FORM_WIDGET_IDENTIFIER,
                                       "LearningKit.Widgets.NumberWidget",
                                       "LearningKit.Widgets.SomeOtherWidget" };
    }
    @await Html.Kentico().WidgetZoneAsync(allowedWidgets: widgetsWhitelist)
</div>

```

<!-- dev-model:core end -->

## Ensuring correct transfer of widgets between section types

When a user [changes the section type](https://docs.kentico.com/13/managing-website-content/adding-page-content-using-widgets.md) in the Page Builder interface, widgets are moved to the new section's widget zones automatically based on the order in which the zones are specified in the section code. This may require additional work from content editors to get the desired page layout.

To ensure that widgets are moved to correct zones when the section type is changed:

1. Add an identifier to each zone, which creates so-called named widget zones.
2. Use the same identifier for corresponding zones within all of your widget sections.

When a section type is changed, the system moves widgets to matching named zones.

![Transfer of widgets between section types](https://docs.kentico.com/docsassets/13/developing-page-builder-sections/named-zones.png "Transfer of widgets between section types")

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

```xml title="Example - Named widget zone"

<div>
    @Html.Kentico().WidgetZone("main")
</div>

```

<!-- dev-model:mvc end -->

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

```xml title="Example - Named widget zone"

<div>
    @await Html.Kentico().WidgetZoneAsync("main")
</div>

```

<!-- dev-model:core end -->

## Storing files for use in the page builder

You may wish to develop sections that use or display various files. You can [store such files](https://docs.kentico.com/13/configuring-xperience/managing-files/storing-files.md) in the system either as [page attachments](https://docs.kentico.com/13/managing-website-content/working-with-files/page-attachments.md) or using [media libraries](https://docs.kentico.com/13/managing-website-content/working-with-files/media-library-files.md). These two approaches vary in different ways:

- [Page attachment files](https://docs.kentico.com/13/managing-website-content/working-with-files/page-attachments.md) are associated only with a specific page. You should store media files as page attachments only if the files are considered to be a content of a particular page (e.g. a language specific variant of an image).
- [Media library files](https://docs.kentico.com/13/managing-website-content/working-with-files/media-library-files.md) are available for all pages of a particular site. You should store files using media libraries when the file content is reusable or the files are more relevant to the general visual design of the page than to its content (e.g. a background image used on all pages with a similar layout).

This is important to remember especially when creating [custom page templates](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-templates.md) from existing pages. New pages created using templates do not display any page attachments, because the attachments stay as content bound to the original pages. On the other hand, pages based on templates display media library files automatically.

## Adding scripts and styles for sections

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

To add JavaScript and CSS styles required by your page builder sections, place script and stylesheet files into sub-folders under the  _**\~/Content/Sections**_  directory of your MVC project (you may need to create the _Sections_ directory). Use sub-folders that match the identifiers of individual sections, or a _Shared_ sub-folder for assets used by multiple sections.

The system automatically creates [bundles](https://docs.microsoft.com/en-us/aspnet/mvc/overview/performance/bundling-and-minification) containing all _.js_ and _.css_ files located under _\~/Content/Sections_. The bundles are then linked on all pages with [page builder editable areas](https://docs.kentico.com/13/developing-websites/page-builder-development/creating-pages-with-editable-areas.md).

> **Info:** The same bundles also contain script and stylesheet files added for [widgets](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md) in the _\~/Content/Widgets_ directory and [inline property editors](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/creating-inline-editors-for-widget-properties.md) in the _\~/Content/InlineEditors_ directory (inline editor scripts and styles are only included in the administration bundles, which are linked when pages are displayed in **Edit** mode within the **Pages** application).

> **Note:** **CSS notes**- Only use the _\~/Content/Sections_ directory to add **basic styles** that are required for the section to render correctly. Any **site-specific styles** that finalize the live site design of the section should be handled separately within the given site's main stylesheet.
>
> - To avoid potential conflicts between styles from other third-party components, we recommend adding a unique prefix to your CSS classes and identifiers (for example _#CompanyName-mid-column_), or employ similar measures to ensure their uniqueness.
> - Do not make any assumptions about the relative order of the source CSS in the resulting bundles – individual stylesheet files contained in the bundle may or may not precede each other.

<!-- dev-model:mvc end -->

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

To add JavaScript and CSS styles required by your sections, we recommend placing script and stylesheet files into sub-folders under:

- _**\~/wwwroot/PageBuilder/Public/Sections/**_ – scripts and styles intended for the live site.
- _**\~/wwwroot/PageBuilder/Admin/Sections/**_ – scripts and styles intended for the administration interface (when working with the section in the page builder editing interface).

You can use sub-folders that match the identifiers of individual sections, or a _Shared_ sub-folder for assets used by multiple sections. Note that this recommendation only applies when using the default configuration of the bundling support provided by Xperience and may be different for your project. See  [Bundling static assets of builder components](https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/bundling-static-assets-of-builder-components.md).

> **Note:** **CSS notes**- Only use the specified directories to add **basic styles** that are required for the section to render correctly. Any **site-specific styles** that finalize the live site design of the section should be handled separately within the given site's main stylesheet.
>
> - To avoid potential conflicts between styles from other third-party components, we recommend adding a unique prefix to your CSS classes and identifiers (for example _#CompanyName-mid-column_), or employ similar measures to ensure their uniqueness.

<!-- dev-model:core end -->

### Initializing section scripts

If you need to initialize scripts (for example call a function on page load or register an event listener), you can add script tags directly into the view code of your page builder sections. However, you need to keep the following in mind:

- Do not rely on the order of execution of multiple script tags within one section. The order of their execution may be different in the page builder interface than on the live site.
- If you declare variables within section script tags, the variables are defined in the global namespace. To prevent conflicts on pages containing multiple instances of the same section, wrap the scripts into a self-executing anonymous function.
- If you use assets stored in the _\~/Content/Sections_ folder within the section views, the related bundles are added at the end of the HTML document's body tag. Such assets are not available in the section code during the page load process. A solution is to run the initialization script during the [DOMContentLoaded](https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded) event. However, sections in the page builder interface may be added dynamically after the page is loaded. In this case, the _DOMContentLoaded_ event has already occurred and will not fire again. For example, the following script demonstrates how to reliably call a custom function on page load:

  ```csharp

  @using Kentico.PageBuilder.Web.Mvc
  @using Kentico.Web.Mvc

  <div>
      @Html.Kentico().WidgetZone()
  </div>
  <script type="text/javascript">
  (function () {
      if (document.readyState === "loading") {
          // Calls the function during the 'DOMContentLoaded' event, after the HTML document has been completely loaded
          document.addEventListener("DOMContentLoaded", function () {
              customFunction();
          });
      } else {
          // Calls the function directly in cases where the section is rendered dynamically after 'DOMContentLoaded'
          customFunction();
      }
  })();
  </script>

  ```

Apart from initialization code, avoid linking or executing scripts directly within section views. This could lead to duplicated scripts on pages that contain multiple instances of the same section.
