Skip to content

Creating Your First Plugin

This step-by-step guide walks you through creating a complete nopCommerce plugin from scratch.

What We'll Build

A simple "Hello World" plugin that:

  • Displays a configuration page in the admin area
  • Shows a widget message on the public store
  • Demonstrates core plugin concepts

Step 1: Create the Project

Using Visual Studio

  1. Right-click the Plugins folder in Solution Explorer
  2. Select Add > New Project
  3. Choose Class Library
  4. Name it: Nop.Plugin.Widgets.HelloWorld

Project Location

src/Plugins/
└── Nop.Plugin.Widgets.HelloWorld/
    ├── Nop.Plugin.Widgets.HelloWorld.csproj
    └── ...

Step 2: Configure the Project File

xml
<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net9.0</TargetFramework>
        <Copyright>SOME_COPYRIGHT</Copyright>
        <Company>YOUR_COMPANY</Company>
        <Authors>SOME_AUTHORS</Authors>
        <PackageLicenseUrl>PACKAGE_LICENSE_URL</PackageLicenseUrl>
        <PackageProjectUrl>PACKAGE_PROJECT_URL</PackageProjectUrl>
        <RepositoryUrl>REPOSITORY_URL</RepositoryUrl>
        <RepositoryType>Git</RepositoryType>
        <OutputPath>$(SolutionDir)\Presentation\Nop.Web\Plugins\Nop.Plugin.Widgets.HelloWorld</OutputPath>
        <OutDir>$(OutputPath)</OutDir>
        <!--Set this parameter to true to get the dlls copied from the NuGet 
        cache to the output of your project. You need to set this parameter to 
        true if your plugin has a nuget package to ensure that   the dlls 
        copied from the NuGet cache to the output of your project-->
        <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
        <ImplicitUsings>enable</ImplicitUsings>
    </PropertyGroup>
    <ItemGroup>
        <ProjectReference Include="$(SolutionDir)\Presentation\Nop.Web.Framework\Nop.Web.Framework.csproj" />
        <ClearPluginAssemblies Include="$(SolutionDir)\Build\ClearPluginAssemblies.proj" />
    </ItemGroup>
    <!-- This target executes after "Build" target -->
    <Target Name="NopTarget" AfterTargets="Build">
        <!-- Delete unnecessary libraries from plugins path -->
        <MSBuild Projects="@(ClearPluginAssemblies)" Properties="PluginPath=$(OutDir)" Targets="NopClear" />
    </Target>
</Project>

Step 3: Create plugin.json

json
{
  "Group": "Widgets",
  "FriendlyName": "Hello World Widget",
  "SystemName": "Widgets.HelloWorld",
  "Version": "1.0.0",
  "SupportedVersions": ["4.90"],
  "Author": "Your Company",
  "DisplayOrder": 100,
  "FileName": "Nop.Plugin.Widgets.HelloWorld.dll",
  "Description": "A sample Hello World widget plugin demonstrating nopCommerce plugin development."
}

System Name Convention

The SystemName should follow the pattern: {Type}.{Name} (e.g., Widgets.HelloWorld, Payment.Stripe)

Step 4: Create the Plugin Class

csharp
// HelloWorldPlugin.cs
using Nop.Core;
using Nop.Services.Cms;
using Nop.Services.Plugins;
using Nop.Web.Framework.Infrastructure;

namespace Nop.Plugin.Widgets.HelloWorld;

public class HelloWorldPlugin : BasePlugin, IWidgetPlugin
{
    #region Fields

    private readonly IWebHelper _webHelper;

    #endregion

    #region Ctor

    public HelloWorldPlugin(IWebHelper webHelper)
    {
        _webHelper = webHelper;
    }

    #endregion

    #region Methods

    /// <summary>
    /// Gets widget zones where this plugin renders content
    /// </summary>
    public Task<IList<string>> GetWidgetZonesAsync()
    {
        return Task.FromResult<IList<string>>(new List<string>
        {
            PublicWidgetZones.HomepageTop
        });
    }

    /// <summary>
    /// Gets the view component for rendering the widget
    /// </summary>
    public Type GetWidgetViewComponent(string widgetZone)
    {
        return typeof(Components.HelloWorldViewComponent);
    }

    /// <summary>
    /// Gets the configuration page URL
    /// </summary>
    public override string GetConfigurationPageUrl()
    {
        return $"{_webHelper.GetStoreLocation()}Admin/HelloWorld/Configure";
    }

    /// <summary>
    /// Install plugin
    /// </summary>
    public override async Task InstallAsync()
    {
        // Add default settings, locale resources, etc.
        await base.InstallAsync();
    }

    /// <summary>
    /// Uninstall plugin
    /// </summary>
    public override async Task UninstallAsync()
    {
        // Remove settings, locale resources, etc.
        await base.UninstallAsync();
    }

    #endregion

    #region Properties

    public bool HideInWidgetList => false;

    #endregion
}

Step 5: Create the View Component

csharp
// Components/HelloWorldViewComponent.cs
using Microsoft.AspNetCore.Mvc;
using Nop.Web.Framework.Components;

namespace Nop.Plugin.Widgets.HelloWorld.Components;

public class HelloWorldViewComponent : NopViewComponent
{
    #region Methods

    public IViewComponentResult Invoke(string widgetZone, object additionalData)
    {
        return View("~/Plugins/Widgets.HelloWorld/Views/HelloWorld.cshtml");
    }

    #endregion
}

Step 6: Create the View

html
<!-- Views/HelloWorld.cshtml -->
@{
    Layout = null;
}

<div class="hello-world-widget" style="
    background: linear-gradient(135deg, #3a8bbb 0%, #28a745 100%);
    color: white;
    padding: 20px;
    text-align: center;
    margin-bottom: 20px;
    border-radius: 8px;">
    <h2 style="margin: 0;">👋 Hello from nopCommerce Plugin!</h2>
    <p style="margin: 10px 0 0 0;">This widget is powered by your custom plugin.</p>
</div>

Step 7: Create Admin Controller

csharp
// Controllers/HelloWorldController.cs
using Microsoft.AspNetCore.Mvc;
using Nop.Web.Framework;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Mvc.Filters;

namespace Nop.Plugin.Widgets.HelloWorld.Controllers;

[AutoValidateAntiforgeryToken]
public class HelloWorldController : BaseAdminController
{
    #region Methods

    public IActionResult Configure()
    {
        return View("~/Plugins/Widgets.HelloWorld/Views/Configure.cshtml");
    }

    [HttpPost]
    public IActionResult Configure(object model)
    {
        // Save settings here
        return Configure();
    }

    #endregion
}

Step 8: Create Admin Configuration View

html
<!-- Views/Configure.cshtml -->
@{
    Layout = "_ConfigurePlugin";
}

<div class="card card-default">
    <div class="card-header">
        <h5 class="card-title">Hello World Widget Configuration</h5>
    </div>
    <div class="card-body">
        <p>Your Hello World plugin is installed and working!</p>
        <p>The widget will display on the homepage above the content.</p>
        
        <div class="alert alert-info">
            <i class="fas fa-info-circle"></i>
            To see the widget, visit your store's homepage.
        </div>
    </div>
</div>

Step 9: Build and Test

bash
# Build the plugin
dotnet build src/Plugins/Nop.Plugin.Widgets.HelloWorld

# Run nopCommerce
dotnet run --project src/Presentation/Nop.Web

Install the Plugin

  1. Go to Admin > Configuration > Local plugins
  2. Find "Hello World Widget" in the list
  3. Click Install
  4. Click Restart application to apply changes
  5. Go to Admin > Configuration > Widgets and enable the Hello World Widget

Verify It Works

  1. Visit your store's homepage
  2. You should see the "Hello from nopCommerce Plugin!" banner
  3. Go to Admin > Configuration > Widgets
  4. Click Configure next to Hello World Widget

Complete File Structure

Nop.Plugin.Widgets.HelloWorld/
├── Nop.Plugin.Widgets.HelloWorld.csproj
├── plugin.json
├── HelloWorldPlugin.cs
├── Components/
│   └── HelloWorldViewComponent.cs
├── Controllers/
│   └── HelloWorldController.cs
└── Views/
    ├── HelloWorld.cshtml
    └── Configure.cshtml

Next Steps

Now that you've created your first plugin:

Released under the nopCommerce Public License.