---
title: Create a customized product widget
slug: configured-commerce/sdk/creating-a-customized-product-widget
createdAt: 2026-08-05T19:24:02.434Z
---

This widget will allow marketers and merchandisers to add products to the page without requiring any development work.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/rPR4KaKQX0mVDU1ylfav6-20260722-195247.png)

1. Add a new TypeScript controller to the Scripts/Custom folder in the \{user\["product-name"]}.Web project. Name: custom.special.controller.ts
2. Create the constructor that initializes the controller. Within the initialization use the injected product service to retrieve the product data based on the product id.

```typescript
module insite.special {
  "use strict";

  export class SpecialController {

    currentSpecial: ProductDto;
    productId: string;

    static $inject = ["$scope", "$window", "productService", "coreService"];

    constructor(protected $scope: ng.IScope,
    protected $window: ng.IWindowService,
    protected productService: IProductService,
    protected coreService: core.ICoreService) {
      this.init();
    }
    init() {
                 var expandParameter = ["documents", "specifications", "styledproducts", 
      "htmlcontent", "attributes", "crosssells", "pricing"];
      this.productService.getProductData(null, this.productId, expandParameter).then(
      (result: ProductModel) => {
        this.currentSpecial = result.product;
      },
      (error) => {
      });
    }
  }

  angular
  .module("insite")
  .controller("SpecialController", SpecialController);
}
```

3. Add a new TypeScript directive definition to the Scripts/Custom folder in the \{user\["product-name"]}.Web project. Name: custom.special.directives.ts

```typescript
module insite.account {
  "use strict";
  angular
  .module("insite")
  .directive("iscSpecialProduct", ["coreService", function (coreService) {
    return {
      restrict: "E",
      replace: true,
      templateUrl: coreService.getApiUri("/Directives/Special/SpecialSaleView"),
      controller: "SpecialController",
      controllerAs: "vm",
      scope: {
        productId: "@"
      },
      bindToController: true
    };
  }])
}
```

This lets you use the \<ISC-special-product> directive within the widget.

4. Add a new class to the project called SpecialSaleView and add a property called ProductId with the TextContentField attribute

```typescript
public class SpecialSaleView : ContentWidget
{
  [TextContentField]
  public virtual string ProductId
  {
    get { return GetValue("ProductId", "", FieldType.General); }
    set { SetValue("ProductId", value, FieldType.General); }
  }
}
```

5. If you haven't already created a new theme, create a new theme and add a new MVC View to the Views/Directives/Special folder called SpecialSaleView. This needs to be the same name as defined in the custom.special.directives.ts.
6. In the SpecialSaleView\.cshtml view add an image and span that will use the Angular model.

```xml
<div style="width:150px;">
  <h3>Product Sale</h3>
  <img ng-src="{{vm.currentSpecial.mediumImagePath}}" style="clear:both;" />
  <span ng-bind="vm.currentSpecial.name"></span>
</div>
```

7. In the custom theme add a folder for Widgets. In the widget folder add a new sub-folder called SpecialSaleView. This will also use the naming convention of the widget.
8. Add a new MVC View called Standard.cshtml. In the new Standard.cshtml file reference the special product and set the product id attribute to the model that will be set in the CMS.
9. Add a reference to the AngularJS template for the SpecialSaleView.

```xml
@model <<product-name>>.Web.Extensions.Widgets.SpecialSaleView

<ISC-special-product product-id="@Model.ProductId"></ISC-special-product>

<script type="text/ng-template" id="/Directives/Special/SpecialSaleView">
  @Html.ThemedPartial("/Views/Directives/Special/SpecialSaleView.cshtml")
</script>
```

10. Rebuild the solution and go to the \{user\["product-name"]} site with ContentAdmin rights. Add the Special Sale View widget to an existing Content zone.
