New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.

DNN9: Diving in a ReactJS Persona Bar Extension

Previously, I went over the setup and compilation steps needed to launch a React app in a Persona Bar extension. Now, I want to go under the hood and explain the inner wiring between Persona Bar and the app itself.

Useful Blogs

Before we proceed, you may want to reference these blogs:

  1. DNN 9: Persona Bar Architecture

  2. DNN 9: Extending the Persona Bar

  3. DNN9: Adding a ReactJS App to Persona Bar

Standard extension vs. React extension

We will now highlight the differences between the standard extension and a React extension. To start with, the main Html and JavaScript files are different. There is an entire new application.web (replace application with your app's name) folder in the source code repository containing code for React. 

Difference in Html 

Difference in the Html File

The old Html had a standard div containing a line of plain text. This text was printed "as is" on the canvas. We will replace the div with a new one. The new div has only one attributes,  id with a value helloworld-container.

We will dig into this id very soon, let's look into JavaScript for now.

Difference in JavaScript

The JavaScript has more changes than the Html file.

Old JavaScript File New JavaScript File

Change in parameters

We pass a different parameter - '$'. This is jQuery, which is used later to make an ajax call.

function ($)

Change in init method

The init method calls a new method loadScript.

            init: function (wrapper, util, params, callback) {

New loadScrpt method

The LoadScript method loads the bundle.js file via ajax. Note the path of the bundle file, it is scripts/bundles/ folder.

        function loadScript() {
            var url = "scripts/bundles/helloworld-bundle.js";
                dataType: "script",
                cache: true,
                url: url


Search for "hello" in the folder

Search for Hello in files

The next step is to dig deeper into the React code base. Some of the code is just boiler plate, and some are specific to this extension. It's a always a good idea to search for hello in the folder HelloWorld.Web and see how many hits we get. We found 4 files. Let's get into them one by one.


Besides other information, this file also stores the name of the output bundle file that gets created after build is completed. This is where helloworld-bundle.js is found.


This file stores the name of the package that you are building. You can use the name helloworld to reference it as a component in another React app.


Main.jsx is the starting point for this application. A React app needs a div (or container) to attach itself to. Recall that we defined a div in the main html file. It's id was helloworld-container. This is what we will hook React to. React will automatically render itself here.


Even though Main.jsx is the starting point, the real app starts from App.Jsx. Most of the React file contains a function render, which is responsible for generating the Html content. All we are doing here is putting a title "Hello World", using one of the DNN's common component named SocialPanelHeader.

This component is further wrapped around another DNN common component PersonaBarPage.

Relationship between Webpack and Package

Webpack.config.js defines a constant webpackExternals, which references dnn-webpack-externals component defined in Package.json. The entire common component set is actually made available at run time in the browser by Persona Bar core. However, this relationship must be defined in this specific way for your React source to be compiled and a bundle created.

Relationship between WebPack and Package Json

Common Components

The DNN team has built several common React components to be used in Persona Bar extension. The source code for such components can be found here:

Using Common React Components in extensions

We have two main common components that you can use: dnn-global-styles and dnn-webpack-externals. The first one pertains to styling, which we will discuss in a future blog. The second one - dnn-webpack-externals contains all the common React components made available in the Persona Bar.

An easy way to look at all the common components running is to open the developer tool in your browser with Persona Bar running and issue the following command:


It will list all the common components, e.g. Button, Checkbox, etc.

Common Components In Browser Console


Entry point in the App

Each app must have a starting point. We use Webpack as the module loader, where the starting point needs to be defined. In our example, it is indicated by entry. This points to main.jsx file under src sub-folder.

Code for Webpack with Entry


The main.jsx file has a render method that contains Provider, Root and Container. 

Provider pertains to Redux state, that we will discuss in a future blog. Use of Redux is optional, however we are using Redux heavily for state management, so might as well have it from the get go.

The Container points to the div on the Html file to which the React app will hook itself to. Root is where the real application starts.

Code for Main


Root is defined under src/containers folder. It simply loads a production or development version of the application. We will talk about development tools in a future blog. They both load a component called App.

Code for Root

App is defined under src/components. This is where the application really starts. The common components are mostly used here or any other sub-components referenced further. In this example, we are using two common components – PersonaBarPage and SocialPanelHeader. PersonaBarPage has one property – isOpen. SocialPanelHeader also has one property – title. In this example we are setting the value of title as Hello World, which is what gets printed in the final Html output.

Code for App

The properties exposed by these common components can also be seen in the developer console.

Common Component Properties In Browser Console


Final Html Markup

The final html mark shows the common components used in the app. It also shows the main div for the application – hello-world-container.

Final Markup
  • Published:


Stephen Lim
@Ash, is Webpack necessary to build pages for persona bar?

Are developers free to use any of their own chosen build script?

Is Redux necessary or required to use the common components?
Stephen Lim Thursday, November 24, 2016 4:36 PM (link)
Ash Prasad
@Stephen - None of that is necessary. Developers can use whatever framework they like. It all depends on how you load your extension's JS into Persona Bar. This example uses React, which is loaded via loadScript method above. You are free to use whatever you like.
Ash Prasad Tuesday, December 13, 2016 12:42 PM (link)
Will Strohl
@Ash: Are you still planning to post another article that speaks to the styling?
Will Strohl Monday, October 30, 2017 7:58 PM (link)

Comment Form

Only registered users may post comments.


Aderson Oliveira (22)
Alec Whittington (11)
Alessandra Daniels (3)
Alex Shirley (10)
Andrew Hoefling (3)
Andrew Nurse (30)
Andy Tryba (1)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (37)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Bogdan Litescu (1)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (213)
Chris Paterra (55)
Clint Patterson (108)
Cuong Dang (21)
Daniel Bartholomew (2)
Daniel Mettler (181)
Daniel Valadas (48)
Dave Buckner (2)
David Poindexter (12)
David Rodriguez (3)
Dennis Shiao (1)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (80)
Francisco Perez Andres (17)
Geoff Barlow (12)
George Alatrash (12)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (274)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Kelly Ford (4)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matt Rutledge (2)
Matthias Schlomann (16)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Miguel Gatmaytan (3)
Mike Horton (19)
Mitchel Sellers (40)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Oliver Hine (1)
Patricio F. Salinas (1)
Patrick Ryan (1)
Peter Donker (54)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Sacha Trauwaen (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott Schlesier (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Steven Fisher (1)
Tony Henrich (3)
Torsten Weggen (3)
Tycho de Waard (4)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (40)
Will Strohl (180)
William Severance (5)
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out