 SharePoint Embedded provides a faster way to build file and document focused apps. SharePoint Embedded is powered by SharePoint's existing document management features and makes it easy for every developer, independent software vendor, and enterprise to include critical Microsoft 365 file and document management capabilities in every app they build without special or additional licenses and at the same time keeping all these files in their own Microsoft 365 tenants. In this episode, you're going to learn how to create a simple web application that demonstrates common scenarios and use cases that developers can implement in their SharePoint Embedded enabled applications. I'll give you a heads up though. This is a longer episode where I demonstrate creating a SharePoint Embedded app step by step. There is a lot of code. If you're following along, you can check the description for a link in the for the associated article where you can either copy and paste the code or you can download a sample app that I created during this episode. Hi, I'm Andrew. If you're new here, be sure to hit that subscribe button to stay up to date on all my videos for Microsoft 365 and Microsoft Azure full stack developers. If you're new to SharePoint Embedded and you're not sure what it is or why you'd use it as developer, you want to check out my other video where I cover those topics. This one is going to be about building an application, but I do want to set a little bit of context here. Developers can create applications that utilize the powerful file and document management capabilities in SharePoint using SharePoint Embedded. These types of applications have two distinct components. One component is responsible for performing all the crud operations against SharePoint Embedded using Microsoft Graph APIs and the other component implements the interface for users to consume and store documents that have been stored inside of SharePoint Embedded. Now that's what SharePoint Embedded brings to developers. It provides a faster way for developers to create file and document focused applications. SharePoint Embedded is powered by SharePoint and developers can integrate the same powerful file and document management capabilities that SharePoint has to offer in their own custom applications without the SharePoint UX. Another way to look at SharePoint Embedded is your custom application leverages SharePoint for all document storage and collaboration features and this effectively is going to be using SharePoint Embedded as a headless API into SharePoint's document storage system. Before you can start creating a SharePoint Embedded application, the first thing you need to do is make sure that SharePoint Embedded is enabled in all of your tenants. Now this must be done in all relevant tenants. There are two categories of tenants involved in all SharePoint Embedded applications. There's a single provider template and one or more consumer tenants. Consider two different scenarios. In the first scenario, Contoso is going to create a new SharePoint Embedded application that they intend to sell to their customers such as AdventureWorks and Woodgrove Bank. These customers will use the app but the app is going to store the data in the customer's 365 tenants. So in this scenario Contoso is my provider of the app while AdventureWorks and Woodgrove Bank are consumers of the app. So in this scenario there are three tenants involved and all three of them must have SharePoint Embedded enabled. Now in the second scenario Wingtip Toys is creating a new SharePoint Embedded line of business application to enable their partners to use the application to submit designs, invoices and other files to Wingtip Toys. Now in this scenario Wingtip Toys is both the provider and the consumer of their application. So in this case only a single Microsoft 365 tenant is involved but it serves both roles. In both of these scenarios all provider and consumer tenants must have SharePoint Embedded enabled before you can create and use a SharePoint Embedded application. Now a little side note is that I created this video during the public preview of SharePoint Embedded in December of 2023. So the steps may change prior to and after SharePoint Embedded reaches the general availability milestone. Therefore I'm not going to cover that step here and instead I want to suggest referring to the docs for the most current steps on how to enable SharePoint Embedded in your tenants. Now for my demo I'm focusing on the single tenant setup so my Microsoft 365 tenant is going to serve both as my provider and my consumer tenant. Now once SharePoint Embedded has been enabled for the provider tenant which I've already done you then need to do a few things in your tenant before you can start coding up your SharePoint Embedded application. Now in the provider tenant I need to first create a new Microsoft Intra ID application formerly known as Azure ID and then I need to create a new container type. The container type is responsible for two things. It's going to associate all of the storage containers that are going to live in a consumer 365 tenant with the provider app and it's going to link the containers with a specific Azure subscription for billing purposes. Now after you create the container type in the provider's tenant you then need to register the container type in the consumer's tenant. Now let's start by creating the Microsoft Intra ID application. This is going to be used to authenticate and obtain the necessary permissions to call the Microsoft Graph and the Microsoft SharePoint APIs. I'll start by creating that Intra ID application using the Microsoft Intra ID Admin Center and I'm going to create a new registration named my SharePoint Embedded app and set it to be a single tenant app. Microsoft Intra is then going to display the details of the new app that I just created. Now I'm going to create a new text file so I can keep track of multiple values that I'm going to need later in my example here. So I'm going to copy the client ID and the tenant ID from the app's overview page into this text file that I'm going to need later in building out my app. Next let's configure the authentication for the React based spa and setting the redirect URI to localhost 3000 which is where my demo app is going to run. Now I need to set the permissions that the app is going to need so it can create and access container types and containers. Now I need to set the permissions the app is going to need so it can create and access container types and containers with SharePoint Embedded. But at the time of writing this article and recording this video the two permissions that I need to add aren't yet visible in the list of permissions in the Microsoft Intra ID web interface to be selected so to get around this I'm going to manually add them to the app's manifest. From the manifest page in Intra ID I'm going to need to find a property called required resource access and there's an existing resource with the resource ID app ID that's been set to this one that's got a bunch of zeros and then a three and a C in there. That's Microsoft Graph and the existing permission that you see that's already present that's the user.readScope that all apps have by default. Next I'm going to add a new resource app ID for SharePoint whose ID has a 0FF1-CE00 in the ID and I'm going to add the following application and delegated permissions for the container.selectedScope. Next I'm going to add a custom permission or scope to my application so an administrator can prompt the user to allow the app to manage containers. Now this is not a SharePoint online or Microsoft Graph permission this is a custom permission that I'm creating that only my web API is going to understand. So to do this on the expose an API page I'm going to select the set link next to the application ID URI and this is going to default to my app's ID using the API colon slash slash and then the GUID of my app. Next I'm going to select add a scope and I'm going to add a new permission for the app. I'm going to create a brand new scope using the following settings that you're going to see me type out here and then I'm going to select add the scope and my web API I'll ensure that this permission has been granted to the application using code. Now some of these permissions we've added require admin consent so from the API permissions page I'm going to scroll to the bottom of the page I'm going to select the enterprise applications. You're going to notice though that these permissions are showing up for Microsoft Graph and SharePoint but they just have their GUIDs because the web UI doesn't understand what these are just yet or doesn't recognize them yet because we're still and as I said earlier I'm doing this video during the public preview phase of SharePoint embedded but I'm sure that these will show up later. Then on the permissions page I'm going to select the grant admin consent for Contoso or my tenant name and then accept to the prompt to grant admin consent the two pairs of permissions file file storage container that selected for Microsoft Graph and containers selected for SharePoint. The two pairs represented the application and the delegated permissions for each of the two permissions that you see that you saw listed there. Now for an app to authenticate using the OF2 client credentials flow with Microsoft Intra ID it needs both the client ID and a client secret or that's the flow we're going to use from our web API. So on the clients and secrets page we need to create a new secret so I'm going to select the client secrets tab and then I'm going to create a new client secret setting a description and setting a duration for the expiration. Now when the secret is created it's going to be shown one time so make sure that you copy this as the client secret in your local text file for use in a later in this demo. If you don't copy this value you're going to have to create a new secret as you'll never see a previously created secret. Finally as part of the last step I need to register the container type that's currently defined in the provider tenant. I need to do and need to register it in the consumer tenant or tenants and this is true for both single tenant and multi-tenant application and what this does is it ensures that only specified applications have access to the containers in their tenant. Now if this step is not completed my SharePoint embedded application is going to get an access denied error whenever I attempt to do anything with a container getting a container a listing a container or writing or creating it to container or accessing the data within it. So to register a container type I'm going to use the SharePoint online REST API. Now the SharePoint online REST API requires an application to authenticate with a certificate rather than just a client secret so first I need a certificate which I'm going to create as a self-signed certificate. Now you can do this using either PowerShell and the new self-signed certificate commandlet or you can use the open SSL utility. Now while there's nothing wrong with it I'm personally not a fan of PowerShell and I avoid it if at all possible so I'm going to use the open SSL utility. Now regardless if you choose PowerShell or the open SSL utility to create the certificate you're going to have a couple files that are going to be generated for you. The .cer file is the self-signed certificate this is the public key. The .key files are the private keys for my certificate the .pem1 is the private key in a base 64 format which is what we're going to use. Now I need to add this key to the Microsoft's intra ID application that we've created for our SharePoint embedded application and I'm going to do that in the certificates and secrets page and once this is done you'll see that the intra ID is going to show me the generated thumbprint for my private key so I'm going to save this value to that text file where I'm keeping all my other values just like we've done before because I'm going to need this in just a minute. Now the last step is to create a new container type in my provider tenant and this can be done using the SharePoint online PowerShell module so you want to make sure you've got the latest version installed by either installing the Microsoft online SharePoint PowerShell module using the PowerShell installed module command or you want to upgrade the one that you've previously installed to ensure you've got the latest version with some of the new command lists that we need for SharePoint embedded and you can do that by using the same name of the module but instead you're going to use the update module uh uh commandlet instead. Now once you've got the latest version you want to connect to your SharePoint online site and create a new container type and the way you're going to do this is you're going to first import the Microsoft online SharePoint PowerShell module and then you use the commandlet connect SPO service and pass in the URL of the admin center for your SharePoint site to log in as an administrator and then use the new SPO uh container type commandlet to create a new container. Now you want to make sure that you specify what you want to name your new container type. Mine is my first SBE container type that I'm going to use in my example and the app or client ID of my intra ID application that I previously created so this is going to map my container type to a particular intra ID application which is my SharePoint embedded app that I'm creating. Now in this case I'm creating a trial container type which means I don't have to set any billing details. Trial container types are great for development they're only valid for 30 days and they're limited to 100 megabytes but if you want to create a permanent or production one you're going to need to also pass in the parameters to set the azure subscription ID the resource group and the region the azure region to real values and you can learn more about the developer versus production container types in the docs you'll find that under SharePoint embedded admin experiences and dev admin. Now after running this command you're going to see the results of creating the container type so I'm going to copy the ID of the container type that was just created and I'm going to put that in my text file as I'm going to need that later as well. Now to register the container type with the consumer's tenant I'm going to use the SharePoint REST API specifically the storage container types application permissions endpoint. The SharePoint embedded team has made this a lot easier for us by giving us a postman collection that's filled with lots of examples in calling the different SharePoint online and Microsoft Graph endpoint so not just registering the content type the container type in our tenant our consumer or provider tenant but there's a lot of other examples here I just going to use one piece of it for this step. Now the SharePoint embedded samples repository from the from Microsoft I'm going to find a postman collection and I'm going to get the raw URL for that collection in the GitHub repo. Now in postman I'm then going to import the collection again postman is just a utility that I have installed that you can get for free and you can use it to make calls to restful endpoints or just make HTTP requests get some posts and all other sorts of things to simplify a little bit of debugging stuff. Now notice that the overview of the collection contains a bunch of documentation and one important section covers creating a postman environment file to simplify setting up the necessary values. Now I've already created one and I just need to populate the different values. The client ID well this is the Microsoft intra applications application or client ID the client secret this is what Microsoft the Microsoft intra ID applications client secret the consuming tenant ID this is the ID of the Microsoft 365 tenant of the consumer tenant that you want to target the tenant name is the name of your tenant and that's the sub domain portion of your SharePoint online site the root site URL this is the root URL of your tenant including SharePoint comm in the name the container type ID this is the good of the container type that you created in your provider tenant the cert thumbprint this is the thumbprint of the certificate that was displayed by Microsoft intra ID after I successfully uploaded my certificate to my Microsoft intra ID application and the certificate private key is the private key of my certificate so for this value I want the one that is in the base 64 format that's also known as the PEM format the last two values that you see here the app only cert spo token and the app only cert graph token these are going to be dynamically generated and populated as explained by the rest of the postman collections overview page and I'll let you read that on your round okay once my postman collection and my environment are all set up I'm going to run the register container type request in the application containers folder and once that's done the app that I'm going to create in my next few steps but we'll be able to manage and access storage containers in my Microsoft 365 tenant all right at this point you should have the following values saved in a text file from the steps that are already performed you should have a Microsoft intra ID app that's the application that you've created that will be used by the app that we're about to create to communicate with SharePoint online and Microsoft graph and for that we need a couple things we need the client ID which is the good of the intra ID application so client ID is also known as the application ID we also need the client secret which is the secret of the intra ID application and we're also going to need the container type ID the ID of the SharePoint embedded container type that I just created in the provider tenant all right at this point we've enabled and set up the core pieces that we need to start creating our first SharePoint embedded application now the application is going to have a client side interface that I'm going to implement as a single page app or a spa using react and a web API that I'm going to implement as a no JS based rest server that the spa is going to use to perform a more privileged operation than it can just going straight from the client to say Microsoft graph now I'm going to start by creating the spa using the create react app utility and I'm going to do this from a folder where I want the app to be created now that my app has been created I'm going to go ahead and open it up in VS code and I'm going to go back and also open up my little text file that's got all my settings in there that we're going to need and let's just make sure we don't lose this on penness to the interface open up the package.json file because now I need to install a bunch of packages that I'm going to use in this in the spa app by running another command to install a bunch of packages I'll explain what this command is doing it's installing the following packages it's installing the azure mcell package which is going to be used to authenticate with Microsoft intra ID and then it's going to install a couple Microsoft graph toolkit packages like the element package the react package and the mcell to provider package these are all for from the Microsoft graph toolkit and it's going to contain some UI components for react and for authenticating with the Microsoft authentication library provider that we have for Microsoft graph I'm also installing the react components and icons packages from the fluent UI via v9 library next up I'm going to go ahead and add the necessary scaffolding for my API my web API server so I'm going to start by running another command to install a bunch of packages and actually I'm going to run two commands one to install some production packages or real dependencies and then I'm going to have some dev dependencies as well so this command is installing the following packages it's installing the restifying and types restify package which is a node js based API server and it's going to be as associated declarations for typescript this is what I'm using to implement my web API it's also going to install the mcell node package which will be used to authenticate with intra ID from a node environment and it's also going to install the Microsoft graph client which is the JavaScript SDK from Microsoft graph and then finally it's going to install the isomorphic fetch package which is a polyfill that's going to add the browser's fetch API as a global so its API is consistent in my web my web API's code is going to be consistent between both the client and the server I can use the fetch method both in the client and now with this I'll be able to use the fetch method on the server I'm also installing the JSON web token package which is an implementation of JSON web token and the jwks.rsa package which is a library for retrieving signing keys from a JSON web key set endpoint or jwks now next I'm then going to go in and add a typescript compiler configuration for my web API project I'm going to do that by adding a new folder called server to the root of my project where my web API is going to go and then I'm going to put a file of the tsconfig JSON in that folder and add the following code to it now what this does is it's going to set and configure the typescript compiler when I need to build my web API part of my project now I need to add a placeholder for my web API to this project so I'm going to do that by adding a index.ts file to the root of my server folder and I'm going to add the following code to it this is going to create a new restify server and then configure it to listen for requests on port 3001 and it's also going to enable cores next I'm going to add a few constants to store my deployment settings so I'm going to do this by adding a new file called .env to store the settings for my web API server and then I'm going to add a bunch of settings to that file that I'll set the values for later now that's great for the server side or web API part of my project but I need to do a similar thing for my single page app so what I'm going to do is create a new file called constants.steak ts in a common folder and this is going to store the same kind of settings for my react app and I need to do this because you'll see that I can't inject environment variables into the client process because that's going to be running in the browser I can do that on the server side process though which is why I created the .env file now I need to update the values of these two files to use a lot of those values that we specified earlier so the anything where you see the client ID this is the application or client ID of the intra ID application that I previously created with the intra admin center same thing is true for the client secret now the app authority this is the authority of the Microsoft intra ID application and for this I'm just going to use the login.microsoftonline.com slash .com slash common the client server URL this is the URL of the client side react spa application and for this the create react app spends this up at localhost 3000 on an HTTP endpoint and then the API server URL this is the URL of the web API server I mentioned earlier a RESTify server defaults to HTTP localhost colon port 3001 and then finally I need to specify the container type ID this is the ID of the SharePoint embedded container type that I created when I was previously setting up my provider tenant so the authority I could use the common endpoint but that's only available it's only applicable when I'm doing a single tenant app so in this case here I'm specifying the authority using the ID of my tenant which if you recall I actually copied that when we created our intra ID application finally I'm going to add a new file the scopes.ts file to my common folder for my client side web app this is going to store a list of all of the OAuth2 scopes or permissions that I'm going to use in my spa app so this contains a list of all the permissions that I'm that I'm going to use and I'm going to export that as constants for easier reuse and and intelligence I'm actually going to create a copy of this and move the copy over to my server side come part of my project for the web API because it's going to yield a lot of these same scopes and so I'm just going to do this to make it easy next step is I'm going to make some changes to the project to simplify my life of building running and testing my app I like to do this using npm scripts and using two really useful utility packages so I'm going to go ahead and install these two packages first at the root of my project where I package.json file is so what are these packages well the envcmd package that's going to inject environment variables defined in a file into another process that will come in handy for our backend server or for our web api the npm run all package is going to include a couple utilities to run multiple commands including npm scripts in a parallel or in a sequence um sequentially and then uh finally the last thing I'm going to do to use these is in my package.json file I'm going to go update these scripts object to have a bunch of new and changed scripts so let me explain what these scripts do all the default create react app scripts I rename those to include a cre suffix in their name to indicate that they're associated with the create react app now the star script uses the run esk method from the npm run all package that I just installed and it's going to run two scripts sequentially it first runs the build script to transpile the entire project from typescript to javascript the create react app already does that when I build it but I have to also do that to my server side web api project and then it's going to run the script called start apps now the start app script that runs the start front end and start back end scripts in parallel so I'm both those running at the same time and it does that using the run p command or method from the npm run all npm package and then finally the start back end script is going to use the env cmd npm package I just installed to inject all the environment variables that I defined in the dot env file into my api server process for the web api so at this point we have a template project that I can now use to add some additional functionality now I want to do one final step in preparing my project adding support for the user login to my react spa app this involves adding some configuration code for the microsoft authentication library and configuring the microsoft graph toolkit with the necessary login details the microsoft graph toolkit includes this concept of a provider that's going to enable authentication implementation for acquiring access tokens on different platforms and these also expose a microsoft graph client for calling microsoft graph apis now one neat aspect about this is that you can define a global provider that's used throughout our entire spa so I'm I'll configure and add an msal provider to the root of the spa which is in the source folders index.tsx file before actually load the react app okay now let's go ahead and implement that sign-in process I'm going to do this in the root component for my entire spa and that's the app.tsx file so the first thing I'm going to do is update all the import statements to use some react hooks the necessary graph components and import some permissions as well as the constants that I've defined in my project now my app is going to need the current user sign-in status so to do that make my life easier I'm going to use a custom react hooked that I'm going to add outside my existing app function for my app component what this does is this creates a method called update state that sets an internal state value based on the current user signed in state and then registers a listener to call the method when the provider is updated it then sets the current state and then it returns the user signed in state next I need to add a handler to obtain an access token when the user completes the sign-in process so this handler called prompt for container consent uses a configured instance of an msal public client application to acquire the user's access token from a successful authentication flow using either the token acquisition process of obtaining it from cash silently or by launching the the pop-up sign-in process now with all this set I'm now going to update the components rendering to include a sign-in button I'm going to test the app by running npm run start and after a few moments my browser will load with my application you'll see that I'm not signed in so we'll test out the sign-in process by clicking the little login button and here you can see that we've successfully logged in and you can see that it's displaying the currently logged in user's name now that the basic project setup is complete and the user authentication has been configured let's move on to adding support for listing and selecting containers in my tenants partition but before we go there I need to discuss some specifics around authentication and how to obtain access tokens for the application to call Microsoft Graph interacting with SharePoint embedded containers is a privileged operation that is carried out using the Microsoft Graphs storage slash file storage slash containers endpoint and in my app container management will only be handled by the web API which will authenticate as the app to obtain an access token for Microsoft Graph and it's doing that using the app plus user style of authentication also known as delegated permission now in this scenario the web API is going to use a different identity other than the one that it it's its own identity to call another API Microsoft Graph and that other identity it's going to use is the user's identity now using the OAuth 2 on behalf of or otherwise known as obo flow the web API is going to request an access token from intra ID for use with Microsoft Graph but it will include the user's access token that the spa that obtained when the user signed in to the application the user's access token is included in the obo request as the assertion to prove Microsoft intra ID that the identity of the user that I want the web API to operate as that you can learn more about the OAuth 2 obo flow from the Microsoft identity platform documentation so for this task I'm going to use the MSAL library so first I'm going to create a confidential client application for the Microsoft intra ID application then I'm going to include the user's access token as the user assertion token to obtain a new obo access token and once I have that obo token I can then create a Microsoft Graph client from the graphs SDK to simplify issuing and calling the Microsoft Graph and finally I can submit the request to Microsoft Graph for example to create a new container so let me go ahead and implement this within my application so to begin I'm going to go ahead and create the necessary web API components to support my react app I first need a utility file to obtain an access token using the obo flow using the existing credential so I'm going to create a new file called auth.ts in my web API folder and I'm going to add some of the following code to it this will take a configured MSAL confidential client application and the user's ID token to request a new token that I can use to call Microsoft Graph now I'm going to create a handler to get a list of all the containers using the Microsoft Graph to be I'm going to return back to the react app so I'm going to create another new file called list container.ts in my web API and I'm going to add a bunch of code to it this defines a new function called list containers that I'm going to link it up to my restify server to listen to for that specific request when it's called now what this does is it's going to use an MSAL confidential client to issue a call to the beta version of Microsoft Graphs storage slash file storage slash containers endpoint that's matching the specific container type that I created previously the results of this call will be returned to the caller which is our spa of the API's new endpoint now with the endpoint created I'm going to add it to my restify server as a listener for an htb get request to the slash API slash list containers endpoint with the web API setup I can update the react project to provide users an interface to select an existing container or to select a new container so I'm going to start by creating a new interface for I container with a bunch of different properties that are going to represent the object that I'm going to both send and receive to and from calls to the Microsoft Graph endpoint now I'll create a new service that will be used to call the web API endpoint or make direct calls from the react app directly to the Microsoft Graph so I'm going to create this new file called sp embedded.ts and a folder called services in my spa and I'm going to add a bunch of code to it the method get API access token in the service is going to use an MSAL public client application that I'm going to use to call the web API specifically my list containers endpoint next I'm going to add the following list containers method that will call the web API to get a list of all the containers now this will get the access token the get API access token utility method returns and include it in the call to my web API recall that this access token is used to create a MSAL confidential client application to obtain an OBO token in order to call Microsoft Graph that OBO token has more permissions granted to it than I can only get from just a standard web call like I'm doing from my spa okay now I'm going to create a brand new react component that will handle all of my container tasks and the user interface so this new file containers.tsx is a component that's going to go inside of my components folder and I'm going to add a bunch of code to it now the code that I'm just pasting in here this is going to serve as a scaffolding for this component as I'm going to need to add a lot of business logic to it so just pasting in a bunch of code just to save a little bit of time here now aside from the typical imports and component declaration this code contains a new instance of my SharePoint embedded service that I just created in the last step and this new method called use styles this is used to create the an object that will use to style the fluid UI react components in the in the component so the first step in this process is to get a list of all my containers I'm going to start by adding the following code to the component now this is going to set a few state values to hold the containers that are retrieved from my web API next I'm going to add the following code that will do two things first it will implement a react hook to get all the containers when the page loads and set the state object that will keep track of them second it'll create an event handler method that when a user selects a container from the drop down control and will implement in the user interface in just a moment next I want to update the rendering by adding the following to the return method this is going to create my drop down control and a placeholder where we're going to add a list of the containers in the selected the contents of the selected container we'll do that later though in our demo the last step is to add the new containers component to the app in the app.tsx file I'm also going to find the empty div markup in my components return statement in the app.tsx and I'm going to replace that markup with the following code that you see here to add the containers component but only if the current user is signed in I'm going to test the app by running npm run start and I'm going to sign in when the browser launches if I need to if this is the first time that you're creating a SharePoint embedded app you're not going to have any containers listed in your drop down because you haven't created any yet just like you see here with me I have no containers created yet so I have nothing to show but we've got it set up we can see that we're actually fetching and getting nothing back so we'll see them eventually when we start creating them speaking of that let's go ahead and create them the last thing to do with the containers component is to add support for creating containers so I'm going to start by first creating the web API parts to support the react app now let's create the handler to create a container using Microsoft Graph and we're going to have that return back to the react app to simplify this step I'm going to duplicate our existing list containers.tsx into a new file called create container.tsx because there's a lot of similarities between the two first I'm going to rename the main method to create container from list container and then I'm going to add some error checking to ensure that the body object in the request contains a property display name for the new container to create I'll then create the payload that I need to send the to Microsoft Graphs API to create the new container and then finally I'm going to update the call to Microsoft Graph to submit a post to the container endpoint to create that new container now that I have my handler for my create container process I'm going to add this as a new endpoint to my restify server by listening to for an HTTP post request to the API slash create containers endpoint now that I have the create container process all sorted on my web API I now want to go address the capability inside of my SPA so I'm going to add a function to my SP embedded service in the SPA this is going to submit the container creation request to the web API and include the user's access token so that the API server can use that to authenticate the main request to obtain an OBO token in order to call Microsoft Graph this new method is similar to the existing list containers method except that it creates a new object and submits it as a post to the web API for this step I'm going to use a fluid UI react dialogue component to prompt the user in a modal for the name of the new container so I'm going to start by adding the following state objects and UI component ID objects immediately after the existing state statements next I'm going to add the following event handlers after my existing event handler that's going to update the name and the description properties for the new container from the input components that will be in the dialogue that we're going to create in a minute and these are also used to handle when the user clicks on a button to create the container as well finally I'm going to update the user experience to add the following react code immediately after my drop-down component this is going to create a fluid UI react dialogue component that's going to be triggered from the button the dialogue is shown when the dialogue opens state changes to true and this happens when the button is clicked the contents of the dialogue the contents of the dialogue contains a title a form and some buttons now the form consists of two input controls to collect the name and the description of the new container and finally the action section contains two buttons to cancel or to submit your request when you submit the request by clicking the button it triggers a spinner to appear and disables the buttons while I wait for the call to be submitted to the web api and onto Microsoft graph to create the container and when all that completes I then hide the dialogue now let's test the app by running npm run start and sign in when the browser launches and loads my spa now let's create a new storage container I'm going to click my create a new storage container button fill in the form and then I'm going to select the button when I'm ready to create it a spinner is going to be displayed while I'm waiting for the operation to complete sending my request back to my web api that's going to then send the request onto Microsoft graph but to do that I had to obtain the obo token and we saw how we set all that up so far well as the operation completes it's going to then hide my dialogue and then it should show up inside of my dropdown selector there it is my first container and when I select it we can see that it's been selected so we've got the process of listing and creating new containers complete so let's see how I can manage the contents of these different containers now if you recall I left a placeholder in the containers component that'll be used to display the contents of the selected container I want to replace this with a new files component but first you need to make a few edits to my project SharePoint embedded containers and their contents they're just drive and drive item objects in Microsoft graph so to simplify my life a little bit I like to use those types that are provided by the Microsoft graph and because I have it installed the npm package that includes them I need to do that first so from the command line I'm going to run the following command from the root folder of my project and it's going to install the graph types from the Microsoft graph types project okay now I can add the new files component so what I'm going to do first is I'm going to assume that it's already created because we're going to create a second but I'm going to start by updating my containers component to replace the placeholder with the files component that I'm going to create in the containers component I'm going to find the line for our selected container and I'm going to replace it with the following now I'm going to create a new file for my files component I'm going to add the following code to it this is just a boilerplate component that includes all the imports and the skeleton of my new files component including a brand new interfaces that I'm going to use throughout this component the first thing I'll do is display the contents of my selected container so to do this I'm going to use a data grid component from the Fluent UI version 9 react library so I'm going to add the following markup inside of the existing div element in my return statement now the grid references a bunch of objects and methods that I'm going to create in a few minutes for the items to display the columns in the grid and settings for how I want the columns to be sized up the child components within the grid define the header rows and the body and mapping them to methods that I'm going to define also in just a minute you can learn more about the Fluent UI v9 data grid control from the docs I'm not going to go into depth and explain it here because the docs are in the included samples that they give you are pretty good I'm going to start by filling in these holes by implementing the things in my grid reference like collection settings and methods I'm going to start with the visual pieces and then we're going to look at getting data into the grid the columns in the data grid can be resized according to the properties that I set so I'm going to create a brand new constant called column sizing options that's currently referenced and then I'm going to add the following code immediately before the return statement next I'm going to define the structure and the rendering settings for all the columns in the data grid I'm going to do this by creating a new collection called columns and I added immediately before the column sizing options that I just created and this defines three columns with properties and methods that the grid references to render the header and the content cells for each row and this is done using this utility method called create table column and I imported that at the top of this file when I pasted in the scaffolding this is going to give each column an ID and specify how the header and the body cells in the table are going to be rendered out now with the data grid configured I'm going to add some constants to manage the react apps state with the properties the existing code is using now I'm going to put these objects at the top of my existing component next I'm going to add some handlers to fetch and display the data from my container now this handler and the react hook are going to get the contents of the selected container the use effect hook that's going to run the very first time the component is rendered as well as when the files components input properties are set or are changed the load items function uses the Microsoft graph client to get a list of all the files within the current folder it's going to default to the root folder if no folder is already selected and then it's going to take a collection of all the drive items returned by the Microsoft graph and adds a few additional properties to simplify the code later at the end of the method it calls the set drive items state accessor method that will trigger a re-rendering of the component and the drive items are set on the data grid items property which explains why the table is going to display some information so let's test our app by running npm run start if it's not already running and if prompted we'll sign in when the browser launches and loads our spa I'm going to select any of my existing containers and if I've added files to them I should see those files but because I haven't yet in this demo I shouldn't see anything come back but I should at least see my grid let's continue building out the files component by adding support to creating and displaying folders I'm going to start by adding the following code immediately alongside my existing react uh state statements and this is going to add the necessary react state values that I'm going to use to create a new folder I'll display a modal pop-up with a dialogue component to the user when they click a button in the toolbar so within my return method immediately before my data grid uh component I'm going to add the following code to implement the dialogue now that the UI is all set up I now need to add some handlers I'm going to add the following handlers after my existing load items handler and these are going to handle opening the dialogue saving the value of a new folder's name and what happens when the user selects the button in the dialogue so again let's test the app I'm going to select the existing container and then I'm going to select the button above the grid to create a new folder in that container now I need to make one more change to the component because right now when I select the folder it's going to launch the URL in a new tab leaving the app and that's not what I want I wanted to just drill into the folder I'm going to fix that by locating the existing columns constant that I previously added and I'm going to find the table the create table column that references the column ID called drive item name and the render cell property I'm going to replace my existing link component with the following code and what this will do is it'll generate two links based on the current item being rendered uh is a is a file or is a folder now I want to select the folder the app will show the contents of the folder next I want to add the ability to upload files to a container or a folder within that container so I'm going to start by adding the following code alongside my existing react statements next I'm going to implement a technique using a hidden input control to upload a file and then I'm going to add the following code immediately after my opening div in the components return method and I need to add a button to the toolbar to trigger the file selection dialog so the way I'm going to do this is I'm going to add the following code immediately after my existing toolbar button that's going to add a new folder finally I'm going to add the following code after my existing event handlers uh to add two new event handlers the on upload file click handler is triggered when you select the upload file toolbar button and the upload file selected uh handler is triggered when the user selects a file if it's not already running go ahead and start your app up again so we can test this by running npm run start and if prompted sign in I'm going to select my existing container and then I'm going to select the button the button above the grid to upload a file all right we're making progress so let's keep going with the content display feature complete let's update the component to support downloading the files that we're uploading so I'm going to start by adding the following code alongside my existing react statements next I want to make sure that an item the data grid is selected before they can download it otherwise the download button should be disabled in the data grid I'll add three properties to set it to support a single item selection mode using the selection mode property I'll keep track of which items are selected using the selected items property and what to do when the selection changes using the on selected change event handler okay now I need to add the following handler after my existing handlers and what this will do is fire when the file selection changes in the grid and set the selected items on the specified state object the download option will use a hidden hyperlink that I'm going to use to do the following first it's going to set the URL of the hyperlink to the download URL of the item and then programmatically click the hyperlink this is going to trigger the download for the user I'm going to add the following markup just after the opening div in the return method to implement this now in the existing columns constant that I previously added I'm going to add a new column to the end of my array this is going to be for supporting different actions and different buttons and then I'll add the following handler immediately after my existing on selected change event handler that I previously added and this is going to handle the two programmatic steps that I previously mentioned where I'm going to set the URL of the link of where the file is it's going to be downloaded and then I'm going to programmatically click it now let's test the app out if your app isn't currently running run it by running npm run start select one of the existing files that you've already uploaded and then select the download button that's enabled once I selected the file here we can see we're downloading the file sweet the last step is to add the ability to delete a file or folder from my container so to do this I'm going to start by adding the following code to my existing list of use state calls next I'm going to add a dialogue to act as a confirmation when the user selects the delete button so I'm going to add the following dialogue just after my existing dialogue component in the return statement I'll then add a delete button by finding the existing columns constant that I added previously and I'm going to find that create table column that referenced my column actions uh my column for actions and in the render cell property I'm going to add a second button after my existing button to support the delete it's basically the same but it's just going to do something different finally I'm going to add one more handler after all my existing ones to handle the deletion of the currently selected item last but not least let's test that app one more time when the browser loads I'm going to select a file or a folder and then select the delete button that's enabled once I selected something and within a second or two I should see the item disappear because it's been deleted and there you have it well it's simple it took a while to build but we've got our first SharePoint embedded application that can list and create containers as well as creating folders and even upload download and delete files and folders within those containers so what do you think about SharePoint embedded do you have any ideas for how you'd use it in a future project or where it would have been useful in previous projects let me know by dropping a comment below and let me know if you want to see more videos about SharePoint embedded and about what topics and don't forget check the links in the description below the video for a link to the associated article where you can download the sample project that I built throughout this video and if you found this video useful please give me a thumbs up it really helps me reach new people and subscribe by hitting that big subscribe button below the video so you'll see when I publish more videos for full stack developers on Microsoft 365 and Microsoft Azure I'm Andrew Connell thanks for watching and I'll see you in my next episode