Thursday, 29 June 2017

Office 365 developer wish list (SPFx and modern sites), summer 2017

Clearly we’re in a transitional period in Office 365 at the time of writing (June 2017), where modern SharePoint experiences are available - modern sites and pages for example - but not everything is fully joined-up yet. That said, it’s a fast-moving landscape and part of the consultant’s role is to keep up with the best way to deliver solutions. For once, I hope this is a blog post which dates very quickly – certainly I have had to add bits of info as I’ve been writing it, and I’ll come back again and update the table below as things get announced/released.

Going back to that ‘transitional period’ - this is especially the case for organizations with collaboration workloads, where there’s a need to create some kind of site template for team sites. This is still very common for our clients, even if it’s just a need to provide a different home page experience or add some lists/libraries/content types/global admins to the site. After all, I think that *whatever* Microsoft provide as the default experience, many orgs benefit from some lightweight changes to this – and so site templating continues to be important in SharePoint. I hope Microsoft don’t lose sight of this. Certainly when I consider my wish list, many items relate to “doing team sites at scale” in SharePoint – so perhaps let’s think about that first.

Current site templating challenges

Currently site templating is challenging because:

  • Want to use Group sites? Well, it’s challenging to template these currently, because:
    • Can’t currently specify a custom template
    • Can’t currently be notified that a new site has been created, because there are no web hooks
      • [By the way, I agree there are  ways around this (e.g. web job/function which polls for new sites), but none are pretty because users may start using the site in one state, only for it to change as they are working in it..]
  • Want to use non-Group SharePoint sites? Currently challenging to template these *and get modern experiences*, because:
    • Even the Patterns and Practices (PnP) site templating doesn’t currently allow provisioning of modern pages – at least, not without some dev effort to extend it

For our clients who don’t want to use Groups, that 2nd approach is becoming common for us. But it would be nice if it was more baked-in/required less work. It’s coming I know (see info in my table below), but there’s no harm in nudging people along the way ;)

My current wish list

Here’s an extract from a PowerPoint slide I recently to discuss my current list of “asks” to Microsoft:

SPFx and modern pages wishlist - June 2017

Let me expand on those in a bit more detail:


Status (June 2017)


Global deployment of SPFx web parts

  • Needed so that SPFx app does not need to be installed to each site
  • Ideally at different scopes e.g:
    • All sites of a certain type e.g. all group sites, all regular team sites etc.
    • Sites with X in property bag
    • All site collections except [list]
    • etc.

Partial solution “imminent” (weeks not months)

See slide at the end of this article. Initial solution will allow web parts to be available across sites, but without much control (e.g. my “scopes” examples).

Expand PnP schema to include provisioning modern pages and web parts

  • Needed to allow provisioning of team sites *with modern page as home page* – without code/PnP extensibility provider)

Expected in next release of PnP Core (August 2017 release). It’s in the XML schema already...

More web hooks

No news

I’d like to see web hooks for:

  • Site creation e.g. group sites
  • Subsite creation
  • List creation
  • Permission changes
  • Other changes

Remove restrictions on “no script” sites (esp. property bag)

  • Needed to bring more extensibility to Group sites (or other sites with “no script” enabled
  • Writing to property bag is common in many customization scenarios


It’s now possible to disable “no script” on modern team sites, including Group sites. The Customizing modern team sites page has been updated to reflect this (June 26 2017)

Missing controls and tagging support

  • Taxonomy control
  • Person/Group control
  • Calendar control (for non-Group sites)
  • Full Content Search web part (or similar)

No specific news

Modern pages in team sites are great for editing and display, but currently not so good when it comes to some types of content and tagging. Missing controls include the ones I’ve listed (difficult to have a “Page contact” or “Site owner” for example), but the tagging/metadata support is lacking too due to the (lack of) fields on the Site Page content type. Rolling up these pages with a filter is tricky in the current arrangement.


  • Multi-column support
  • Fix banner/header height

Coming “soon”

More known issues with flexibility of these pages – the single column aspect in particular. But, this is relatively low-hanging fruit for Microsoft and we can expect these resolved soon I think.

Expand SPFx extensions model (bonus item)

No specific news

Additional areas to target, not just “PageHeader” and “PageFooter”. The product group have said more areas are coming for modern pages in team sites (and presumably communication sites too).

    In terms of the first item, global deployment of SPFx web parts, Vesa recently used this slide to discuss what’s coming:


      That sounds like a reasonable plan, since at least the long-term solution would give us full control. The short-term solution would clearly mean that all SPFx web parts are available everywhere (e.g. in my team sites, my intranet and my communication sites) which might not make sense, so hopefully the long-term arrangement isn’t too far away.

      Communication sites

      Communication sites are starting to launch and Microsoft’s “Ask Me Anything” session was yesterday (28 June 2017). I was disappointed not to hear any detail about templating of communication sites, so that would certainly be another wish list item. I know there are “new” templating options for those coming, but I still want the ability to use PnP site provisioning and XML too – after all, we still need the control and ability to specify all the aspects of a site template that PnP provides, so why use another approach? Also, having a mismatch between what I’m doing everywhere else and for comms sites would be sub-optimal too. Hopefully PnP provisioning will be possible there too – I really hope so!

      What else?

      I could certainly think of a few more items. But what did I miss that’s on your list at the moment?

        Sunday, 11 June 2017

        Use an SPFx Application Customizer to add JavaScript (e.g. header) to every page in a site

        New tools for customizing modern SharePoint sites and pages in Office 365 have arrived (in preview at the time of writing, June 2017).  These are known as “SharePoint Framework (SPFx) extensions”, and replace some tools that SharePoint developers have long used to deliver key scenarios such as:

        • Adding JavaScript to every page in a site/web
        • Injecting some content (e.g. a mega-menu/global navigation or message bar) into every page
        • Popping up dialog boxes in an integrated way
        • Adding items into certain toolbars/menus in SharePoint
        • Changing the rendering/behavior of a specific field in a list

        In other words, SPFx extensions provide the equivalent of CustomActions and JSLink – previous dev approaches which didn’t necessarily translate to modern pages.

        In this article I want to focus on the first two scenarios listed above (in bold) – referencing some JS on every page, and also running some code to put something in the header area of the page. The documentation provided by Microsoft does a good job on the 2nd scenario, but sometimes it’s good to have something a bit more visual so I’ll provide more screenshots. I’ll also talk about the scenario where you don’t necessarily want to add some *content* to the page, but you do want to add *some other form of script* to run on every page (e.g. analytics/whatever).

        In terms of injecting content into the page, we now have the following zones in modern pages:

        • PageHeader
        • PageFooter
        • DialogContainer

        N.B. We can expect more zones in the future! Here’s what the header and footer look like:


        Key information

        Microsoft are currently saying that SPFx extensions will hit General Availability (i.e. fully-released in all tenants and suitable for production use) in fall/autumn of 2017. Until this time they are in preview.

        Also be aware that what makes the new extensions possible is Microsoft's updates to tenants (only in developer tenants at the time of writing, not even in First Release), and updates to the Yeoman Generator that developers use to get started - this has a new set of component types which get you started with the right default code.

        Previous limitations with modern pages

        Modern pages have been frustrating because:

        • No possibility to run custom script
          • Global JS added with previous methods (CustomAction + JSLink) did not run here – only on “classic” pages
        • Corresponding lack of page extensibility
          • No way to inject content into the page

        What’s changing here is that Microsoft are providing a hook to run your code, and are also providing named placeholders on modern pages – zones of the page which you can add content to. So long as you stick to these zones and don’t arbitrarily “hack” the page by changing other DOM elements (e.g. with jQuery or similar), then Microsoft effectively guarantee that updates to Office 365 will not impact your customizations.

        The script you provide has to be installed to an app catalog and deployed that way, meaning that there is effectively an approval step. This means that simply editing the page to add a Script Editor web part no longer exists as the easy option – the script must be OK’d by an administrator. Lots of debate on this one of course, but ultimately it’s what Microsoft need to do to facilitate more governance and safeguard Office 365 as a stable platform.

        Targeting placeholders such as the PageHeader and PageFooter zones

        The earlier image showed where the PageHeader and PageFooter zones are. As shown above, these zones are present on “system” pages such as a list/library page, but note that some modern pages such as a regular Site Page (in a standard site or a Group site) don’t get all placeholders. For example, there is no footer here:



        And there’s nothing to stop you making that header zone larger if you want to with CSS (this image is zoomed out):


        And of course, all this only applies to modern pages – classic pages do not have these zones or support SPFx extensions in general:


        I’ll talk about the end-to-end process later, but to get straight to the code - with some minor tweaks/simplification to the suggested code in the documentation, mine looks like this:

        And the CSS is implemented by adding an SCSS file in your extension’s directory – mine is named AppCustomizer.module.scss and has the following content:

        Remember this is imported to the class for your customizer e.g:

        import styles from './AppCustomizer.module.scss';

        So, the key elements here are:

        • A class that derives from the ApplicationBaseCustomizer class
        • Use of the this.context.placeholders collection to get a reference to the appropriate placeholder - and the fact that it gives you the DOM element to manipulate (e.g. set innerHTML)

        In terms of what associates your customizer to the site, this is done declaratively in the app packaging – your customizer has a manifest file which contains it’s ID ([MyCustomizer].manifest.json), and on top of this you actually add an elements.xml file with a CustomAction element (just like the old days!). This has a new "’ClientSideComponentId” attribute, and this must point to the ID of your customizer. But before then, there’s a mode when you can dev/test your customizer before worrying about packaging. This works by running a “gulp serve” locally and adding some querystring parameters to a modern page so that the manifest is loaded from localhost – it’s a bit like the “local SPFx workbench” equivalent but for SPFx extensions/customizers.

        But I don’t need placeholders – I just want to reference some JavaScript on every page!

        In this case, the code is somewhat simpler. If you have an external JS file you want to reference in a quick and dirty way, you could do this by dynamically adding a script tag to the <head> element of the page. My testing shows it seems safe to do this in the onInit method, but the onRender method would be fine also – in any case, it’s just the old-fashioned method like this:

        But consider!

        • If the JS is hosted on another domain, you may need to enable CORS there (depending on what your JS is doing)
        • If you're referencing a module script, you could do this in a cleaner way by referencing it as an external module in the "externals" section of your config.json file (see Add an external library to your SharePoint client-side web part for more). I've tested and this approach does work with an Application Customizer
        • You could also choose to bundle your script if that made sense, and ensure it was referenced in the onRender method for your customizer. That should work too..


        The process is effectively the same whether you're targeting page placeholders or just referencing script on every page:

        Update the SPFx Yeoman Generator if needed

        The first step you might need to do is to update your SPFx Yeoman Generator – assuming you already have all the bits installed, you can do this by typing “yo” at the command-line and then going through the update process:


        Choose the “Update your generators” option and select “@microsoft/sharepoint”:



        Creating an Application Customizer extension

        [N.B. I’m essentially duplicating/walking through the main “Build your first extension” documentation here – you should reference that too.]

        Once you’re ready to actually create your app customizer, do this by running that generator:


        Give your solution a name, and ensure you select the “Extension” option:


        In this case, we’re using Application Customizer (rather than ListView Command Set Customizer [CustomAction/toolbar replacement] or Field Customizer [JSLink/field replacement]):


        Provide a name for your customizer and then a description:


        The generator will then get busy creating your application with the appropriate files, and then you’ll see:


        Your application has now been created and you’ll get the boilerplate code:


        It’s a good idea to test running this in debug mode before making any code changes, so do this by running a gulp serve with the “nobrowser” switch:


        The next step is to browse to a modern page, but adding some querystring parameters in the URL so that our *local* manifest for the customizer is loaded. First, open a browser to a modern page – a document library is a good choice:


        And then in Notepad or similar, build the querystring parameters you need. This basic format of this is:

        customActions={"badba93c-7f98-4a68-b5ed-c87ea51a3145":{"location":"ClientSideExtension.ApplicationCustomizer","properties":{"testMessage":"Hello as property!"}}}

        However, you’ll need to replace the ID with the one from your customizer’s manifest file:



        If you paste that onto the end of the URL to the document library in your browser window and hit enter, you should see a warning message related to debug mode:


        Click the “Load debug scripts” button, and then your code should execute and you should see the results – in the case of the boilerplate code, it’s an alert box:


        Success! You’ve now run an Application Customizer in debug mode.

        Packaging for production

        For this, I recommend following the steps in the documentation (start at Deploy your extension to SharePoint) – but below is an extract of the main steps. Ultimately it revolves around:

        1. Building your app, and deploying the bundled JS files to somewhere like a CDN (just like an SPFx web part)
        2. Adding some packaging files to your app, so that your customizer is called when the app is added to a site (a bit like feature activation – in fact, it IS feature activation ;))
        3. Deploying the app package to an App Catalog, and then adding the app to a site

        In terms of the process, key steps are:

        • Create SharePoint/Assets folder and add an elements.xml file:

        • Add the contents to elements.xml – set the “ClientSideComponentId” to identifier of your customizer i.e. the one found in the [MyCustomizer].manifest.json file:

          <?xml version="1.0" encoding="utf-8"?>
          <Elements xmlns="">
                  Title="COB Global JS"

        • Edit the config\package-solution.json file – add a “Features” node to reference your elements.xml file. It needs contents similar to the following:

            "features": [{
                "title": "COB AppCustomizer - global JS",
                "description": "Adds some JavaScript to every page in the site",
                "id": "456da147-ced2-3036-b564-8dad5c1c2e34",
                "version": "",
                "assets": {        
                  "elementManifests": [
        • Take care of some other steps related to CDN-hosting of your JS bundle (e.g. updating the ‘cdnBasePath’ property in the ‘write-manifests.json’ file), and then bundle and package your app using 'gulp bundle --ship' and 'gulp package-solution --ship' respectively.
        • As I say, head to the documentation for the full steps when you actually come to do this.

          The app is then upload to the app catalog:


          Notice that at this point, the admin needs to trust the application and will see where the remote files are hosted - in my case, I used the Office 365 public CDN:


          You should then see your customizer take effect, and if you go looking you’ll see a web-scoped feauture (by default) which is binding your customizer to the site:


        Other matters

        • Feature scope – it should be possible to adjust the feature scope from the default of “web” to “site”. I haven’t tried this yet, but expect it to be in the “features” node of package-solution.json
        • Property bag – as shown in the “Build your first extension” page, there’s a property bag of sorts that can be used with customizers. In production mode, properties are specified in the CustomAction element in your elements.xml file. In my example, I chose to use values specified directly in the code, but this property bag provides some level of separation (but it is still burnt into your package)

        Happy customizing!

        Friday, 12 May 2017

        Calling an Azure Function from a SharePoint Framework web part (SPFx) – part 2: calling from SPFx and passing data

        In the previous post we looked at the work to get started with an Azure Function which can be called from an SPFx web part, and can use the PnP core library. Having got our Function set up with CORS, NuGet support for PnP, and deployment from source control we’re now ready to finalise the code. As a recap, I’m splitting the steps and code into these two articles:

        Part 1 – setup, use of PnP Core, CORS and continuous deployment (previous article):
        • Initial creation of Function
        • Deployment of function code (using Continuous Deployment from GitHub)
        • Allowing CORS on an Azure Function so that it can be called from JavaScript (including a special entry for the SPFx workbench)
        • Use of SharePoint PnP Core library - via Azure Functions NuGet support
        • Use of App Settings (environment variables) in an Azure Function
        Part 2 – calling from SPFx and passing data (this article):
        • Code for the Azure Function side (i.e. the work to create a modern page from some passed parameters)
        • Code for the SPFx side
        • Passing data to the function and adding correct headers
        • Returning data from the function, and displaying success/failure in our SPFx web part

        The code – Azure Function side

        I’ll talk about a couple of notable things first, and then show the full code.

        Collecting data passed from client

        We’re going to assume the caller is going to POST data to the function as JSON in the request body – the boilerplate function code does this too, so we’re just extending things a little. We can then access the pieces of data through the Content.ReadAsync() method using a C# dynamic variable and plain object type:

        // collect site/page details from request body.. 
          dynamic data = await req.Content.ReadAsAsync<object>(); 
          string siteUrl = data.SiteUrl; 
          string pageName = data.PageName; 
          string pageText = data.PageText; 
          log.Info($"Received siteUrl={siteUrl}, pageName={pageName}, pageText={pageText}"); 

        If you wanted to be “tighter” on how data is passed to the server, you could implement a specific class with appropriate fields/properties of course, and specify that as the type that .NET’s ReadAsAsync method should attempt to deserialize the request body to (instead of ‘object’). But, the code above works as a simple way to collect some data passed to the Function – on the client side, of course, we would ensure an appropriate string of JSON with the same properties is set to the body of the request (shown below).

        Returning in the right way to the client

        We want our endpoint to respect the HTTP conventions here by returning a HTTP 200 if all is good, some appropriate 4xx error code if the request isn’t valid, and so on. We can use the HttpRequestMessage.CreateResponse() method to do this. One example where we might want our Function to send back an error is when it’s called from the SharePoint Framework local workbench instead of a real site – if we don’t have a site, how can our Function know where to create the page? So, I send back a HTTP 400 (bad request) in this case:

        if (siteUrl.Contains("")) { 
           // N.B. the “” URL indicates the local workbench in SPFx.. 
          return req.CreateResponse(HttpStatusCode.BadRequest, "Error: please run in the context of a real SharePoint site, not the local workbench. We need this to know which site to create the page in!"); 

        ..and now this will show up in browser dev tools/Fiddler/other monitoring tools in the right way and so on.

        The full code for the Azure Function to create a modern page is:

        We’ll get to the SPFx web part soon, but note that the Azure portal gives you a nice way to test your Function before you’ve actually created a caller. You can craft the request body so that it contains the JSON with the properties the function expects, and then press the “Run” button to see the results. Your Function will execute, and any logging messages you have will be output to the console:


        Integrating the function with an SPFx web part

        So, let’s create a simple SPFx web part which calls our Function. We’ll provide a simple form to collect parameters for the page name and default content, and a button to actually call the Function and get the page created. I didn’t do anything fancy here – I ended up with this:


        So let’s head towards that. First, we need the Function’s URL – we can get this from the Azure portal. Find this link to do that:


        Now we need to think about calling our Function from SPFx. You can do this using the HttpClient object of course, but there are some things to know to structure the request correctly in terms of the headers and body content. We also need to collect some information from our form fields, but the important thing when POSTing data in SPFx is the use of the Headers and IHttpClientOptions objects in the SharePoint Framework:

        const requestHeaders: Headers = new Headers();
        requestHeaders.append("Content-type", "application/json");
        requestHeaders.append("Cache-Control", "no-cache");
        let siteUrl: string = this.context.pageContext.web.absoluteUrl;
        let pageName: string = (document.getElementById("txtPageName")).value;
        let pageText: string = (document.getElementById("txtPageText")).value;
        console.log(`SiteUrl: '${siteUrl}', PageName: '${pageName}.aspx', PageText: '${pageText}'`);
        const postOptions: IHttpClientOptions = {
           headers: requestHeaders,
           body: `{ SiteUrl: '${siteUrl}', PageName: '${pageName}.aspx', PageText: '${pageText}' }`

        ..and then we can use this set of headers/body content (in the ‘postOptions’ object) in a POST request to our Function with the method:, HttpClient.configurations.v1, postOptions).then((response: HttpClientResponse) => {
            // code omitted..

        The important thing here is to trap any non-success responses from the server, by ensuring your call to has both an 'onFulfilled' and 'onRejected' handler (the first and second parameter respectively). You can see this in the full code for the SPFx web part below:

        So, with the code for both the server and client side sorted, our web part can now create a modern page using the PnP methods. Because the Azure Function sends back the appropriate responses, it’s easy for us to display success/failure in the UI.





        Assuming all was well, a new modern page is created in the current site as you’d expect:


        Note that if you want to recreate this web part, you'd also need to some styles in your *.module.scss file:


        In addition to “timer” processes and processing of Azure BLOBs and Queue items, Azure Functions are a great way to add little bits of .NET code to your client-side apps and web parts. We showed it in the context of a SharePoint Framework web part here, but any kind of JavaScript could call our Function – that includes mobile apps, SharePoint Content Editor web parts, SPFx extensions/customizers (the replacement for JSLink/CustomActions etc.) and so on. We went through enabling CORS, bringing in the PnP Core component through the project.json file for NuGet, setting up source control integration and other steps.

        Other things you might need to think of in production include authentication. My example used “Function auth + SharePointOnlineCredentials”, but you might want to secure your Function with AAD instead and use true app authentication within your code. That would mean first registering an AAD app and obtaining an access token through adal.js, which is certainly more complex and presents an issue around Reply URLs if your web part can be on multiple pages. Vesa and Waldek talked about an interesting alternative which calls the Function through an IFrame (with cookies), but that only works if your code can use app-only auth. It would be nice to have better options than this in the future to be honest.

        Consider also that Functions are evolving beyond .csx files, so although you could always reference your own DLLs from there and factor your code that way, other more direct ways of using class libraries now exist too – see Publishing a .NET class library as a Function App

        Either way, Functions are a great tool and as a developer you’ll benefit from being familiar with them :)

        Wednesday, 26 April 2017

        Calling an Azure Function from a SharePoint Framework web part (SPFx) – part 1: use of PnP Core, CORS and continuous deployment

        Azure Functions are the cool thing these days, mainly because they’re just so damn useful. They can work out cheaper than other hosted code (e.g. WebJobs), but they’re also very flexible. You can define a function which runs on a timer or when an item is added to a queue (just like a WebJob), or you can define one to execute when when a HTTP endpoint is hit. In that respect it’s similar to a web API, but simpler and with less of the infrastructure. If I have a button in a page or web part that needs to do something that’s simpler on the server-side (use a method in the OfficeDev PnP library perhaps), I really like the idea of hooking the button up to an Azure Function. My click handler would then POST to the Function’s endpoint, the server-side code will execute, and then the client-side code will receive the response.

        I thought it would be good to show this in a SPFx web part – and to show how data is passed between client and server. We’ll use the example of having our Azure function make use of the OfficeDev PnP core library. Specifically, my web part provisions a modern page into a site and adds an SPFx web part – both things that are harder to do purely on the client side. I’m splitting this into two articles, but overall I’m trying to show a few things here:

        Part 1 – setup, use of PnP Core, CORS and continuous deployment (this article):
        • Initial creation of Function
        • Deployment of function code (using Continuous Deployment from GitHub)
        • Allowing CORS on an Azure Function so that it can be called from JavaScript (including a special entry for the SPFx workbench)
        • Use of SharePoint PnP Core library - via Azure Functions NuGet support
        • Use of App Settings (environment variables) in an Azure Function
        Part 2 – calling from SPFx and passing data (next article):
        • Code for the Azure Function side (i.e. the work to create a modern page from some passed parameters)
        • Code for the SPFx side
        • Passing data to the function and adding correct headers
        • Returning data from the function, and displaying success/failure in our SPFx web part

        Overall we’ll have a solution which creates a modern SharePoint page from a button click – but the pattern can be used for whatever you want.

        Azure Functions – different types, and use of .NET code

        As a reminder, when you define a function you specify the trigger – these include:

        • HTTPTrigger (the one we’ll use here)
        • TimerTrigger – execute something on a scheduled basis, as you could do with a WebJob
        • QueueTrigger – execute when something is added to a queue
        • Lots of others – including BlobTrigger and “Generic webhooks” (N.B. not currently what you’d use for SharePoint webhooks)

        Of course, use of a HTTPTrigger doesn’t need to be in response to a button click – it could be any time you can post something to the server-side. But a button-click is what we’ll use here. Picking up some awareness of pricing of Azure Functions is a good idea, in particular the difference between the Consumption plan and an App Service plan. In most cases the Consumption plan is what you’ll prefer (and your costs will be peanuts), except perhaps for production implementations that need to run at scale and/or when you have existing resources running on an App Service plan. Anyway, that’s a slightly different topic and you can read more at Choose the correct service plan for Azure Functions.

        Developing Azure Functions code with .NET
        If you're new to Azure Functions, note that the development model for .NET is different in a couple of places:
        • There's no Visual Studio solution - it's just a collection of files in a directory
        • The main file is a csx file, and you won't get IntelliSense support here
        • You can deploy other assemblies and make use of NuGet packages, but this is done in a different way
        Overall, I find a nice approach for developing more complex things is to use Visual Studio to create a DLL/library project for most of my logic, with an accompanying console app to help with local testing. The DLL gets deployed to the BIN directory of the Azure Function, and you can call into it from the function code (CSX file). That’s not the only way, but I like it. However, in the example shown here we’ll keep things simple by having our implementation in the .csx file.

        Let’s get started on creating our function.

        Create the Azure Function app

        1. Open the Azure portal, and find the option to create a new Function App.
        2. Specify the app name and any existing Resource Group and Storage Account that you may have (if not, you’ll need to create these prerequisite containers):

        3. Once the app has finished creating, find it in the portal (e.g. by accessing the “recent” section) and click into it.
        4. Click the “New Function” button: 

        5. I then prefer to use the “custom function” path:

        6. Find the “HttpTrigger-CSharp” template (you might want to filter down to C# templates only using the dropdown):

        7. Give the function a name – we’ll also leave the “Authorization level” as the default of “Function”: 

        8. Click Create – you should now see the integrated editor: 

        9. You can now play around with running the function – consider how data is passed to the function and returned for example.

        You’ll find that the integrated editor is great for some initial playing. But as you get more serious, I personally find it slicker to set-up some continuous deployment from source control, whether that’s GitHub or Visual Studio Online. Yes, you do have to commit/check-in each time you want to test your updated code – but that feels better than a) using the integrated editor and b) manually copying files using the Kudu interface. If source control integration feels a bit heavyweight for your needs, consider also the options of sync’ing from OneDrive or Dropbox – cool stuff I suppose, at least if you don’t really need true source control.

        Deploying files to an Azure Function via GitHub integration (optional)

        So this is an optional step, but since we’re here let’s go through the high level. The only complexity is doing things in the right order and making sure your folder is “at the right level” for how an Azure Function expects to have it’s files. The process isn’t hugely different for other systems such as Visual Studio Online by the way. The full documentation is at, but here’s my summary with screenshots:

        1. First create yourself a repository:

        2. Then clone it to the directory you want to work in on your machine:


        3. Now open the directory in VS Code, and add the files for your function – you need to obtain these by copying from the Function you created earlier. It’s only a a couple of files, so I just copy the contents between the Azure portal and a file I created in VS Code. At this point it’s just the default content of these files – so I suggest making a simple code change to help us check later that the deployment is happening properly (e.g. make a simple change to one of the logging statements):

        4. Once your files are ready, go back into the Azure portal and find the “Deployment options” link where continuous deployment is configured:


        5. Click that link, then click the “Setup” button and choose GitHub:

        6. Now walk through the process of pointing to your GitHub repository and providing authentication details:

        7. Now we need to commit our files to GitHub – you can do this from the command-line if you like, or using VS Code like this:

        8. Once the code is checked-in, examining the file in the Azure Functions portal should show your code change:


        So, we’re now in good shape for developing our code. We’re no longer restricted to the web-based editor – instead, we can use whatever editor we like and properly store our Azure Function files in source control.

        Enable CORS on the Azure Function

        The next step is to ensure our Function can be called from JavaScript in a web page – and that means CORS support must be added. This is critical even to be able to test with the SPFx workbench, and we need to specify whatever URLs we will use (including the local workbench URL). To do this, find the “CORS” setting in the “Platform features” area of your Function:


        Once in there, specify any URL domain which will host JS code which will call into your Function – as in the image below, this is typically your Office 365 tenant domain(s) and also the local SPFx workbench URL (https://localhost:4321):


        Click “Save” to store the settings. Your Azure Function can now be called from SPFx.

        Add the SharePoint PnP Core component via NuGet

        To call into SharePoint PnP methods, the best option is to use Azure Functions support for NuGet – as an alternative you could obtain the PnP DLL and upload it to your function’s bin directory, but the NuGet way is more straightforward. The first time the code runs, any NuGet packages you specify as dependencies get downloaded and installed to your Function’s directory.

        This is done by adding a project.json file in the directory of your Azure Function:


        Add content like this to specify the “SharePointPnPCoreOnline” NuGet package:

        If you configured source control integration earlier, remember you’ll need to check-in now so that the code builds:


        Configure App Settings for SharePoint credentials

        As the final preparation step, we’ll add some App Settings variables to store the username/password used to call into SharePoint (to create our modern page). We’re doing this because we’ll authenticate to SharePoint using SharePointOnlineCredentials (i.e. a simple username and password). For real-life uses you should consider using app authentication, be it of the SharePoint Add-in variety OR the Office 365/Azure AD app variety – in the latter case, you’d need to use adal.js or similar to obtain an access token to pass to your function of course. In this case, we’ll do two things to add some security and manageability to things:

        • Ensure our Azure Function requires simple auth in the form of an “API key” – the calling code must provide this
        • Store the credentials to call into SharePoint as App Settings of our Azure Function – that way they’re not hard-coded anywhere or stored in any particular file in clear text

        Configuring App Settings for a Function is just like doing it for any Azure web app:

        1. Go to the “Application Settings” area within “Platform Features” in your Function app:

        2. Once there, enter a key/value for the username and password you wish to connect to SharePoint with:

        3. Click “Save”. These values will now be available to your code.

        The corresponding C# code to use in your Function to fetch these values is this:

        string ADMIN_USER_CONFIG_KEY = "SharePointAdminUser";
        string ADMIN_PASSWORD_CONFIG_KEY = "SharePointAdminPassword";
        string adminUserName = System.Environment.GetEnvironmentVariable(ADMIN_USER_CONFIG_KEY, EnvironmentVariableTarget.Process);
        string adminPassword = System.Environment.GetEnvironmentVariable(ADMIN_PASSWORD_CONFIG_KEY, EnvironmentVariableTarget.Process);



        We’re now complete with the setup steps. Our Azure Function is configured with CORS, is ready to call into the SharePoint PnP Core library, has some App Settings for credentials, and is configured with Continuous Deployment from GitHub. In the next post we discuss the code used on both sides – the TypeScript/SPFx code to call the function, and the code inside the function which does the work - see Part 2 - calling from SPFx and passing data.