Speaking at SharePoint Fest Seattle 2017!

In just a few short weeks (August 8-11), I will be joining SharePoint experts from around the world at SharePoint Fest Seattle 2017! I am very excited to be debuting a new session that will take a lighthearted, but detailed look at how to attempt to achieve consistency when branding the mix of classic and modern page experiences within SharePoint Online sites, modern team sites, and recently unveiled communication sites using the SharePoint Framework along with techniques from the SharePoint add-in model:

DEV 206 – Apply Consistent UI Customizations Across Classic and Modern Pages in SharePoint Online

SharePoint Online sites are currently made up of a hodgepodge of classic and modern page experiences. A site’s home page is a classic page while the site contents page is a modern page. Page experiences may vary between pages, lists, and libraries as users navigate a site.

Although the SharePoint Framework allows you to build client-side web parts to customize both classic and modern pages, a combination of the add-in model and SharePoint Framework application customizers must be used to embed JavaScript-based UI customizations across both page types.

In this demo-intensive session, you will learn how to brand a SharePoint Online site with a customizable page header and footer that looks identical across classic and modern pages.

If you register now and use code JesseeSeattle100 at checkout, you can save $100!

My session is Friday, August 11th at 3:30 in Breakout 8. This will be my fourth SharePoint Fest and my second SharePoint Fest Seattle. I look forward to seeing you there!

Applying a custom header and footer on communication sites and modern team sites

NOTE: SharePoint Framework Extensions (such as application customizers) used in this blog post are currently in developer preview and are limited to Office 365 developer tenant sites only.

Although the title of this post indicates the particular objective I achieved, this post walks through the steps that are necessary for any scenario that requires you to have access to the classic page experience on a communication site or modern team site in SharePoint Online. In my case, the reason for this is to leverage a “legacy” app part on a classic wiki page that allows users to configure settings for a custom page header and footer. Unlike “classic” SharePoint Online sites, communication sites and modern team sites do not give you the ability to create a new wiki page in the Site Pages library that allows you to add “legacy” web parts. SharePoint Framework client-side web parts are the only custom web parts supported on modern page experiences.

Microsoft didn’t necessarily make it “easy” to do all of this, but it is possible and the process is simple if you follow the steps below.

Step 1 (modern team sites only): Disable NoScript

This step is required because my app part uses custom script to access and manipulate values stored in the site property bag. In this post, I explain the differences between modern team sites and communication sites when it comes to the default NoScript setting and show how you can query a site’s NoScript status and change it if necessary.

Because communication sites are not NoScript sites (apologies for the double negative), you do not need to perform this step on them.

Step 2: Install the SharePoint-hosted add-in

My SharePoint-hosted add-in surfaces an app part that reads configuration settings for the custom header and footer from the site property bag and allows users to update them. I built the .app package for the add-in and deployed it to my tenant’s app catalog site. This made it available to install in my communication site and modern team site:

After installing my SharePoint-hosted add-in’s SiteHeaderFooter.app file and my SharePoint Framework Application Customizer Extension’s sp-fx-header-footer.sppkg file to my tenant’s app catalog site, both are available to install on my new communication site. We will install the SharePoint Framework Application Customizer Extension in step 4 below. Notice how the addanapp.aspx page retains the “classic” page experience. This was my first clue that it would still be possible to unlock other classic page experiences–such as a classic wiki page–within these modern sites.

Step 3: Create the classic wiki page and add the “legacy” app part

If you navigate to the Site Pages library in a “classic” site, you will see the option to create a new Wiki Page within that library:

The Site Pages library within “classic” sites still allows you to create Wiki Pages with the classic page experience.

However, if you navigate to the Site Pages library in a communication site or modern team site, this option does not exist:

The Site Pages libraries within communication sites and modern team sites do not expose the option to create new Wiki Pages.

How can we add a new wiki page to the Site Pages library if the option isn’t there? By clicking the “Return to classic SharePoint” link that appears in the lower left corner of the screen:

There is much to be said about what happens when you click that link, but for our purposes it does exactly what we need (at least for the duration of our session). When viewing the same Site Pages library returned to the classic page experience, clicking the New link now prompts you for a new page name:

Specifying the page name and pressing Create gives us a new “classic” wiki page to which we can add the app part from the SharePoint-hosted add-in. Once that is done, I can configure the custom header and footer parameters and press Set Values:

Refreshing the page will display the header and footer, since this is a classic page experience that supports the user custom actions used by the add-in to embed the JavaScript responsible for rendering the header and footer:

Installing and configuring the SharePoint-hosted add-in handles the rendering of the header and footer on all classic page experiences within a site.

However, the site home page will still not display the header and footer because modern page experiences do not support user custom actions. That’s where the SharePoint Framework Application Customizer Extension comes into play.

Step 4: Install the SharePoint Framework Application Customizer Extension

Return to the addanapp.aspx page we visited earlier when installing the SharePoint-hosted add-in to our site. This time, choose to add the sp-fx-header-footer-client-side-solution. You can read all about this SharePoint Framework Application Customizer Extension and how it works in this blog post. This will activate the associated site-scoped feature that renders the header and footer on modern page experiences. You can confirm this by going to Site Settings and ensuring the SPFx HeaderFooter Application Extension – Deployment of custom action feature is Active:

When this feature is Active, the JavaScript associated with our SharePoint Framework Application Customizer Extension will execute on all modern page experiences.

Step 5: Enjoy the results

Below you can see my custom header and footer applied on both a new communication site and a modern team site:

Custom header and footer rendered on a communication site.

Custom header and footer rendered on a modern team site where I followed the same steps performed on the communication site in the steps above.

Key takeaways

– By returning to classic SharePoint, it is still possible to add new wiki pages to the Site Pages library in communication sites and modern team sites in SharePoint Online (where the option to create them is not shown by default).
– Restoring this classic page experience to modern sites allows you to leverage “legacy” app parts that were built using the add-in model without having to rebuild the functionality using a SharePoint Framework client-side web part (NOTE: this is probably something you will still want to do in most cases).
– Even when your “Return to classic SharePoint” session cookie expires, your classic wiki page will remain in the Site Pages library and is still completely accessible.
– Applying branding such as a custom header and footer to modern sites–especially those that contain a combination of classic and modern page experiences–will require a multifaceted approach that may include capabilities from the SharePoint add-in model as well as SharePoint Framework.

Keep in mind that all of the SharePoint Framework Application Customizer Extension capabilities demonstrated in this post are in developer preview and much of what I have outlined above is subject to change before they reach general availability in the months ahead.

SharePoint Framework page placeholders on new communication sites

UPDATE 8/13/2017: As of August 11, 2017, all modern site pages also contain the PageFooter placeholder.

The original post from July 1, 2017 appears below.

Earlier this month, Microsoft launched the developer preview of SharePoint Framework Extensions. I examined the available page placeholders on modern list and library pages, the modern Site Contents page, and modern site pages in this blog post.

With the rollout of SharePoint communication sites now underway, I thought I would take this opportunity to confirm the available page placeholders on each of the three new communication site designs:

– Topic
– Showcase
– Blank

Communication sites are based on the SITEPAGEPUBLISHING#0 template and feature a new responsive modern site page for the site home page. Based on my previous research, it came as no surprise that all three modern communication site page designs contain the PageHeader placeholder but not the PageFooter placeholder.

Below are screenshots of all three communication site designs in Edge and the SharePoint mobile app, reflecting the custom content rendered in the PageHeader placeholder after deploying the SharePoint Framework Hello World Application Customizer Extension.




(8/13/2017) NOTE: All three communication site designs–as well as all modern site pages in general–now also contain the PageFooter placeholder.

What if I also need a custom footer on these modern communication site pages?

I recently implemented a custom header and footer SharePoint Framework Application Customizer Extension that was based on a custom header and footer SharePoint-hosted add-in I developed back in 2015. This particular extension works great on the modern page experiences within my “classic” SharePoint Online site because I am able to leverage the SharePoint-hosted add-in part (on a classic wiki page) that maintains the custom header and footer configuration parameters in the site property bag.

In my next post, I will show you how to create a classic wiki page in a modern communication site (unlike in classic sites, you can’t just go to New > Wiki Page in the Site Pages library) to leverage the SharePoint-hosted add-in part to configure the custom header and footer configuration parameters in the site property bag. My SharePoint Framework Application Customizer Extension will then read these values from the property bag and render the custom header and footer.

As an added bonus, I will also show you the extra step necessary to accomplish this on a modern team site, a so-called “NoScript site” that does not allow custom script to access the site property bag by default.

SharePoint Online modern team sites and communication sites are NoScript sites

UPDATE 8/13/2017: As it now appears that communication sites will be NoScript sites by default, I have updated the title of this post to reflect this change and avoid any confusion.

See below for more history.

UPDATE 8/1/2017: Newly created communication sites are still NoScript sites by default; however, as of today I am again able to disable NoScript on them by running the Set-SPOSite cmdlet shown in the post below. See this Github issue for more information.

UPDATE 7/22/2017: It appears that newly created communication sites are also NoScript sites by default, and I am currently receiving an error when I try to disable NoScript on one:

The original post from July 1, 2017 appears below.

While new SharePoint Online communication sites continue to roll out across First Release – Select Users tenants, I discovered an interesting difference between them and modern team sites. Modern team sites have been around since late 2016 and are connected to an Office 365 Group when they are created. They are also so-called “NoScript sites” by default, which affects the types of customizations that can be applied to them. They use the GROUP#0 template and not the STS#0 template used by “classic” team sites (which can still contain modern page experiences…confused yet?)

My “classic” team site uses the STS#0 template while my “modern” team site uses the GROUP#0 template.

Some of the original guidance suggested that NoScript could not be disabled on modern team sites, but earlier this week Microsoft decided to officially support disabling NoScript on modern team sites. The documentation on MSDN has been updated to reflect this as well.

Checking the NoScript status of a site

You can query a site’s DenyAddAndCustomizePages property via PowerShell:

$site = Get-SPOSite https://yoursite.sharepoint.com

If the value is Enabled, your site is a NoScript site. To disable it, run the following cmdlet:

Set-SPOSite https://yoursite.sharepoint.com -DenyAddAndCustomizePages 0

Disabling NoScript allows users to run custom scripts on a site and allows custom script to do things such as access a site’s property bag. This may come in handy if you happen to have a solution that requires this. Stay tuned for more about that!

What about communication sites?

Since communication sites are new modern sites, you might expect them to be NoScript sites as well. However, this is not the case. Communication sites use the SITEPAGEPUBLISHING#0 template and come with the DenyAddAndCustomizePages property Disabled out of the box:

My communication site uses the SITEPAGEPUBLISHING#0 template and already has NoScript disabled.

In summary:

(8/13/2017) NOTE: Both modern team sites and communication sites now have NoScript enabled by default. In either case, NoScript can be disabled by running the appropriate Set-SPOSite cmdlet detailed above.

In an upcoming post, I will leverage this knowledge to apply my custom header and footer SharePoint Framework Application Customizer Extension to both modern team sites and communication sites.

The “opt out of modern experiences” (splnu) cookie applies to all sites in your tenant subdomain

In my last post, I showed how you must click Return to classic SharePoint in order to remove an app from SharePoint Online’s modern Site Contents page. Clicking Return to classic SharePoint sets a session cookie named splnu with a Content attribute value of 0:

As long as this cookie is present, pages that would typically render using the modern page experience (such as the Site Contents page) will use the classic page experience instead. But did you catch something about that cookie in the screenshot above? It is set with a Path attribute value of /:

Based on this explanation of the purpose of a cookie’s Domain and Path attribute values as defined in RFC 6265, the value of the Path attribute can be used to scope the cookie to a particular URL (and its subdirectories). However, when it is set to /, the browser will use the cookie for any path within the cookie’s domain.

From any site, it affects every site

It turns out that the splnu cookie’s Path attribute is set to / no matter which site or subsite you choose to return to the classic page experience. I tested this by clicking Return to classic SharePoint from each of the following sites within my tenant (clearing my cookies between each test):

https://djsp.sharepoint.com (root site collection)
https://djsp.sharepoint.com/test (subsite of root site collection)
https://djsp.sharepoint.com/sites/test (root of new private site collection)

In all of these scenarios, the same splnu cookie was created with the same Path attribute of /, no matter the subdirectory from which the request was initiated.

What does this mean?

For the duration of your session (splnu is a session cookie), you will be returned to the classic SharePoint page experience on ALL sites that share the same parent domain (in my example above, the root site collection, subsite, and private site collection underneath the /sites path all share the same parent domain–djsp.sharepoint.com–and are therefore all matches for the Path of /).

This may not be a major issue for you since the splnu cookie is only valid for the duration of your session, and as I suggest in my last post, the effects of this cookie can be mitigated by using your browser’s “private browsing” or “incognito” mode. However, this behavior may cause confusion since you might expect the Return to classic SharePoint link to only apply within the scope of the particular site where you selected it.

To that end, I have submitted this UserVoice request asking the product team to consider appropriately scoping the Path attribute value of the splnu session cookie based on where the user has asked to return to the classic page experience. Feel free to vote or comment on my request.

The easy way to remove an app from modern SharePoint Online

If you are using the modern page experiences in SharePoint Online, perhaps you’ve run into a moment of frustration when you go to the Site Contents screen to remove an installed app (err, add-in?) and discover you can’t.

Clicking the brings up a context menu with only two options, Details and Monitor. Hmmm…no Remove here:

Uh oh, how do I remove this thing?

It turns out that you have to switch the Site Contents page back to the classic page experience in order to remove an app. This little nugget is buried in an Office support article:

Glad I scrolled all the way to the bottom of this article.

Sure enough, once you return to the classic page experience, the Remove link is there as you would expect.

You may need to expand the left navigation to see this link at the bottom.

After clicking Return to classic SharePoint, apps can be removed from the classic Site Contents screen.

There was only one problem: despite the support article’s guidance to “use the Back button in the browser to return from classic view,” at least when I pressed my browser’s back button, my browser retained the classic page experience. I navigated away from the Site Contents page and back to it again…still classic. And when I went to a list view page that was formerly using the modern page experience, that page now had the classic experience as well. Only some document libraries and site pages were still using the modern page experience.

What’s going on here?

The good news is that clicking Return to classic SharePoint doesn’t actually change any SharePoint Online settings, nor does it change any user settings (not even your own). This is why you won’t find a link anywhere to “Return to modern SharePoint” after you’ve switched to classic view. Switching to classic view simply sets a session cookie that changes your default page experience. You can locate and remove this cookie to switch back immediately or just wait until your session expires. For the intellectually curious, the cookie is named splnu (anyone want to guess what that stands for?) and contains this information:

Removing this cookie will return you to the modern page experience. However, for the duration of your session, the presence of this cookie will cause pages to be rendered with the classic page experience on all sites within your tenant subdomain.

To avoid this problem altogether, I prefer to take advantage of my browser’s “private browsing” or “incognito” mode. This allows me to log in to my SharePoint Online site, go to my Site Contents page, switch to classic view, and remove the app, all without interfering with any existing cookies on my machine and eliminating the hassle of having to potentially locate and remove the splnu cookie after the fact.

Hopefully this will help the next time you need to remove an app from SharePoint Online!

Custom modern page header and footer using SharePoint Framework

NOTE: SharePoint Framework Extensions (such as application customizers) used in this blog post are currently in developer preview and are limited to Office 365 developer tenant sites only.

Back in 2015, I published a post on this blog detailing the steps for implementing a custom site header and footer using a SharePoint-hosted add-in. The add-in contained:

1. An add-in part that provides an interface to configure the text and colors associated with the custom header and footer, storing the necessary values in the property bag of the site.

2. Custom JavaScript that is embedded on every (classic) page through the use of user custom actions that reads the values set by the add-in part from the property bag and renders the header and footer on each page.

An add-in part is used to display and update the site header and footer configuration information, which is stored in the site property bag. User custom actions are then used to embed the JavaScript that reads this information and renders the header and footer on all (classic) pages within a site.

Issues with current add-in solution

While the add-in solution from that blog post worked great in SharePoint Online in 2015 (and still works great for SharePoint Online classic pages and SharePoint 2013/2016 on-premises today), SharePoint Online has evolved somewhat over the past two years.

Since late 2016, Microsoft has been rolling out new modern page experiences across SharePoint Online. These include new modern team site pages as well as list and library view pages. The technique I used for embedding custom JavaScript on every page–namely, user custom actions–are not supported on modern pages. Therefore, even with the add-in deployed and configured you will not see a header or footer on any modern page. So how are we supposed to customize them?

Enter SharePoint Framework

The SharePoint Framework gives us a new way to deploy JavaScript-based customizations to SharePoint. These include web parts (for both classic and modern pages) and now Extensions such as Application Customizers (in developer preview) that allow you to embed JavaScript on modern pages.

To extend the functionality of my SharePoint-hosted add-in to modern pages using the SharePoint Framework, I created a new SharePoint client-side solution containing an application customizer extension to handle the rendering of the header and footer on all modern pages, reading the same configuration values from the site property bag that are set by the add-in part from my original SharePoint-hosted add-in.

Modern pages contain useful placeholders

When creating the original add-in, I had to do some manipulation of the DOM to insert the <div> elements representing the custom header and footer in the appropriate places on the page using jQuery’s .insertBefore() and .insertAfter() methods. These kinds of customizations are fragile and could break if Microsoft changed the IDs or locations of existing page elements I was referencing such as suiteBarTop or s4-bodycontainer. I was hoping to get away from this in my modern page solution.

To that end, SharePoint Framework Extensions now give us access to page placeholders representing well-known locations on the page where we can more reliably inject our customizations. These include PageHeader and PageFooter. Awesome, right?

Unfortunately, in my initial experiments with page placeholders, I identified some shortcomings that would prevent me from building a complete modern page header/footer solution that leverages them. Most notably, modern site pages do not contain the PageFooter placeholder at all. Also, since my current solution renders the header at the very top of the page, I wasn’t a fan of the PageHeader placeholder location beneath the #suiteBarTop <div> instead of above it at the very top of the page.

SharePoint Framework page placeholders render the PageHeader below the suiteBarTop <div> and do not render a PageFooter on modern site pages, as shown above.


NOTE: This approach still relies on DOM manipulation and is a fragile and unsupported way to make user interface customizations to modern pages because of dependencies on page elements with specific IDs and CSS classes. In your solutions, please make every effort to leverage the supported page placeholders if possible.

With these limitations in mind and for the sake of a consistent look and feel across all pages (both classic and modern), I decided to stick with my jQuery-based approach of using .insertBefore() and .insertAfter() to inject my custom header and footer at the top and bottom of the page. While investigating the DOM on modern pages to determine where I would need to inject my header and footer, I realized that not all modern pages are created alike. Perhaps this is part of the reason why modern site pages do not contain a PageFooter placeholder…

The <div> element representing the page content on modern list and library view pages (and the modern Site Contents page) has an ID of spoAppComponent. This <div> does not exist on modern site pages. On modern site pages, the <div> element representing the page content has a class of SPPageChrome. (NOTE: modern list and library view pages also contain a <div> with a class of SPPageChrome, but this <div> does not represent the main content area on those pages.)

Page content areas on a modern list/library view page (left) and a modern site page (right) with the custom header and footer injected around them.

In my code, you will see that I test for the existence of #spoAppComponent on the page. If it exists, I know I’m on a modern list or library view page and I inject the custom header and footer around that <div>. Otherwise, I add the header and footer around the <div> with class SPPageChrome.

Building the Application Customizer

I followed the step-by-step instructions from the four-part Office Dev Center article series Build your first extension to generate, build, and deploy my application customizer. The following notes may be useful to you:

– If you have already installed a previous version of Microsoft’s Yeoman SharePoint Client-side Solution Generator, you will need to update it by running npm update -g @microsoft/generator-sharepoint. The current version of the generator (as of the publishing of this post) is now 1.1.1.

– If you haven’t updated your SharePoint Framework development environment in awhile, you may want to run npm update -g to ensure the rest of your global packages are up-to-date as well.

– I added jQuery (npm install –save jquery) and sp-pnp-js (npm install –save sp-pnp-js) to my project and used the PnP JavaScript Core library to simplify the API query for the header and footer configuration values from the site property bag.

– Since I didn’t make use of any ClientSideComponentProperties, I removed that attribute from my ./sharepoint/assets/elements.xml file.

– If you download this code, you will need to update the CDN URL in the ./config/write-manifests.json file to match the location where you deploy the assets from the ./temp/deploy folder in your environment. More information about working with the Office 365 CDN may be found here.

– Remember that you must upload the .sppkg file from the ./sharepoint/solution folder to your tenant’s app catalog site, then add the associated app on your site. This will provision and activate the feature that deploys the application customizer to your site.

The code

My code is posted to GitHub at the following location:


I encourage you to download it, try it out in your environment, and let me know if you run into any issues with it. Please keep the following things in mind:

– This application customizer will only work on modern pages in SharePoint Online developer tenant sites while the capability is still in developer preview.

– You must also install the SharePoint-hosted add-in located here in order to configure the header and footer property bag values and render them on classic pages.

– Although the above dependency on my SharePoint-hosted add-in currently exists, it should be possible to move all of these capabilities into a SharePoint Framework solution (i.e., by building a client-side web part to read and write the property bag configuration values and apply the user custom actions to classic pages within the site using the REST API, JSOM, or the PnP JavaScript Core library).

Stay tuned!

This is a very exciting time to be doing modern SharePoint development. SharePoint Framework extensions should be out of developer preview by the end of 2017 and even more new capabilities and options for modern SharePoint customizations are still in the pipeline. Keep an eye on the SharePoint Framework wiki for more announcements and updates!

An early look at the new SharePoint Framework page placeholders

UPDATE 8/13/2017: As of August 11, 2017, all modern site pages also contain the PageFooter placeholder.

The original post from June 9, 2017 appears below.

We finally received some much anticipated news this week: SharePoint Framework Extensions are now available in developer preview! For a full overview of the new capabilities that are now available in your Office 365 developer tenant, I encourage you to read through the official documentation and labs here.

As someone who developed a SharePoint-hosted add-in a couple years ago that renders a custom site header and footer on every page, I was especially excited to begin playing with the new page placeholders that were available to use within Application Customizer Extensions. According to the definition of an Application Customizer Extension, they “allow developers to add script to the page, as well as access well-known HTML element placeholders and extend them with custom renderings.” The sample walkthrough shows how to render a custom header and footer using placeholders on a modern list view page.

Once you have updated your SharePoint Framework packages (in particular the Yeoman generator for SharePoint, which is now version 1.1.1 as of June 8) and scaffolded your first Application Customizer Extension, you can follow the steps in the walkthrough and see how to inject custom HTML into these page placeholders without too much effort.

I was curious to see which placeholders are available–namely if there were any others besides PageHeader and PageFooter, the two used in the sample walkthrough–and how they would look. I tested the walkthrough code on each of the modern page experiences:

  1. Modern library view page
  2. Modern list view page
  3. Modern Site Contents page
  4. Modern page in SitePages library

For experiences 1-3, I saw the same results in my console:

The “defined” clientSidePlaceholders were:

  • DialogContainer (I haven’t been able to successfully find or use this one anywhere yet)
  • PageHeader
  • PageFooter

After the onRender() method was called, the “available” placeholders were:

  • PageHeader
  • PageFooter

Consequently, the header and footer rendered properly on each of these page types as shown in the walkthrough (modern library view shown below, the others looked exactly the same):

However, for a modern page in the SitePages library, my console showed something a little different:

For whatever reason, modern site pages do not appear to contain a PageFooter placeholder. As you can see, only the PageHeader rendered on this page:

(8/13/2017) NOTE: All modern site pages now also contain the PageFooter placeholder.

This may be intentional and by design or it may be subject to change in the future. There will no doubt be many updates, fixes, and enhancements to page placeholders, Application Customizer Extensions, and the SharePoint Framework in general over the weeks and months ahead.

Going back to my blog post from 2015, the advent of modern page experiences in SharePoint Online has produced some new challenges to overcome if your objective is to apply a custom header and footer across all pages in a SharePoint Online site as things stand today:

  • My SharePoint-hosted add-in solution from 2015 uses customization techniques (e.g., user custom actions that inject JavaScript on every page) that are not supported in modern page experiences.
  • SharePoint Framework Application Customizer Extensions only work on modern page experiences (and as seen above, modern site pages do not currently contain a PageFooter placeholder).

The story here will no doubt evolve and improve as time goes on and I will continue to post updates as these changes take place. In the meantime, I encourage you to follow this frequently updated guidance on how to customize the modern experiences in SharePoint Online and keep a close eye on the official SharePoint Framework documentation.

Installing a Let’s Encrypt SSL certificate on Winhost with only a Windows 10 workstation

Author’s note: We will return to our regularly scheduled SharePoint programming soon, but I wanted to share this story for anyone in my shoes who wants to create and install a free Let’s Encrypt SSL certificate in a cPanel/shared hosting environment such as Winhost without direct server access. This is the post I wish I could have found when I started on this journey.

I have hosted this blog on Winhost since 2014. I am a huge fan of their affordable, reliable web hosting and friendly, responsive customer support. However, I am not a fan of paying $39-$49 (or more) per year just to have a simple SSL certificate for a personal blog site.

Let’s Encrypt is a free and automated Certificate Authority (CA) that has major community backing. I am an ardent supporter of their mission and believe we should do everything possible to support “HTTPS everywhere.” Many web hosting providers integrate Let’s Encrypt support right out of the box and if yours is one of them, you need not read any further. However, if you are using a shared hosting provider with a cPanel such as Winhost that is somewhere between lukewarm and slightly hostile toward Let’s Encrypt, do not fear. It is still possible to create and install a FREE SSL certificate for your site.

I would like to add that despite the “slightly hostile” Winhost blog post linked above, Winhost support was extremely helpful with a couple of issues I had during this process. If they were upset with me for not buying my SSL certificate through them, they didn’t let it show. 🙂

Certificate Signing Request (CSR)

When requesting an SSL certificate, you must specify a Certificate Signing Request (CSR). I don’t pretend to fully understand how all of this works, but through this process I have learned that the CSR is based on a public/private key pair generated on the server. Therefore, when using a hosting provider like Winhost you must allow them to generate the CSR and not attempt to generate one yourself (unfortunately, this rules out using alternative methods for getting a free SSL certificate such as gethttpsforfree.com, which requires you to have access to the private key).

Within your cPanel, navigate to the SSL Manager and click Generate New CSR. Enter the domain name you wish to protect in the Common Name field. After filling in all the fields, press Submit CSR Information.

This will produce output like what you see below:

Copy this text into a file on your local workstation. I called mine domain.csr. You will need to reference this file when submitting your certificate request.


Let’s Encrypt recommends the use of Certbot to get your certificate. Certbot is only available for UNIX-like operating systems (e.g., Linux and MacOS). If you are running Windows 10, however, you can enable and run a Bash shell on Ubuntu 16.04!

Certbot is used to request the certificate and is especially useful when it can be run directly on the web server. Obviously I could not do this, but fortunately Certbot also offers a “manual mode” that lets you specify the CSR to use when submitting your request and prove ownership of your domain without running it directly on the server where the certificate is to be installed.

After you have followed the steps to get Bash on Windows 10, launch Bash on Ubuntu on Windows and run the following commands to install Certbot:

$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install certbot

Once this is complete, you can begin the process of requesting your certificate. The command to run is:

$ certbot certonly --manual --csr <path to domain.csr file>

NOTE: Your Windows C: drive is mounted as /mnt/c in Ubuntu.

You must consent to your IP being logged in association with this certificate request.

Once that is done, Certbot asks that you prove ownership of the domain for which you are requesting a certificate by serving a specific string of plain-text content from a URL in the /.well-known/acme-challenge subdirectory of your domain.

To accomplish this, I created a plain-text file in Notepad and named it according to the URL specified. I pasted in the string of content that is supposed to be served from that URL and uploaded it to the appropriate directory of my web site using FTP. Before pressing Enter, I navigated to the URL to ensure the appropriate content was being served, but I received the following error:

Because the file has no extension and is being served out from IIS, I also need to create a new web.config file in this directory, telling IIS to treat this extensionless file as plain text when serving it out:

<?xml version="1.0" encoding="UTF-8"?>
            <mimeMap fileExtension="." mimeType="text/plain" />

After saving and uploading the web.config file, I confirmed that I was serving out the correct content from the specified URL. I returned to my Bash shell and pressed Enter.

Now that you have proven ownership of your domain, Certbot will request the certificate for your domain and write it out to a .pem file on your workstation.

We can now copy the contents of this file (in this case, 0000_cert.prm) and paste it in our cPanel where it requests the SSL certificate:

Press Submit Certificate. It took about 20 seconds for me, and you won’t see any fancy success or confirmation messages, but after you are redirected away from this page you can navigate to your site and see that it is secured with the Let’s Encrypt certificate.


There are some caveats worth pointing out below that may not make this the best solution for you.

– At least for Winhost, the CSR you generate can only contain a single Common Name. Unfortunately, you cannot get a certificate that protects both yourdomain.com and yourotherdomain.com, or even yourdomain.com and www.yourdomain.com.
– The certificate expires every 90 days, so you will need to repeat this process to renew the certificate fairly often. This is worth the cost savings, at least for me.

Despite these caveats, I am thrilled to have my free SSL certificate from Let’s Encrypt protecting my Winhost-hosted site and I hope these steps are useful for someone else.

One final author’s note: I am a SharePoint developer by trade and am far from an expert when it comes to web servers and SSL. If I have misstated anything in this post, please leave a correction in the comments and I will update this post. In addition to hopefully being useful, I want to ensure I am being accurate as well. Thanks!

Tooling up for SharePoint Framework

Over a year ago, Microsoft first announced the SharePoint Framework (SPFx) at the Future of SharePoint event. Accompanying the introduction was this blog post describing the SharePoint Framework as “an open and connected platform” that represents the next step in a natural evolution toward client-side development and customization on top of SharePoint. The SharePoint Framework allows developers to use modern web paradigms and JavaScript frameworks and moves away from the more Microsoft-specific legacy server-side customizations of the past.

The SharePoint Framework finally reached GA in February 2017 and is currently available in SharePoint Online. SharePoint Framework support will be available to SharePoint 2016 on-premises users with the release of Feature Pack 2 later this year.

Getting started with the new developer toolchain

Perhaps the largest barrier to entry when it comes to getting started with development using the SharePoint Framework is the new developer toolchain, which bears very little resemblance to any SharePoint development tools you may have used in the past. Gone are the days of just cracking open Visual Studio to build a SharePoint solution (although Eric Shupps has just announced the SharePoint Framework Extension for Visual Studio, so definitely check that out if you want to continue leveraging Visual Studio as part of your development workflow).

In exchange for the added complexity introduced by this new toolchain we get a set of modern, open-source, cross-platform tools and technologies that finally levels the playing field between SharePoint development and modern web development (try leveraging React or Angular in a Script Editor Web Part!) and opens the door for developers on Linux and Mac OS to build SharePoint customizations. It also eliminates the need for a local SharePoint farm on the developer workstation for on-premises development. Moving forward, the SharePoint Framework is your only option for building custom web parts that can be added to the new modern page experiences.

Even if you decide to leverage the SharePoint Framework Extension for Visual Studio, you will still need to install–and have a basic understanding of–all of the prerequisite tools and technologies that comprise this developer toolchain, which include:

Tool Purpose
Node.js (LTS version) JavaScript runtime; most of the other tools in the toolchain are built on Node.js
npm Package and dependency management
Yeoman Scaffolding engine for new projects
TypeScript Typed superset of JavaScript; transpiles to plain JavaScript
Gulp Extensible build task runner

My Pluralsight course

Feeling overwhelmed? I recently published a Pluralsight course that contains short, easy-to-digest modules and demos, each introducing a different item in the toolchain: Tooling up for SharePoint Framework. The course is geared toward “newbies” with little to no prior experience using any of these new tools and technologies. If you follow along with the course, within about an hour you will be able to stand up a new, fully-configured SharePoint Framework development workstation and create, build, and test your first client-side web part. The clip below is a demo from the course showing how to use the Workbench that is included with the SharePoint Framework to test customizations locally without having to deploy anything to SharePoint (another advantage over “legacy” SharePoint development).

What the future holds

Client-side web parts are the first of what will ultimately be many types of JavaScript customizations supported by the SharePoint Framework. According to this blog post from the Office Team, we can expect to see support for the following customizations coming to the SharePoint Framework soon:

  • Web Part Connections that allow client-side web parts to communicate and exchange information with each other
  • ApplicationCustomizers to embed JavaScript on pages within SharePoint sites
  • FieldCustomizers to update the way data is displayed in a list view, similar to JSLink
  • CommandSets to add custom ECB actions, toolbar buttons, etc.

Finally: SPFx vs. the Add-in Model

As the SharePoint Framework continues to evolve and mature, you may encounter scenarios where you cannot use it to achieve a particular objective. In these cases (and many other cases, such as those where server-side code is still necessary), the Add-in model is still viable and fully supported. Microsoft intends for the SharePoint Framework to be complementary to the Add-in model, not a replacement for it. If you’re interested in learning more about updating your legacy SharePoint customizations to take advantage of the Add-in model, please check out my blog post and Pluralsight course.