---
title: Extending widgets
related:
  - https://docs.kentico.com/13/developing-websites/page-builder-development.md
  - https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md
  - https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/defining-widget-properties.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).

When developing [page builder widgets](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md), you can extend an existing widget instead of creating a new one from scratch. The API provides a way to render a **"nested"** widget from the view code of another widget. An extended widget retains the full functionality of the original nested widget, but can introduce additions such as wrapping HTML code, new [configurable properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/defining-widget-properties.md) and additional custom logic.

Nesting is possible for widgets of any type, including the [default system widgets](https://docs.kentico.com/13/developing-websites/page-builder-development/reference-system-widgets.md), third-party widgets, or your own custom widgets. The only requirement is for the widget to be registered using the _RegisterWidget_ assembly attribute (as described in [Developing widgets](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md)).

## Creating extended widgets

<!-- 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 create a widget that extends another widget via nesting:

1. Start by following the [standard widget development](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md) instructions.
2. For widgets with [configurable properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/defining-widget-properties.md), choose one of the following approaches based on your requirements:

   - Use the property model class of the nested widget for your extended widget (either during registration or in the widget's custom controller).\
     – OR –
   - Create a new property model class that **inherits** from the nested widget's property model. You can then add any properties that you need for your extended widget.
3. In the partial view of the extended widget, find the location where you want to display the content of the nested widget, and call the **Html.Kentico().RenderNestedWidget** extension method (available in the _Kentico.PageBuilder.Web.Mvc_ namespace). The method takes the following parameters:
   - **identifier** – the _string_ identifier under which the nested widget was registered. For identifiers of default system widgets, check [the system widget reference](https://docs.kentico.com/13/developing-websites/page-builder-development/reference-system-widgets.md).
   - **properties**– object containing the configurable properties of the nested widget. Use the [ComponentViewModel\<TProperties>](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/defining-widget-properties.md) model class to make the system automatically pass the properties to the widget view.

<!-- 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 create a widget that extends another widget via nesting:

1. Start by following the [standard widget development](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md) instructions.
2. For widgets with [configurable properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/defining-widget-properties.md), choose one of the following approaches based on your requirements:

   - Use the property model class of the nested widget for your extended widget (either during registration or in the widget's custom controller).\
     – OR –
   - Create a new property model class that **inherits** from the nested widget's property model. You can then add any properties that you need for your extended widget.
3. In the partial view of the extended widget, find the location where you want to display the content of the nested widget, and call the **Html.Kentico().RenderNestedWidget** extension method (from the _Kentico.PageBuilder.Web.Mvc_ namespace) or its [Tag Helper](https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/reference-xperience-tag-helpers.md) equivalent. The method takes the following parameters:
   - **identifier** – the _string_ identifier under which the nested widget was registered. 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).
   - **properties**– object containing the properties of the nested widget. Use the [ComponentViewModel\<TProperties>](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/defining-widget-properties.md) model class to make the system automatically pass the properties to the widget view.

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

You now have a custom widget that provides the same content and functionality as the nested widget. Implement any required extended functionality, for example by adding HTML code before or after the nested widget.

If the nested widget has configurable properties, they are also available for the extended widget within the page builder interface (along with any additional properties defined in an inherited property model class).

## Example

The following example demonstrates how to use widget nesting to extend the system's default **Form** widget. The sample extended widget adds an extra heading above the default form content, along with a custom property that allows editors to set the heading text.

<!-- 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.

> **Note:** **Note**: The following example is based on the [LearningKit project](https://github.com/Kentico/LearningKit-Mvc). To use the code samples in your project, you need to modify the namespaces, identifiers and other occurrences where _LearningKit_ is mentioned to match your project's name.

1. Create a widget property model class in the _\~/Models/Widgets/ExtendedFormWidget_ folder, named **ExtendedFormWidgetProperties.cs**.
2. Make the property model inherit from the **FormWidgetProperties** class (in the _Kentico.Forms.Web.Mvc.Wigets_ namespace), which is the property model of the default form widget.
3. Define a string property representing the text of the additional heading.

   ```csharp

   using Kentico.Forms.Web.Mvc;
   using Kentico.Forms.Web.Mvc.Widgets;

   namespace LearningKit.Models.Widgets.ExtendedFormWidget
   {
       public class ExtendedFormWidgetProperties : FormWidgetProperties
       {
           // Defines a property and sets its default value
           // Assigns the default Xperience text input component, which allows users to enter 
           // a textual value for the property in the widget's configuration dialog
           [EditingComponent(TextInputComponent.IDENTIFIER, Order = 0, Label = "Heading text")]
           public string HeadingText { get; set; } = "Default";
       }    
   }

   ```
4. Create a partial view for the widget in the _\~/Views/Shared/Widgets_ folder, named **\_ExtendedFormWidget.cshtml**.
5. Call the **Html.Kentico().RenderNestedWidget** extension method to render the system's default form widget.

   ```xml

   @using Kentico.Forms.Web.Mvc.Widgets
   @using Kentico.PageBuilder.Web.Mvc
   @using Kentico.Web.Mvc

   @using LearningKit.Models.Widgets.ExtendedFormWidget

   @model ComponentViewModel<ExtendedFormWidgetProperties>

   @* Configurable heading added above the default form widget *@
   <h1>@Model.Properties.HeadingText</h1>

   @* Renders the nested form widget *@
   @Html.Kentico().RenderNestedWidget(SystemComponentIdentifiers.FORM_WIDGET_IDENTIFIER, Model.Properties)

   ```
6. Register the new widget into the system using the **RegisterWidget** assembly attribute. We recommend adding a dedicated code file to your project's _\~/App\_Start_ folder for the purposes of component registration, for example named **PageBuilderComponentRegister.cs**.

   ```csharp

   using LearningKit.Models.Widgets.ExtendedFormWidget;

   using Kentico.PageBuilder.Web.Mvc;

   // Registers the 'Extended form' widget (it uses the system's default controller and ComponentViewModel)
   [assembly: RegisterWidget("LearningKit.Widgets.ExtendedFormWidget", 
                             "Extended form",
                             typeof(ExtendedFormWidgetProperties),
                             customViewName: "Widgets/_ExtendedFormWidget",
                             IconClass = "icon-form")]

   ```

<!-- 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.

> **Note:** **Note**: The following example is based on the [LearningKit project](https://github.com/Kentico/LearningKit-Core). To use the code samples in your project, you need to modify the namespaces, identifiers and other occurrences where _LearningKit_ is mentioned to match your project's name.

1. Create a widget property model class in the _\~/Components/Widgets/ExtendedFormWidget_ folder, named **ExtendedFormWidgetProperties.cs**.
2. Make the property model inherit from the **FormWidgetProperties** class (in the _Kentico.Forms.Web.Mvc.Wigets_ namespace), which is the property model of the default form widget.
3. Define a string property representing the text of the additional heading.

   ```csharp

   using Kentico.Forms.Web.Mvc;
   using Kentico.Forms.Web.Mvc.Widgets;

   public class ExtendedFormWidgetProperties : FormWidgetProperties
   {
       // Defines a property and sets its default value
       // Assigns the default Kentico text input component, which allows users to enter
       // a textual value for the property in the widget's configuration dialog
       [EditingComponent(TextInputComponent.IDENTIFIER, Order = 0, Label = "Heading text")]
       public string HeadingText { get; set; } = "Default";

   }

   ```
4. Create a partial view for the widget in the _\~/Components/Widgets/ExtendedFormWidget_ folder, named **\_ExtendedFormWidget.cshtml**.
5. Call the **Html.Kentico().RenderNestedWidget** extension method to render the system's default form widget.

   ```xml

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

   @model ComponentViewModel<ExtendedFormWidgetProperties>
   @* Configurable heading added above the default form widget *@
   <h1>@Model.Properties.HeadingText</h1>

   @* Renders the nested form widget *@
   @await Html.Kentico().RenderNestedWidget(SystemComponentIdentifiers.FORM_WIDGET_IDENTIFIER, Model.Properties)

   ```
6. Register the new widget into the system using the **RegisterWidget** assembly attribute. We recommend adding a dedicated file to your project's _\~/Components_ folder for the purposes of component registration, for example named **ComponentRegister.cs**.

   ```csharp

   // Registers the 'Extended form' widget
   [assembly: RegisterWidget("MySite.Widgets.ExtendedFormWidget",
                             "Extended form",
                             typeof(ExtendedFormWidgetProperties),
                             customViewName: "~/Components/Widgets/ExtendedFormWidget/_ExtendedFormWidget.cshtml",
                             IconClass = "icon-form")]

   ```

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

You now have a custom widget that works exactly like the default _Form_ widget, but with an additional heading. The text of the heading can be configured in the page builder interface through a new property.
