New CodeTour Option for SharePoint Framework (SPFx) Upgrades in the Office 365 CLI

2 minute read

I tried out the relatively new CodeTour option in the Office 365 CLI today to upgrade a SharePoint Framework (SPFx) Web Part solution. I originally built the Web Part to work in SharePoint 2019, so the underlying SPFx version was 1.4.1. I wanted to get it “up to rev” to 1.10.0 to put a cleaned up version of it into the pnp/sp-dev-fx-webparts repo of SPFx samples.

The first thing I needed to do was install the CodeTour extension for VSCode, which you can download from the marketplace.

Next, I made sure I had the latest version of the Office 365 CLI by running:

You’ll need version 2.1.0 or greater. The line above will install the Office 365 CLI globally, which is probably what you want.

To get the tour started (and who doesn’t like a good tour?), I simply ran the following:

o365 spfx project upgrade –output tour

This created a tour in the CodeTour section in the left rail in VS Code, which looks something like this:

To start the tour, I just clicked on the Upgrade project… row, which expanded out all the steps I needed to complete the upgrade.

Because I was going all the way from SPFx 1.4.1 to 1.10.1, there were 44 steps. That’s more that you would generally see, since it’s such a big jump.

The great thing about this is each step does the following:

Highlights the row of code or parameter which needs to change. You see the exact context for the change.Provides some information about what the step will do. I expect these messages will improve over time.Gives you a link to click to accomplish the step if it’s possible to automate it. If it’s not possible to automate it, you get instructions about what to do yourself.

In the past, when I used the spfx project upgrade command, I’d scroll all the way down to the output, copy the commands out, and just paste them into the terminal. I didn’t really take the time to understand what specifically was happening because I didn’t need to. (I trust Waldek Mastykarz (@waldekm) and Gary Trinder (@garrytrinder), who manage the Office 365 CLI project. Maybe I trust them too much?)

I like the fact that the CodeTour approach lets me pay a bit more attention, without spending much more time to get the work done. If you’re interested in understanding more about the internal workings of SFPx, this is a nice middle ground: it gets the upgrade done pretty painlessly, but you can follow along and learn some things.

Give it a try and let me know what you think in the comments…

I was remiss in the initial version of this post in not giving Hugo Bernier (@bernierh) credit for his work on the CodeTour updates.


SharePoint Online – Provisioning Microsoft 365 learning pathways Error

Another day of Office 365 Admin’s life, today one of the customer having the issue with Microsoft 365 learning pathways site.

Global admin successfully provisioned the learning site and hand over to the customer. But when users browse the site, home page loading without any issue but when they click on any other link i.e., they get the error: “Something went wrong”

And here is the detailed error.


Something went wrong

If the problem persists, contact the site administrator and give them the information in Technical Details.

Technical Details

[SPLoaderError.loadComponentError]:***Failed to load component “141d4ab7-b6ca-4bf4-ac59-25b7bf93642d” (CustomLearningWebPart). Original error: ***Failed to load URL ‘’ for resource ‘CustomLearningWebPartStrings’ in component ‘141d4ab7-b6ca-4bf4-ac59-25b7bf93642d’ (CustomLearningWebPart). There was a network problem. This may be a problem with a HTTPS certificate. Make sure you have the right certificate.

***INNERERROR:***Failed to load URL ‘’ for resource ‘CustomLearningWebPartStrings’ in component ‘141d4ab7-b6ca-4bf4-ac59-25b7bf93642d’ (CustomLearningWebPart). There was a network problem. This may be a problem with a HTTPS certificate. Make sure you have the right certificate.***CALLSTACK:Errorat t._generateErrorStackForIE ( t ( t ( e.buildErrorWithVerboseLog ( e.buildLoadComponentError ( Anonymous function ( L ( T ( O ( g (

It is hard to decide from where to start, so I pick from the error detailes.

As per the error, learning site downloading the CDN assets from the url “Failed to load URL ‘” but encountering the certificate issue “There was a network problem. This may be a problem with a HTTPS certificate. Make sure you have the right certificate.“. I checked couple of things to make sure there is no issue.

Make sure there is no proxy blocking this download Also make sure no firewall blocking for the URL. As per Office 365 URLs and IP address ranges, I make sure the all the urls & ports are open. Check # 37 under SharePoint and OnDrive.

There is nothing, I find which can be causing this issue. So I move one step back. And checked for the Provisioning requirements.

Here are the pre-requisite for provisioning the learning site.

User provisioning the learning site should be a Global Tenant Admin. An app catalog must be provisioned and configured User who provisioning the pathways site should be Site collection of the App catalog site.

After closely checking the pre-requisite, I found that my account is global admin but not the site collection admin of the App Catalog. This is cause of the error as during the provisioning process, due to lack of permission, it failed to register the app in the app catalog. Error is kind of misleading.

To resolve the issue, I have perform the below steps:

Boom, after provisioning again, Site is working as expected:

Thank you guys for reading it, till next enjoying and keep SharePoint’ing.

Leave Request System


This presentation seeks to show how easily you can setup a leave or vacation request system in DFFS. This presentation assumes that you already have SharePoint and DFFS already installed in your environment.

The development is based on an On premises SharePoint 2016 setup however the same concept applies to SharePoint 2019 or O365


SharePoint 2016DFFSSharePoint Designer 2013

Note: The way I have developed this system is not the only way of achieving this task. DFFS is so flexible That it allows you to do this in many ways. I just chose one the ways.

Scope and Features.

This system will manage the leave requests and leave days of employees of any organization. The leave days will be stored in another list where user can track the number of leave/vacation days taken and leave/vacation days to be taken.

When the requests are made the leave days will go through approval processes based on the employee´s position. For example, in some organization a Manager´s leave request will only be approved by the Managing Director i.e. one level approval process.

However, in most cases the approval process is far more complex than that they are case where you have factory employees who report to different Supervisors who in turn report to the different Managers. In such a case the approval process has to go through all these different approval processes. This system will address that as well.

System Features.

Submission of Leave Requests.Submission of Justification Requests for absence (attachment of doctor’s report).

 The system will also have safety nets in that a requests can only be submitted if the request days do not exceed available days.

Now enough with the theory, let get into it!

We need to create two custom lists named Leave Requests and Employees requests.

After creating the custom lists please go ahead and create the columns necessary. For the leave request I have created the columns as shown below.

For choice fields I have shown the option configured in the print screen below.

Please note that the Days taken column is a calculated column. You have to be careful when calculating Start Days and End Days not to include weekends so for that we use the formula

Below. In The Column validation of the calculated Column.

=IF(AND((WEEKDAY([[End Date]];2))<(WEEKDAY([Start Date];2));((WEEKDAY([Start Date];2))-(WEEKDAY([End Date];2)))>1);(((DATEDIF([Start Date];[End Date];”D”)+1))-(FLOOR((DATEDIF([Start Date];[End Date];”D”)+1)/7;1)*2)-2);(((DATEDIF([Start Date];[End Date];”D”)+1))-(FLOOR((DATEDIF([Start Date];[End Date];”D”)+1)/7;1)*2)))

After creating the two custom list, we need to install DFFS on these list in order to create and customize our forms. Please follow the step below to customize to install DFFS.

First identity in Site Contents a folder written SPJS and open it.

After opening the DFFS folder on the target list please select the name of the list in which you want to customize your forms. In my case it is the Leave Request list.

After selecting the list proceed to install DFFS by clicking theinstall DFFS buttonfor all the formtypes i.e. New Form, Display form and Edit form.

When we reopen our form when can now see that its Enhanced with DFFS meaning the install was successful. And now we can start customizing our form.I will not go deep in customization as this is already covered in the DFFS Manual however I will add a little colour to make this form look pleasant.

To do a bit of customization we are going to do the below configs to help the form look a bit more pleasant. Customization is a whole big topic on its own and like I mentioned earlier we will not be getting in more detail.

Add the columns to the form as shown below

tabs configuration


After few configurations shown above our form is already looking this. We need to include the attachments on the form to help when submitting the Doctors reports when justifying for absence due to medical reasons.

As our requests will pass through different approval stages will need to create the approvals Tabs in the Edit form. In our case the approvals will be done by Supervisors, Managers and HR Department. As a rule of thumb you need to create SharePoint Groups for each TAB for example.The edit tabs will have the approvals columns which are Supervisor Approval,

Manager Approval and HR Approval.Normally, this will have a date field to show the date when the approval was made.In our example we did not include a date for simplicity sake.

When creating the Edit Tabs, we need to specify which groups will be able to visualize that TAB in the example below the group Supervisors Caixa will visualize the Approval TAB for the Supervisors.

This is a good security measure to make sure the Approvals are done by the intended people.

Please note that we are not going to be installing DFFS on the Employees custom list because this basically used to track Employees Leave Days. What will happen is that someone from the HR Department with edit permissions will update the leave days of the employees normally at the beginning of the year.

Please note the leave available column is a calculated column which use the formula below

To calculate the number of days.

=IF (AND ([Total Leave] <[Leave Taken];NOT(ISBLANK([Total Leave]));NOT(ISBLANK([Leave Taken])));””;IF(AND([Total Leave]>=[Leave Taken];NOT(ISBLANK([Total Leave]));NOT(ISBLANK([Leave Taken])));[Total Leave]-[Leave Taken];””))

Now that the basic customizations are done we will jump to SharePoint Designer(SPD) to continue with our configs.

When opening SPD we need to specify the site that hosts our custom list.

In SDP open your Leave Request list as shown below.

Give your workflow a name and make sure it is a 2013 Workflow as highlighted below. Please note will not go into details on how to make workflows in SPD.That’s a whole big subject which has books written on it. I will just show the Configuration that will make your leave request work.However, from the configuration we are going to be making here there is a lot to be learnt.

Again, the way I will configure my workflow is not the only way please feel to configure in a way that best suits your environment.Our requests will follow the fluxogram shown below.

We can add a stage by clicking the Stage Option on the ribbon tab of the SDP as shown below.

To simplify things, for each approval stage we will create a Stage in SPD except for Supervisor Approval because this will be part of the variables stage. First we will create A stage to store all of our variables.This stage will be called variables.

To set a variable click in the Set workflow variable on the actions ribbon as shown below.

the option to create variables

To set values we click on condition right on the ribbon and select the option If value equals value. To make logic in SPD we need to associate conditions and actions.

IF Department equals IT, Department and IT being lookup values from our Custom list through SPD.

To kick start the workflow we need to make sure that the ID field should have a value.

After clicking the option double click, it and give name to the variable in our case It going to VSupervisor and we are setting that to user mstest. Basically what we are saying it is.

If a request is made and the Department is IT, make the Supervisor to be mstest. In other words, we are telling the workflow to route all IT request to the IT Supervisor who is mstest.

Will the follow the same procedure to setup for Variable for Managers as well.This request has to be sent by email so we are going to prepare that as well. Normally for HR you can just forward the e-mail to a Group.These are usually the HR employees who deal with vacations

After setting your variables then configure the send e-mail option and to do that follow the steps.

After adding the e-mail option double click it and configure as follows.

Select the VSupervisor variable as shown below.

 As we configured the email we will need an edit form link. This the link which will be used for the approval. There are so many ways of getting this but I prefer to simply create a dummy request edit it and get the link from thereI my case I created the dummy request below

I will now edit it by clicking the 3 dots to obtain the edit link. Please make sure to copy the whole link we will need it later.

After getting the edit link paste it in the body of your e-mail.

Now we need to edit the edit link sorry for the pun so that it will be different on every request

If we do not edit it all the requests will come with one ID. To do so click on the 3 dots next to

Fx. Delete the ID number, in these case its 1, meaning request is number 1 on the list.

After deleting, the ID value lookup the ID field from the list. To do that click the add or change lookup value.

After the email is wait is sent to the Supervisor we need to put the wait function on this stage to do that the parallel block option in the ribbon. The whole idea here is we want the workflow to stop until the Supervisor approves the task. If we do not do that the workflow we just go through all the stages even if the conditions are not met. Basically the logic here will tell the workflow to stop until the Supervisor approves or rejects the request. This setup will be done also for the Manager and HR Stages.

After selecting the run in parallel block and 2 steps in that block by clicking the Step option in the ribbon.

In the first step we are going to configure the wait for approval option. First we need to create a variable for starting and ending our parallel block, it has to be a Boolean variable. In our case we will call it Supervisor Task Completed.

Right mouse click the parallel block and go to Advanced properties and then select the previouslycreated variable Supervisor Task Completed As shown by the prints below.

After completing your waiting steps configuration, it should look like below.

As I have already highlighted the waiting configuration should be done of for all the stages.

Our Basic Email Setup is done for the Supervisor.

For the Manager´s approval the setup is similar. The only difference is that the Manager should only receive the Leave Request if the Supervisor approves else an email of rejection is sent to

 to the requester. Your Manager Stage Setup should look like below.

And to reach HR the request will need the approval of the Supervisor and the Manager.

So the Setup should be like the on below.

After HR has approved a request the system should look into the Employees List and deduct the number of approved days from that Employees´ leave available days.

To do that I have included another stage for Calculation which will call Calculation Stage.

Basically we need to create Variables again for this, we need the store the Values from our employees list such as the Leave Taken & Leave available. So Basically our formula will be

 Leave taken + Days Requested =New Leave Taken then we update the in the Employees list and there since we the Leave available is a calculated field it will also be updated.

The result to the formula should not be negative because its means the Employee has requested leave days than has available. In a such we can put a condition that if that happens then the requested should be rejected.

Now that we have the idea he goes the configuration in SharePoint designer.

First let´s create a variable for our day taken. Please note when creating the variables at this Stage the type should be numbers since we are dealing with numbers.

It is important to note that the calculation should on be made if the reason for request is Annual leave to guarantee that we will put a condition that specifies it.

Please note when looking up the value for the Leave Taken valuable we need to change the Data source to the employees list.

To retrieve the Value, on the Field from Source field we should select the column Leave Taken because that’s where our field. The on the find list item we need matching values in both lists. In this we are matching by name.

After we retrieve these values the we need to do the calculation. In SharePoint Designer there is

an action called do calculation

When looking up for the fields we need for the calculation all we need to retrieve our previous

Set variables. Your formula should look like the print below.

After we have out NewLeaveTaken we need to updated the Employees list

Your setup should look like the print below.

After everything is done your Calculation Stage should like below.Please note the condition on annual leave.This to guarantee that the calculation can only be done when its a leave request.

Almost done, we just need to setup the rejection stage. Basically if the request is rejected on any of the stages then the request is rejected. And this is where the workflow ends.

Lastly we need to setup the Workflow to run automatically and to do that we click on Workflow settings

Now let’s test.

As you see the e-mail has been received by the supervisor.

After the Supervisor Approves yes the Request move to the Manager.

After the Managers Approval the Request goes to HR.

After the HR approves the request you the employees’ days are then updated in the Employees List automatically.

To make a justification request the user simply has to select the motive justification for absence in the motive column otherwise all the approvals stages are the same. The only difference is that when you make a justification for absence fase and after all the approvals you leave days’ balance will not be updated.

So this is basically a setup for a leave request System using DFFS enjoy.

NOW AVAILABLE: Mastering SharePoint Framework Continuous Monitoring Azure Application Insights Chapter Published

Today I published a new chapter to the Ultimate bundle of my Mastering the SharePoint Framework course. This new chapter, DevOps: Monitoring & Telemetry with Azure Application Insights, is immediately available to all existing Ultimate bundle subscribers!

This new chapter is nearly 2 hours long & brings the Ultimate course to 13+ hours of content across 80 lessons. The complete course is over 32 hours long across 246 lessons!

You’ll find the following lessons in this new chapter:

What is DevOps? What is Continuous Monitoring? Azure Application Insights SharePoint Framework & Continuous Monitoring Implement Azure Application Insights in SPFx Projects DEMO: Implement Continuous Monitoring of SPO Tenants DEMO: Implement Continuous Monitoring of SPFx components

One of the demos from this chapter shows how to create a SPFx component that you can install in your SPO tenant that will track every time someone in your organization selects one of the buttons in the Microsoft 365 suite bar. This way, you can get detailed analytics on how many users are opening the “waffle” menu, selecting the “help” icon or clicking on the “settings” button.

Screenshot Azure Application Insights tracking Microsoft 365 Suite Bar usage

This is one of two DevOps chapters in the Ultimate bundle. The other DevOps chapter was released two weeks ago: DevOps: CI/CD with GitHub Actions & Azure Pipelines. This milestone means there are just two more chapters to complete before the course is content complete. THe next chapter is about sharing code across SPFx project where I’ll show you how to use library components and NPM packages in your SPFx solutions.

30% off the Fundamentals bundle through May 2020

Throughout the month of May, I’ve been offering a 30% discount on the Fundamentals bundle. Use the code WeAreAllInThisTogether2020 when you checkout. Yes, that means this deal ends on Sunday night!

PRO TIP: If you’re interested in the Ultimate bundle, then get Fundamentals & select the “Yes! Mastering the SharePoint Framework – Upgrade to Ultimate” at checkout. The 30% discount will only apply to the Fundamentals bundle, but you’ll still save a bunch!

Giving back: 5% of all sales in May go to food banks

Not knowing where your next meal comes from or how you’ll manage isn’t something people should have to deal with right now in these trying times.

That’s why, for each subscription purchased, Voitanos is donating 5% of all May sales to our local North East Florida Foodbank.

So far we’ve been able to donate over 3,765 meals! If you prefer a donation to your local community when you purchase the course send me a link to your local food bank where you’d like us to apply your donation.

comments powered by

Everything you need to know about the new Microsoft Lists (so far)

At the time of writing this, we’re preparing for Day #3 of GlobalCon2 [Register to join here]. Day #1 was so informative and I can’t thank Microsoft enough for “trusting us” to deliver some of their amazing announcements.

One session in particular that resonated with me was around the new “Microsoft Lists” announcement from Lincoln DeMaris. 

(Note: If you prefer to watch the session then scroll to the bottom and watch it in full or here on YouTube).

In this post, I have taken Lincoln’s session and sliced it up into smaller videos so that you can scan this post to find the parts that most interest you. You can also see the entire session at the end.

What are Microsoft lists?

Microsoft Lists are a brand new app in Microsoft 365 that enable you to track information and organise work for your team. The goal with Lists is for them to be:

Simple. Start a list easily from scratch or with ready-to-use templates.Smart. User Teams to collaborate on lists, using flexible views like grids, cards and calendar.Flexible. Keep everyone in sync with smart alerts and conditional formatting.

You can think of a list as being like a database or a spreadsheet and with the ability customise your view of the data displayed.

In case you’re wondering, Microsoft Lists are nothing new. Lists are the natural evolution of SharePoint Lists. Everything new announced today will also be coming to lists within modern SharePoint sites.

There’s also a new dedicated Lists iOS app coming towards the end of the year.

Video: A quick tour of the new Microsoft Lists home

So let’s dive in : Watch the video to see the new Microsoft Lists Home. From this page you can see my ‘Recent lists’ and “Favorites’. 

Recent lists: This denotes the lists that you’ve accessed or created recently.Favorites: This is the lists that you want to access more often. To make a favorite, simply click the star icon on the list tile

Video: Create Lists in a variety of ways.

You can create new lists in a few different ways:

Create a blank listCreate a list from an Excel SpreadsheetCreate from an existing listCreate from a Template

When you create based on a new template, you can preview the data and columns. You can also choose colour, name, icon and a choose whether to save it personally (‘My Lists’) or with your Team.

The video below also shows how to pre-fill the columns and how quick it is to edit it.

Video: Say hello to a brand new image column!

This short demo illustrates the brand new image column allows you to attach an image (from your computer) directly to a SharePoint list. This is very different from the normal way of linking to an existing image. 

Video: How to set the default view to ‘quick edit’ in a Microsoft List

If you’d like your default view to ‘quick edit’ then this is now really simple to do. All you need to do is choose “save view as..”.

Quick Recap of the new Lists experience

From the slide below you can see that you can already create blank lists and lists based on existing lists. Coming this Summer, you are going to be able to create from Excel or a template. In addition you can can create personal lists or shared lists in team sites. 

There are also some big improvements coming to ‘Quick edit’ (I get the feeling that this will end up as flexible as Excel, eventually). There’s also some cool formatting improvements as well as big performance improvements.

Video: How to format list items in the new Microsoft Lists

Find out how to format columns using fills, colors, and images. You can also add conditional formatting based on rules that you can set. E.g. If you want to show a row as red if it’s ‘priority’ is high and ‘days old’ is greater than five.

How to display list items in a Microsoft List as Tiles (“Gallery view”)

If your list contains images that are the central focus of your data (such as in a car booking list) then you’d probably want to present that in a gallery view. This is all easily achievable with the new Microsoft Lists. What’s even cooler is that you can also edit the order and items that are displayed in the tile view. 

How to display data as a Calendar with a new Microsoft List

For lists that are focused around time (such as an event planning list). It’s not possible to create a calendar view on any list in SharePoint. This will allow you to visualize your data by day, week, month, and add/edit the items by simply clicking on them. 

How to completely customise a List form in the new Microsoft lists

With new Microsoft Lists, you can show/hide form items and re-order them at the click of a button. You can also conditionally show/hide a form item based on data from other items then this is now also very easy to achieve. For example, if you’d like to hide a “Notes” field if the “Event Capacity” is greater than 500.

Additionally, you can now edit the entire layout of the form including the header and footer. This experience is more for a power user because it requires a working knowledge of JSON to achieve the required formatting.

Views and Formatting Recap

Views and formatting are getting some serious lovin’. We’re going to see a new way to create views along with new Calendar views and Gallery views. Post-summer we may even see a Kanban view, which sets up a potential decision point with Microsoft Planner 🙂

Video: Want to collaborate (comment on share) on a list?

If you want to share a list with other people then this is all possible. You can also share individual list items in the same way that you can in OneDrive. All of the standard sharing options are available. Microsoft is also adding the ability to chat/comment on a list item. It will be interesting to see how that works when the list is surfaced from within Microsoft Teams. You will also be able to @ Mention people from the comment stream.

Video: How to configure rules in the new Microsoft Lists

You can now create rules that will take action when something happens inside of the Microsoft List. A perfect example is to send an email to a person if the field is set to a certain value.

Recap: Sharing, Collaboration, and Commenting

I personally like the commenting features coming to Lists as i can see so many uses for it. Here’s the recap shared by Lincoln.

The new List experience is here to serve a wide range of use cases, ranging from simple to complex. For the none Power User, they are there to model a very simple business process. For the more advanced Power User, then they can be used to be the data repository for complicated line of business process with with the Power Platform talking to the lists.

Microsoft Teams is fast becoming the central hub for all collaboration, so it’s essential that other Microsoft apps integrate seamlessly with it. Lists are no exception. Microsoft are committed to making sure that the Lists + Teams experience is first class. Lists will be surfaced as a Tab and conversations is set to be more closely integrated.

Later this year, Lists will be available on a new the Lists iOS app. Microsoft are planning to allow you to manage, create,  customise and manage alerts all from the mobile app. 

Full Video: watch the entire GlobalCon2 Microsoft Lists demo in full.

If you’ve time, we strongly recommend you watch the entire session presented by Lincoln at Microsoft.

Learn More about Lists? Visit the official Microsoft site.

Branding the Modern UI in SharePoint Online – Part 3

Welcome to the third post about options for branding modern SharePoint Online pages and sites. Before reading this new blog post, please read the first two posts in this series before you read this one:

Part 1: 2:

Great, now in this post I’ll show you how to work with and apply your custom branding in a Modern site, with a little help of an SharePoint Framework (SPFx) Web Part. Let’s say you need to override some of SharePoint Out Of The Box CSS in just one page, then it can be handy to apply a web part onto the page with a portion of your CSS overrides. This technique is similar to what you could do in SharePoint classic sites with help of the Content Editor Web Part or the Script Editor Web part.



As you can see onto the image above, I’ve only done a few minimal changes on the page, replaced the standard font for all web part headers in this page, and I’ve also replaced the site title to a font named Ubuntu. This font is free to use as a custom web font (ttf), and you can find it at Google Font library.

Ok, this can sure be a way forward when your client has a strict guideline for branding that requires custom fonts or colors, matching the graphical profile, and you need to create a branding for SharePoint and not be so limited by what’s possible to do with a theme. By a web part, you can only affect the page where you add this web part. If you want to add some CSS overrides globally onto all modern sites, then you need to do it with help of an application customizer (SPFx Extension).

Last thing, don’t forget that Microsoft is constantly adding new features to SharePoint Online and also updates the DOM. The overrides and customizations you make with adding and injecting custom CSS may just stop working one day, not so dramatic perhaps but it’s important to know this and have a plan for this. You can read more about that in my previous post.

The idea is to add a CSS file in the Web Part and reference this into public render, with help of require.

Another thing that maybe could be useful here, is to hide the web part it self if the page is saved or published, and only display the web part if the state of the page is in edit mode. This could be done with help of a portions of JavaScript and to import the function called DisplayMode from SP core library. Maybe I’ll do a blog post about that later on.. Let’s see. Anyway, feel free to download my web part from here and test this out!

Stay in tune for the next post of this series, see you!


The easiest way to store user settings of your Microsoft 365 app

When building a Microsoft 365 app, you might want to store user settings. Here’s the easiest way to do it.

Microsoft 365 applications

With more and more organizations being in the cloud, building Microsoft 365 apps is a perfect opportunity to extend the standard capabilities to organization’s needs and make better use of the available technologies. Microsoft 365 is a rich platform that offers you a lot of flexibility for the apps you want to build. You can make fully-fledged line of business applications, hosted on Microsoft Azure and using some of the AI services available on the Microsoft cloud. There are also scenarios, for which a single-page application without a backend can offer added value as well. By tying the different resources available on Microsoft 365 and putting them in a business context, you can help your organization be more productive.

Configurable application

We all work differently. Applications that are most widely adopted take that into account and let us store our preferences. If the application that you’re building, has some kind of backend, you will likely store the settings there. But what if Microsoft 365 is your backend? Where would you store user settings then?

Storing user settings the SharePoint way

If you’re used to working with SharePoint, your first choice to store user settings could be using the user profile service. Each SharePoint user has an individual profile with a number of properties, such as name, email, office, etc. Often, developers would create a custom user profile property and store the serialized configuration data in there.

While the approach is working, it has one limitation. It’s not possible to script creating new user profile properties, so as a part of your application deployment, you need to include a manual step of adding the new profile property.

Another challenge with using the user profile service is that it’s not exposed via a REST API. So if you use anything else than than SharePoint Client-Side Object Model (CSOM) you would need to manually construct SOAP calls to store and retrieve the data. PnPjs addresses this limitation by offering you a fluent API but still you will need to create the custom property in the first place.

Configuration lists

An alternative approach to store user settings is by using a SharePoint list. On its first use, your application would create a hidden list, where the settings for the different users will be stored.

While creating the list can be fully scripted, each time your application wants to read or write settings, it first needs to check if the list exists and create it if it doesn’t. This adds extra complexity and can introduce a noticeable delay. Also, if you choose to store the different settings in columns, you might need to transform the previously stored settings should your configuration model change.

There is however another way to store user settings, which is way easier than using the user profile or SharePoint lists.

Store user configuration in the application’s personal folder

One of the hidden gems of Microsoft Graph is the application’s personal folder. It’s a special folder in user’s OneDrive for Business that’s automatically created whenever application reads or writes data to it. Each application gets its own folder in which it can store any number of files and folders.

Store data in the application’s personal folder

To store data in the application’s personal folder, execute the following request:

PUT content-type: text/plain authorization: Bearer abc {“key”: “value”}

If you’re using the Microsoft Graph SDK, the request looks like follows:

const settings = { key: value }; this.graphClient .api(/me/drive/special/approot:/settings.json:/content) .header(content-type, text/plain) .put(JSON.stringify(settings));

In the API URL, approot points to your application’s personal folder and will be automatically resolved by Microsoft Graph to[email protected]/Documents/Apps/<your AAD app name>. settings.json is an arbitrary name of your configuration file. The body of the request, is the serialized representation of your configuration object. In this example it’s JSON but it could be anything that you can write to a file.

Retrieve data from the application’s personal folder

How you retrieve the data from a configuration file stored in the application’s folder, depends on the type of your application.

If your application calls Microsoft Graph from server-side code, you can get the contents of your configuration file by executing the following request:

GET authorization: Bearer abc

If your application communicates with Microsoft Graph client-side, as it’s the case for SharePoint Framework solutions or single-page applications, you need to use the following two requests instead:

GET[email protected] authorization: Bearer abc

followed by:

GET <url from the response[‘@microsoft.graph.downloadUrl’] property>

The reason you need two different approaches is, that calling returns a 302 redirect to a pre-authenticated URL on the domain. Because this URL is on a different domain, your browser will try to comply with CORS and call the URL with the OPTIONS method, which will fail. So to avoid it, you need to avoid the automatic redirect by retrieving the target URL and calling it yourself.

If you use the Microsoft Graph SDK, you would use the following setup:

const defaultSettings = { key: value }; this.graphClient .api([email protected]) .get() .then((response: { @microsoft.graph.downloadUrl: string }): Promise<HttpClientResponse> => { return this.httpClient .get(response[@microsoft.graph.downloadUrl], HttpClient.configurations.v1); }) .then((response: HttpClientResponse): Promise<string> => { if (response.ok) { return response.text(); } return Promise.reject(response.statusText); }) .then((settingsString: string): Promise<ISettings> => { try { const settings: ISettings = JSON.parse(settingsString); return Promise.resolve(settings); } catch (e) { return Promise.resolve(defaultSettings); } }, _ => Promise.resolve(defaultSettings));

In this example, httpClient is an instance of the regular HttpClient exposed by the SharePoint Framework. If you build a single-page application, you can replace it by fetch.get or its equivalent capable of issuing an anonymous web request.


Application’s personal folder is created per Azure AD application. So if you want to use it in context of a SharePoint Framework solution, your application will store its data in the SharePoint Online Client Extensibility Web Application Principal folder. To avoid colliding with other applications’ settings, you should store your files in a sub-folder.

To be able to read and write files in the application’s personal folder, your application needs to have the Microsoft Graph Files.ReadWrite permission granted.

For more information about working with the application’s personal folder see the Microsoft Graph docs.

Photo by James Coleman on Unsplash

Video Studio 3.0

It was 2017 when I last shared about the video studio and the configuration. Since then, we’ve made some important upgrades, like retiring the two Canon XH A1s in favor of a Blackmagic Pocket Cinema 6K. We also added two teleprompters (Glide Gear and Magicue), a jib, and a few other pieces to pull it together. Let’s take a step back and talk about the problem.

The Limitations

Most of the time, we’re shooting video for the internet, and that means a final resolution of 1280×720. The limitation of the Canon XH A1s – 1440×1080 wasn’t a problem. However, some of the more recent stuff has been going to a final resolution of 1920×1080 – so the Canons weren’t going to cut it. We have the Nikon D750, but it has a 10 minute recording limit.

We also recognized that even though we had managed most of the angular deflection of our eyes while recording, it was becoming more apparent that we weren’t looking at the lens of the camera when we were recording – we were looking right below it.

Finally, we didn’t have a good way to get overhead shots. For some of the infection prevention videos that we were shooting for Terri, we needed a way to show people multiple angles of handwashing and hand rub.

The Camera

There are a lot of factors that go into picking a digital video camera. For us, it needed to work primarily as a studio camera and secondarily as a camera that we could travel with. Blackmagic Design was a reasonable choice if for no other reason than we’ve had the ATEM and liked it. We landed on the Pocket Cinema 6K for two key reasons. First, it would use standard Canon EF lenses, giving us some flexibility. Second, it would allow us to do cropped frame to 4K for the foreseeable future.

The Good

There’s a lot of great things about the camera. We married the camera with a Tamron 28-300mm lens, which is great. The images are clear, and the minimum F/3.5 isn’t a problem in the studio, where we’ve got plenty of light. The screen is good. The menus are intuitive. The recorded video is very clean. The adapter cord allows us to attach the Rode NTG-1.

We ended up adding a SmallRig cage to it to provide mount points and protect it. We decided to add a top carry handle and we grabbed a few Magic Arms – double-headed threaded articulation. Overall, we’re very happy with the camera, but it didn’t come without a few issues.

I had some trouble with the CFast card I bought to record on. Ultimately, I decided to transition towards recording to portable storage drives. The onboard USB-C port allows for SSDs (solid state drives) to be attached through an adapter or enclosure. I could then slide in a pair of 1TB SSDs – one at a time. They record great, and a simple USB3 adapter cable allows me to pull the data off them and on to the editing bay at about 300MBps, or roughly 2.5x the recording rate. From a workflow perspective, this means that I can be offloading recorded information at the same time that we’re recording more. Given that 1TB is about 4 hours of recording at the settings we use – 4K ProRes – we can basically swap drives during the middle of a day of recording.

The Bad

Perhaps the biggest disappointment was the problems with the USB-C port that’s on the camera. It was supposed to be that you could power the camera with USB-C, but it wouldn’t charge the camera. However, the language of marketing copy kept shifting, as I was digging into the problems I had with why my USB-C power pack wasn’t able to keep the camera powered. The camera would turn itself off after about 40 minutes. Ultimately, I got the answer that it wouldn’t work that way. If you must, you can charge the onboard battery with the USB-C – when the camera is powered off.

I ended up getting a V Mount/V-Lock battery plate with a D-Tap, a D-Tap cable that would connect to the camera, and an adapter between Sony F970 batteries and V Mount. That all required a cheese plate to allow for mounting. Assembled, it’s good. Finding all the pieces wasn’t easy.

I settled on this approach, because I hate having to carry around so many kinds of batteries. When I got the light panels, I got a Watson Duo LCD Charger, which charges the F970 batteries they take. With this solution, I’ve got one set of batteries that the light panels or the camera can use. The charger also means I can recharge the batteries from a wall or any 12-volt lighter socket.

I have no idea how long the camera will run on battery power in this configuration – but it’s a very long time.

The Teleprompters

I knew that I wanted a teleprompter and was trying to get one without spending an arm and a leg, that led me to the Glide Gear TMP100. It was designed for a tablet, but I expected I could use a 10″ monitor. The key consideration for me was that it be full resolution HD. What I didn’t account for was that the monitor was substantially thicker than what the rig was designed for. It required some modifications to get things to work out, and even then, it wasn’t quite right. Ultimately, that led us to a 19″ teleprompter from Draco called Magicue. It’s much bigger and better in many ways – and of course, more expensive.

For both, I needed to address the problem of the mirror flip. Most people do special software to do this, but for our workflow, having the ability to use Microsoft Word or Microsoft PowerPoint was important. We produce video every week, and we have guests renting the studio. It had to be easy. That required a Decimator MD-Cross to flip the signal. It’s like the Decimator MD-HX that we use to frame up signals for the Blackmagic ATEM – except that it supports flipping.

The other thing that I needed for both was a Z-Tilt Tripod Head/Mount. In the teleprompters, getting the camera positioned right is critical. Trying to do that on a micro-ball head just wasn’t stable or easy enough. Since you don’t need side to side, the Z-Tilt is perfect.

Glide Gear

In addition to the issue mentioned above with mounting the monitor, the hood on the Glide Gear was a problem. It wouldn’t seal around the edges of the lens. That’s important both for recording quality, but also because, if you don’t seal it, you get light pollution through the back of the glass, and you can’t read the teleprompter.

Because of the dimensions, it also necessitated a fixed 28mm lens for the Blackmagic to get the right angle and get close enough to the glass to not see the frame. The lens isn’t much crisper than the Tamron 28-300mm – but it’s lighter and much shorter.

Ultimately, we put the Sony DHR-11 on it, since it’s a compact camera and works well on a mini-ball head, and its zoom makes it possible to control what the camera sees (and doesn’t see) through the teleprompter.

We’re set up for this as a backup teleprompter, but it’s dwarfed by the Magicue 19″.


Not withstanding the issues with the Glide Gear itself, the problem was that it’s small. The farther away you place the camera the less well you can read text. So, the problem is simply one of being able to read. The Magicue solves that problem. It’s also a more adaptable solution. You can adjust the tilt of the mirror – where it was fixed with the Glide Gear. It sounds like a small thing, but in this case, it counts. When you’re trying to get as wide a shot as possible, it’s sometimes necessary to tilt the monitor down just a bit rather than being horizontal – so it’s not seen by the camera.

The hood for over the camera is great. It seals around the lens well, and it doesn’t fall into the field of view as the Glide Gear’s shield tended to do. It even feels sturdier. Of course, you’d expect that with the greater cost – but it’s really nice.

The one hitch to the Magicue is the monitor – and, in truth, it’s an inexcusable limitation. The unit ships with a monitor that is 19″ diagonally but on a 4:3 format. On the surface, it looks good. Integrated signal flipping, SDI, HDMI, and VGA support. The detailed problem is the 1280×1024 resolution.

The challenge with a monitor for a teleprompter is that it needs to be bright, so that means just any monitor may not do. Because the image is reflected and some of the light is lost, it needs to be brighter than you’d normally need a screen to be. More importantly, you need it to be the right size. It needs to be about 19.5″ diagonally on a 16:9 format, because that format allows the width to stay inside the reflected area of the mirror. On the brightness side, it’s hard. The monitor they provide is 300cd/m2, which is moderately bright. Most monitors available off the shelf are 250 cd/m2 at best – and few places are selling 19.5″ in the consumer market these days. I did manage to find a ViewSonic VA2055SM that works fairly well, though I’ve got to turn the brightness all the way up.

There are other options that even get to 1000 cd/m2, but they’re specialty and command the specialty price tag. For now, I’ve decided that the monitor is OK. If I need to do something different in the future, I can.

Get Jibby with It

There are just some shots that are difficult to get without the right gear. The overhead shot is one of those. We wanted the overhead shot for the infection prevention demonstration videos, but also because I thought we were going to use them for the change management course we started building. Though we decided against using it for the change management course, it’s become an important part of how we can shoot demonstration video.

A jib is fundamentally a long arm that you mount a camera on the end of. In our case, the PROAIM Astra is an 8 foot jib that allows us to get a camera overhead. We elected to put the Nikon D750 on it, so we could shoot front with the Blackmagic and overhead at the same time. This created a handful of problems. First, the D750 has a camera door that ejects via the bottom, which isn’t convenient to change. We had purchased a vertical grip for it that it’s much easier to add/remove the battery, so we used it. The other problem was that the Jib is set to keep the platform vertical, so we had to get a 90-degree downward turn – and a micro ball head wasn’t going to cut it. We turned to a full tripod head that has great control for locking things off.

We had one last problem. The primary lens we use on the Nikon D750 is a Nikkor 28-300mm f/3.5 that’s great for all around shooting but also extremely heavy. Facing downward, we can lock out the zoom and stay at 28mm or let it zoom all the way in and end up at 300mm. Neither really works from 4 feet above your head (to stay out of the way of the Blackmagic camera.) That why we picked up a Nikkor 50mm f/1.8 lens. It’s a beautiful lens and has a reasonable zoom. We’d love to add a Nikkor 85mm f/1.8 lens to the studio, because it might be a tighter and better shot for some things, but it’s definitely a nice-to-have, not a must-have, for us.

The only real challenge for the jib is managing the counterweights. It’s sometimes interesting to get the camera on one end and get weights on the other to counterbalance. I had some 6lb mic boom counterweights that I had available, so I threw them into small bags and hung them on the post that is designed for regular bar weights. It’s not perfect, but it works.

The other thing for the overhead shot was to add a black rug, since our existing rug was a bit too distracting.


There were other things we rearranged, most notably the tower that used to hold the two cameras. It’s rather bare now, as we’ve removed two camera preview TVs and one switcher preview monitor, and have left the stand with little more than one preview monitor for the ATEM. There’s more gear on the floor now on various light stands and tripods, but we’re in a much more flexible position to be able to capture content in ways that make it seem seamless.

As you can tell, we’re in a much better place, not perfect still, but we’ve got a better picture, and we’ve got more flexibility to get the shots we want.


Most Popular Today

10 Best Apps for Working Remotely From Ltc Home

With remote working sharply on the rise (50% of the entire UK workforce is expected to work remotely at some capacity by 2020), more...