CINXE.COM
OneDrive File Picker - OneDrive dev center | Microsoft Learn
<!DOCTYPE html><html class="hasSidebar hasPageActions hasBreadcrumb conceptual has-default-focus theme-light" lang="en-us" dir="ltr" data-authenticated="false" data-auth-status-determined="false" data-target="docs" x-ms-format-detection="none"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta property="og:title" content="OneDrive File Picker - OneDrive dev center" /> <meta property="og:type" content="website" /> <meta property="og:url" content="https://learn.microsoft.com/en-us/onedrive/developer/controls/file-pickers/?view=odsp-graph-online" /><meta property="og:image" content="https://learn.microsoft.com/en-us/media/open-graph-image.png" /> <meta property="og:image:alt" content="Microsoft Learn" /> <meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:site" content="@MicrosoftLearn" /> <meta name="color-scheme" content="light dark"><meta name="author" content="patrick-rodgers" /> <meta name="breadcrumb_path" content="/onedrive/developer/breadcrumb/toc.json" /> <meta name="default_moniker" content="odsp-graph-online" /> <meta name="depot_name" content="office.onedrive" /> <meta name="document_id" content="3d07a81d-cdaf-bafb-c1d5-aaf640d8de09" /> <meta name="document_version_independent_id" content="c674b276-f0cb-a5d6-3098-6a31c417f162" /> <meta name="feedback_help_link_type" content="" /> <meta name="feedback_help_link_url" content="" /> <meta name="feedback_product_url" content="" /> <meta name="feedback_system" content="None" /> <meta name="git_commit_id" content="69a7673537113f0835acf149e09fc617cd4e3660" /> <meta name="gitcommit" content="https://github.com/OneDrive/onedrive-api-docs/blob/69a7673537113f0835acf149e09fc617cd4e3660/docs/controls/file-pickers/index.md" /> <meta name="locale" content="en-us" /> <meta name="monikers" content="odsp-graph-online" /> <meta name="ms.author" content="patrodg" /> <meta name="ms.date" content="09/10/2017" /> <meta name="ms.localizationpriority" content="High" /> <meta name="ms.service" content="one-drive" /> <meta name="ms.topic" content="overview" /> <meta name="original_content_git_url" content="https://github.com/OneDrive/onedrive-api-docs/blob/live/docs/controls/file-pickers/index.md" /> <meta name="page_type" content="conceptual" /> <meta name="schema" content="Conceptual" /> <meta name="site_name" content="Docs" /> <meta name="toc_rel" content="../../toc.json" /> <meta name="uhfHeaderId" content="MSDocsHeader-OneDrive" /> <meta name="updated_at" content="2024-06-17 05:17 PM" /> <meta name="word_count" content="2093" /> <meta name="persistent_id" content="48c0d47d-fc3e-e595-67f8-d69a3c0f70e2" /> <meta name="cmProducts" content="https://authoring-docs-microsoft.poolparty.biz/devrel/7428317a-e6c2-4461-ad3e-8a8ad3608734" data-source="generated" /> <meta name="cmProducts" content="https://authoring-docs-microsoft.poolparty.biz/devrel/9d7be3ef-f27c-4c7f-9eba-67c3cd429995" data-source="generated" /> <meta name="spProducts" content="https://authoring-docs-microsoft.poolparty.biz/devrel/e4f59707-f107-48f2-8d75-0afd91868cd7" data-source="generated" /> <meta name="spProducts" content="https://authoring-docs-microsoft.poolparty.biz/devrel/feeb50f3-b677-44f9-b3a6-5f2f58182b0d" data-source="generated" /> <meta name="github_feedback_content_git_url" content="https://github.com/OneDrive/onedrive-api-docs/blob/live/docs/controls/file-pickers/index.md" /><link href="https://learn.microsoft.com/en-us/onedrive/developer/controls/file-pickers/?view=odsp-graph-online" rel="canonical"><title>OneDrive File Picker - OneDrive dev center | Microsoft Learn</title><link rel="stylesheet" href="/static/assets/0.4.028726178/styles/site-ltr.css"> <script id="msdocs-script"> var msDocs = {environment: { supportLevel: 'production', accessLevel: 'online', reviewFeatures: false, systemContent: true, azurePortalHostname: 'portal.azure.com', legacyHosting: false, siteName: 'learn', },data: { timeOrigin: Date.now(), contentLocale: 'en-us', contentDir: 'ltr', userLocale: 'en-us', userDir: 'ltr', pageTemplate: 'Conceptual', brand: '', context: {}, hasBinaryRating: true, feedbackHelpLinkType:'', feedbackHelpLinkUrl:'', standardFeedback: false, showFeedbackReport: false, enableTutorialFeedback: false, feedbackSystem: 'None', feedbackGitHubRepo: '', feedbackProductUrl: '',extendBreadcrumb: false,isEditDisplayable: true, hideViewSource: false, hasPageActions: true, hasPrintButton: true, hasBookmark: true, hasShare: true, isPermissioned: false, isPrivateUnauthorized: false,hasRecommendations: true,contributors: [{ name: "patrick-rodgers", url: "https://github.com/patrick-rodgers" },{ name: "ThomasMichon", url: "https://github.com/ThomasMichon" },{ name: "JeremyKelley", url: "https://github.com/JeremyKelley" },{ name: "rgregg-msft", url: "https://github.com/rgregg-msft" },{ name: "chackman", url: "https://github.com/chackman" },{ name: "OfficeGSX", url: "https://github.com/OfficeGSX" },{ name: "KevinTCoughlin", url: "https://github.com/KevinTCoughlin" },{ name: "rgregg", url: "https://github.com/rgregg" }],}, functions:{} }; </script><script src="https://wcpstatic.microsoft.com/mscc/lib/v2/wcp-consent.js"></script> <script src="https://js.monitor.azure.com/scripts/c/ms.jsll-4.min.js"></script><script src="/static/assets/0.4.028726178/global/deprecation.js"></script><script src="/static/assets/0.4.028726178/scripts/en-us/index-docs.js"></script></head> <body lang="en-us" dir="ltr"> <div class="header-holder has-default-focus"> <a href="#main" style="z-index: 1070" class="outline-color-text visually-hidden-until-focused position-fixed inner-focus focus-visible top-0 left-0 right-0 padding-xs text-align-center has-body-background" tabindex="1">Skip to main content</a><div hidden id="cookie-consent-holder" data-test-id="cookie-consent-container"></div> <div id="unsupported-browser" style=" background-color: white; color: black; padding: 16px; border-bottom: 1px solid grey;" hidden > <div style="max-width: 800px; margin: 0 auto;"> <p style="font-size: 24px">This browser is no longer supported.</p> <p style="font-size: 16px; margin-top: 16px;">Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.</p> <div style="margin-top: 12px;"> <a href="https://go.microsoft.com/fwlink/p/?LinkID=2092881 " style=" background-color: #0078d4; border: 1px solid #0078d4; color: white; padding: 6px 12px; border-radius: 2px; display: inline-block; ">Download Microsoft Edge</a> <a href="https://learn.microsoft.com/en-us/lifecycle/faq/internet-explorer-microsoft-edge" style=" background-color: white; padding: 6px 12px; border: 1px solid #505050; color: #171717; border-radius: 2px; display: inline-block; ">More info about Internet Explorer and Microsoft Edge</a> </div> </div> </div> <!-- liquid-tag banners global --> <!-- site header --> <header id="ms--site-header" data-test-id="site-header-wrapper" role="banner" itemscope="itemscope" itemtype="http://schema.org/Organization"> <div id="ms--mobile-nav" class="site-header display-none-tablet padding-inline-none gap-none" data-bi-name="mobile-header" data-test-id="mobile-header"></div> <div id="ms--primary-nav" class="site-header display-none display-flex-tablet" data-bi-name="L1-header" data-test-id="primary-header"></div> <div id="ms--secondary-nav" class="site-header display-none display-flex-tablet" data-bi-name="L2-header" data-test-id="secondary-header"></div> </header><div id="content-header" class="content-header uhf-container has-padding has-default-focus border-bottom-none" data-bi-name="content-header"> <div class="content-header-controls margin-xxs margin-inline-sm-tablet"> <button type="button" class="contents-button button button-sm margin-right-xxs" data-bi-name="contents-expand" aria-haspopup="true" data-contents-button> <span class="icon"><span class="docon docon-menu" aria-hidden="true"></span></span> <span class="contents-expand-title">Table of contents</span> </button> <button type="button" class="ap-collapse-behavior ap-expanded button button-sm" data-bi-name="ap-collapse" aria-controls="action-panel"> <span class="icon"><span class="docon docon-exit-mode" aria-hidden="true"></span></span> <span>Exit focus mode</span> </button> </div> </div><div id="disclaimer-holder" class="has-overflow-hidden has-default-focus"> <!-- liquid-tag banners sectional --> </div> </div> <div class="mainContainer uhf-container has-default-focus" data-bi-name="body"> <div class="columns has-large-gaps is-gapless-mobile "><div id="left-container" class="left-container is-hidden-mobile column is-one-third-tablet is-one-quarter-desktop"> <nav id="affixed-left-container" class="margin-top-sm-tablet position-sticky display-flex flex-direction-column" aria-label="Primary"></nav> </div><!-- .primary-holder --> <section class="primary-holder column is-two-thirds-tablet is-three-quarters-desktop"> <!--div.columns --> <div class="columns is-gapless-mobile has-large-gaps "><div id="main-column" class="column is-full is-8-desktop"> <main id="main" class="" role="main" data-bi-name="content" lang="en-us" dir="ltr"><!-- article-header --> <div id="article-header" class="background-color-body margin-top-sm-tablet margin-bottom-xs display-none-print"> <div class="display-flex align-items-center "><details id="article-header-breadcrumbs-overflow-popover" class="popover" data-for="article-header-breadcrumbs"> <summary class="button button-clear button-primary button-sm inner-focus" aria-label="All breadcrumbs"> <span class="icon"> <span class="docon docon-more"></span> </span> </summary> <div id="article-header-breadcrumbs-overflow" class="popover-content padding-none"> </div> </details> <bread-crumbs id="article-header-breadcrumbs" data-test-id="article-header-breadcrumbs" class="overflow-hidden flex-grow-1 margin-right-sm margin-right-md-tablet margin-right-lg-desktop margin-left-negative-xxs padding-left-xxs"></bread-crumbs><div id="article-header-page-actions" class="opacity-none margin-left-auto display-flex flex-wrap-no-wrap align-items-stretch"><a id="lang-link-tablet" class="button button-primary button-clear button-sm display-none display-inline-flex-tablet" title="Read in English" data-bi-name="language-toggle" data-read-in-link hidden> <span class="icon margin-none" aria-hidden="true" data-read-in-link-icon> <span class="docon docon-locale-globe"></span> </span> <span class="is-visually-hidden" data-read-in-link-text>Read in English</span> </a><button type="button" class="collection button button-clear button-sm button-primary display-none display-inline-flex-tablet" data-list-type="collection" data-bi-name="collection" title="Add to collection"> <span class="icon margin-none" aria-hidden="true"> <span class="docon docon-circle-addition"></span> </span> <span class="collection-status is-visually-hidden">Save</span> </button><a data-contenteditbtn class="button button-clear button-sm text-decoration-none button-primary display-none display-inline-flex-tablet" aria-label="Edit" title="Edit This Document" data-bi-name="edit" href="https://github.com/OneDrive/onedrive-api-docs/blob/live/docs/controls/file-pickers/index.md"> <span class="icon margin-none" aria-hidden="true"> <span class="docon docon-edit-outline"></span> </span> </a> <details class="popover popover-right" id="article-header-page-actions-overflow"> <summary class="justify-content-flex-start button button-clear button-sm button-primary" aria-label="More actions" title="More actions"> <span class="icon" aria-hidden="true"> <span class="docon docon-more-vertical"></span> </span> </summary> <div class="popover-content padding-xs"><button data-page-action-item="overflow-mobile" type="button" class="justify-content-flex-start button-block button-sm has-inner-focus button button-clear display-none-tablet" data-bi-name="contents-expand" data-contents-button data-popover-close> <span class="icon"> <span class="docon docon-editor-list-bullet" aria-hidden="true"></span> </span><span class="contents-expand-title">Table of contents</span></button><a id="lang-link-overflow" class="justify-content-flex-start button-sm has-inner-focus button button-clear button-block display-none-tablet" title="Read in English" data-bi-name="language-toggle" data-page-action-item="overflow-mobile" data-check-hidden="true" data-read-in-link hidden > <span class="icon" aria-hidden="true" data-read-in-link-icon> <span class="docon docon-locale-globe"></span> </span> <span data-read-in-link-text>Read in English</span> </a><button type="button" class="collection justify-content-flex-start button button-clear button-sm has-inner-focus button-block display-none-tablet" data-list-type="collection" data-bi-name="collection" title="Save" data-page-action-item="overflow-mobile" data-check-hidden="true" data-popover-close> <span class="icon" aria-hidden="true"> <span class="docon docon-circle-addition"></span> </span> <span class="collection-status">Save</span> </button> <button type="button" class="collection justify-content-flex-start button button-clear button-sm has-inner-focus button-block display-none-tablet" data-list-type="plan" data-bi-name="plan" title="Add to Plan" data-page-action-item="overflow-mobile" data-check-hidden="true" data-popover-close hidden> <span class="icon" aria-hidden="true"> <span class="docon docon-circle-addition"></span> </span> <span class="plan-status">Add to Plan</span> </button><a data-contenteditbtn class="button button-clear button-block button-sm has-inner-focus justify-content-flex-start text-decoration-none display-none-tablet" aria-label="Edit" title="Edit This Document" data-bi-name="edit" href="https://github.com/OneDrive/onedrive-api-docs/blob/live/docs/controls/file-pickers/index.md"> <span class="icon" aria-hidden="true"> <span class="docon docon-edit-outline"></span> </span> <span>Edit</span> </a><div aria-hidden="true" class="margin-none" data-page-action-item="overflow-all"></div> <hr class="display-none-tablet margin-bottom-xxs margin-top-xxs" /> <h4 class="font-size-sm padding-left-xxs">Share via</h4> <a class="button button-clear button-sm button-block has-inner-focus text-decoration-none justify-content-flex-start share-facebook" data-bi-name="facebook" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-facebook-share font-size-md color-primary"></span> </span> <span class="margin-left-xxs">Facebook</span> </a> <a class="button button-clear button-sm has-inner-focus button-block text-decoration-none justify-content-flex-start share-twitter" data-bi-name="twitter" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-xlogo-share font-size-xxs"></span> </span> <span class="margin-left-xxs">x.com</span> </a> <a class="button button-clear button-sm has-inner-focus button-block text-decoration-none justify-content-flex-start share-linkedin" data-bi-name="linkedin" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-linked-in-logo font-size-sm color-primary"></span> </span> <span class="margin-left-xxs">LinkedIn</span> </a> <a class="button button-clear button-sm button-block has-inner-focus text-decoration-none justify-content-flex-start margin-bottom-xxs share-email" data-bi-name="email" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-mail-message font-size-sm color-primary"></span> </span> <span class="margin-left-xxs">Email</span> </a><hr /> <button class="button button-block button-clear button-sm justify-content-flex-start has-inner-focus margin-top-xxs" title="Print" type="button" aria-label="Print" data-bi-name="print" data-page-action-item="overflow-all" data-popover-close data-print-page data-check-hidden="true"> <span class="icon" aria-hidden="true"> <span class="docon docon-print font-size-sm color-primary"></span> </span> <span class="margin-left-xxs">Print</span> </button> </div> </details> </div></div> </div> <!-- end article-header --><div> <button type="button" class="border contents-button button button-clear button-sm is-hidden-tablet has-inner-focus" data-bi-name="contents-expand" data-contents-button hidden> <span class="icon"> <span class="docon docon-editor-list-bullet" aria-hidden="true"></span> </span><span class="contents-expand-title">Table of contents</span></button> </div><!-- end mobile-contents button --> <div class="content "><h1 id="file-picker">File Picker</h1><div class="display-flex justify-content-space-between align-items-center flex-wrap-wrap page-metadata-container"> <div class="margin-right-xxs"> <ul class="metadata page-metadata" data-bi-name="page info" lang="en-us" dir="ltr"><li>Article</li><li class="visibility-hidden-visual-diff"><time class="is-invisible" data-article-date aria-label="Article review date" datetime="2024-06-17T17:17:00Z" data-article-date-source="calculated">06/17/2024</time> </li><li class="contributors-holder display-none-print"> <button aria-label="View all contributors" class="contributors-button link-button" data-bi-name="contributors" title="View all contributors">8 contributors</button> </li></ul> </div> <div id="user-feedback" class="margin-block-xxs display-none-print" data-hide-on-archived> <button id="user-feedback-button" data-test-id="conceptual-feedback-button" class="button button-sm button-clear button-primary" type="button" data-bi-name="user-feedback-button" data-user-feedback-button > <span class="icon" aria-hidden="true"> <span class="docon docon-like"></span> </span> <span>Feedback</span> </button> </div></div><nav id="center-doc-outline" class="doc-outline is-hidden-desktop display-none-print margin-bottom-sm" data-bi-name="intopic toc" aria-label="In this article"> <h2 id="ms--in-this-article" class="title is-6 margin-block-xs">In this article</h2> </nav><!-- <content> --><p>The File Picker v8 allows you to use the same functionality used within the M365 service within your solutions. Meaning as we iterate and improve the service, those new capabilities appear for your users!</p> <p>This new "control" is a page hosted within the Microsoft service which you interact with via post messages. The page can be hosted either embedded in an iframe or as a popup.</p> <p><strong><a href="https://aka.ms/OneDrive/samples/file-picking" data-linktype="external">Just Show Me The Sample Code</a></strong></p> <blockquote> <p>You can find the <a href="js-v72/?view=odsp-graph-online" data-linktype="relative-path">documentation for the 7.2 picker here</a>.</p> </blockquote> <h2 id="required-setup">Required Setup</h2> <p>To run the samples or use the control in your solution you will need to create an AAD application. You can follow these steps:</p> <ol> <li>Create a new AAD App Registration, note the ID of the application</li> <li>Under authentication, create a new Single-page application registry <ol> <li>Set the redirect uri to <code>https://localhost</code> (this is for testing the samples)</li> <li>Ensure both Access tokens and ID tokens are checked</li> <li>You may optionally configure this application for multitenant but this is outside the scope of this article</li> </ol> </li> <li>Under API permissions <ol> <li>Add <code>Files.Read.All</code>, <code>Sites.Read.All</code>, Leave <code>User.Read</code> for Graph delegated permissions</li> <li>Add <code>AllSites.Read</code>, <code>MyFiles.Read</code> for SharePoint delegated permissions</li> </ol> </li> </ol> <blockquote> <p>If you are developing in <a href="https://aka.ms/spfx" data-linktype="external">SharePoint Framework</a> you can <a href="/en-us/sharepoint/dev/spfx/use-aadhttpclient#request-permissions-to-an-azure-ad-application" data-linktype="absolute-path">request these permissions</a> in the application manifest with the resource "SharePoint" and "Microsoft Graph".</p> </blockquote> <blockquote> <p>To allow the user to upload files and create folders within the Picker experience, you may request access to <code>Files.ReadWrite.All</code>, <code>Sites.ReadWrite.All</code>, <code>AllSites.Write</code>, and <code>MyFiles.Write</code>.</p> </blockquote> <h2 id="permissions">Permissions</h2> <p>The file picker always operates using delegated permissions and as such can only ever access file and folders to which the current user already has access.</p> <p>At a minimum you must request the SharePoint MyFiles.Read permission to read files from a user's OneDrive and SharePoint sites.</p> <p>Please review the table below to understand what permission are required based on the operations you wish to perform. All permissions in this table refer to delegated permissions.</p> <table> <thead> <tr> <th></th> <th>Read</th> <th>Write</th> </tr> </thead> <tbody> <tr> <td>OneDrive</td> <td>SharePoint.MyFiles.Read<br>or<br>Graph.Files.Read</td> <td>SharePoint.MyFiles.Write<br>or<br>Graph.Files.ReadWrite</td> </tr> <tr> <td>SharePoint Sites</td> <td>SharePoint.MyFiles.Read<br>or<br>Graph.Files.Read<br>or<br>SharePoint.AllSites.Read</td> <td>SharePoint.MyFiles.Write<br>or<br>Graph.Files.ReadWrite<br>or<br>SharePoint.AllSites.Write</td> </tr> <tr> <td>Teams Channels</td> <td>Graph.ChannelSettings.Read.All and SharePoint.AllSites.Read</td> <td>Graph.ChannelSettings.Read.All and SharePoint.AllSites.Write</td> </tr> </tbody> </table> <h2 id="how-it-works">How it works</h2> <p>To use the control you must:</p> <ol> <li>Make a POST request to the "control" page hosted at /_layouts/15/FilePicker.aspx. Using this request you supply some parameters, the key one being <a href="v8-schema?view=odsp-graph-online" data-linktype="relative-path">the picker configuration</a>.</li> <li>Setup messaging between your host application and the control using <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage" data-linktype="external">postMessage</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/MessagePort" data-linktype="external">message ports</a>.</li> <li>Once the communication channel is established you must respond to various "commands", the first of which is to provide authentication tokens.</li> <li>Finally, you will need to respond to additional command messages to supply new/different auth tokens, handle picked files, or close the popup.</li> </ol> <p>The following sections explain each step.</p> <blockquote> <p>We also have a <a href="https://aka.ms/OneDrive/samples/file-picking" data-linktype="external">variety of samples</a> showing different ways to integrate with the control.</p> </blockquote> <h2 id="initiate-the-picker">Initiate the Picker</h2> <ul> <li>View <a href="v8-schema?view=odsp-graph-online" data-linktype="relative-path">file picker configuration schema</a>.</li> </ul> <p>To initate the picker you need to create a "window" which can either be an iframe or a popup. Once you have a window you should construct a form and POST the form to the URL <code>{baseUrl}/_layouts/15/FilePicker.aspx</code> with the query string parameters defined.</p> <p>The <code>{baseUrl}</code> value above is either the SharePoint web url of the target web, or the user's onedrive. Some examples are: "https://tenant.sharepoint.com/sites/dev" or "https://tenant-my.sharepoint.com".</p> <h3 id="onedrive-consumer-configuration">OneDrive Consumer Configuration</h3> <table> <thead> <tr> <th>name</th> <th>descriptions</th> </tr> </thead> <tbody> <tr> <td>authority</td> <td>https://login.microsoftonline.com/consumers</td> </tr> <tr> <td>Scope</td> <td>OneDrive.ReadWrite or OneDrive.ReadOnly</td> </tr> <tr> <td>baseUrl</td> <td>https://onedrive.live.com/picker</td> </tr> </tbody> </table> <blockquote> <p>When you request a token you will use the <code>OneDrive.ReadOnly</code> or <code>OneDrive.ReadWrite</code> when you request the token. When you request the permissions for your application you will select for <code>Files.Read</code> or <code>Files.ReadWrite</code> (or another Files.X scope).</p> </blockquote> <pre><code class="lang-TypeScript">// create a new window. The Picker's recommended maximum size is 1080x680, but it can scale down to // a minimum size of 250x230 for very small screens or very large zoom. const win = window.open("", "Picker", "width=1080,height=680"); // we need to get an authentication token to use in the form below (more information in auth section) const authToken = await getToken({ resource: baseUrl, command: "authenticate", type: "SharePoint", }); // to use an iframe you can use code like: // const frame = document.getElementById("iframe-id"); // const win = frame.contentWindow; // now we need to construct our query string // options: These are the picker configuration, see the schema link for a full explaination of the available options const queryString = new URLSearchParams({ filePicker: JSON.stringify(options), locale: 'en-us' }); // Use MSAL to get a token for your app, specifying the resource as {baseUrl}. const accessToken = await getToken(baseUrl); // we create the absolute url by combining the base url, appending the _layouts path, and including the query string const url = baseUrl + `/_layouts/15/FilePicker.aspx?${queryString}`); // create a form const form = win.document.createElement("form"); // set the action of the form to the url defined above // This will include the query string options for the picker. form.setAttribute("action", url); // must be a post request form.setAttribute("method", "POST"); // Create a hidden input element to send the OAuth token to the Picker. // This optional when using a popup window but required when using an iframe. const tokenInput = win.document.createElement("input"); tokenInput.setAttribute("type", "hidden"); tokenInput.setAttribute("name", "access_token"); tokenInput.setAttribute("value", accessToken); form.appendChild(tokenInput); // append the form to the body win.document.body.append(form); // submit the form, this will load the picker page form.submit(); </code></pre> <h3 id="picker-configuration">Picker Configuration</h3> <p>The picker is configured through serializing a json object containing the desired settings, and appending it to the querystring values as showin in the <a href="#initiate-the-picker" data-linktype="self-bookmark">Initiate the Picker</a> section. You can also view the <a href="v8-schema?view=odsp-graph-online" data-linktype="relative-path">full schema</a>. At a minimum you must supply the authentication, entry, and messaging settings.</p> <p>An example minimal settings object is shown below. This sets up messaging on channel 27, lets the picker know we can supply tokens, and that we want the "My Files" tab to represent the user's OneDrive files. This configuration would use a baseUrl of the form "https://{tenant}-my.sharepoint.com";</p> <pre><code class="lang-TypeScript">const channelId = uuid(); // Always use a unique id for the channel when hosting the picker. const options = { sdk: "8.0", entry: { oneDrive: {} }, // Applications must pass this empty `authentication` option in order to obtain details item data // from the picker, or when embedding the picker in an iframe. authentication: {}, messaging: { origin: "http://localhost:3000", channelId: channelId }, } </code></pre> <blockquote> <p>The picker is designed to work with <em>either</em> OneDrive OR SharePoint in a given instance and only one of the entry sections should be included.</p> </blockquote> <h3 id="localization">Localization</h3> <p>The File Picker's interface supports localization for the <a href="https://support.microsoft.com/en-us/office/languages-supported-by-sharepoint-dfbf3652-2902-4809-be21-9080b6512fff" data-linktype="external">same set of languages as SharePoint</a>.</p> <p>To set the language for the File Picker, use the <code>locale</code> query string parameter, set to one of the LCID values in the above list.</p> <h2 id="establish-messaging">Establish Messaging</h2> <p>Once the window is created and the form submitted you will need to establish a messaging channel. This is used to receive the commands from the picker and respond.</p> <pre><code class="lang-TypeScript">let port: MessagePort; function initializeMessageListener(event: MessageEvent): void { // we validate the message is for us, win here is the same variable as above if (event.source && event.source === win) { const message = event.data; // the channelId is part of the configuration options, but we could have multiple pickers so that is supported via channels // On initial load and if it ever refreshes in its window, the Picker will send an 'initialize' message. // Communication with the picker should subsequently take place using a `MessageChannel`. if (message.type === "initialize" && message.channelId === options.messaging.channelId) { // grab the port from the event port = event.ports[0]; // add an event listener to the port (example implementation is in the next section) port.addEventListener("message", channelMessageListener); // start ("open") the port port.start(); // tell the picker to activate port.postMessage({ type: "activate", }); } } }; // this adds a listener to the current (host) window, which the popup or embed will message when ready window.addEventListener("message", messageEvent); </code></pre> <h2 id="message-listener-implementation">Message Listener Implementation</h2> <p>Your solution must handle various messages from the picker, classified as either notifications or commands. Notifications expect no response and can be considered log information. The one exception is the <code>page-loaded</code> notification highlighted below, which will tell you the picker is ready.</p> <p>Commands require that you acknowledge, and depending on the command, respond. This section show an example implementation of the <code>channelMessageListener</code> function added as an event listener to the port. The next sections talks in detail about notifications and commands.</p> <pre><code class="lang-TypeScript">async function channelMessageListener(message: MessageEvent): Promise<void> { const payload = message.data; switch (payload.type) { case "notification": const notification = payload.data; if (notification.notification === "page-loaded") { // here we know that the picker page is loaded and ready for user interaction } console.log(message.data); break; case "command": // all commands must be acknowledged port.postMessage({ type: "acknowledge", id: message.data.id, }); // this is the actual command specific data from the message const command = payload.data; // command.command is the string name of the command switch (command.command) { case "authenticate": // the first command to handle is authenticate. This command will be issued any time the picker requires a token // 'getToken' represents a method that can take a command and return a valid auth token for the requested resource try { const token = await getToken(command); if (!token) { throw new Error("Unable to obtain a token."); } // we report a result for the authentication via the previously established port port.postMessage({ type: "result", id: message.data.id, data: { result: "token", token: token, } }); } catch (error) { port.postMessage({ type: "result", id: message.data.id, data: { result: "error", error: { code: "unableToObtainToken", message: error.message } } }); } break; case "close": // in the base of popup this is triggered by a user request to close the window await close(command); break; case "pick": try { await pick(command); // let the picker know that the pick command was handled (required) port.postMessage({ type: "result", id: message.data.id, data: { result: "success" } }); } catch (error) { port.postMessage({ type: "result", id: message.data.id, data: { result: "error", error: { code: "unusableItem", message: error.message } } }); } break; default: // Always send a reply, if if that reply is that the command is not supported. port.postMessage({ type: "result", id: message.data.id, data: { result: "error", error: { code: "unsupportedCommand", message: command.command } } }); break; } break; } } </code></pre> <h2 id="get-token">Get Token</h2> <p>The control requires that we are able to provide it with authentication tokens based on the sent command. To do so we create a method that takes a command and returns a token as shown below. We are using the <code>@azure/msal-browser</code> package to handle the authentication work.</p> <blockquote> <p>Currently the control relies on SharePoint tokens and not Graph, so you will need to ensure your resource is correct and you cannot reuse tokens for Graph calls.</p> </blockquote> <pre><code class="lang-TS">import { PublicClientApplication, Configuration, SilentRequest } from "@azure/msal-browser"; import { combine } from "@pnp/core"; import { IAuthenticateCommand } from "./types"; const app = new PublicClientApplication(msalParams); async function getToken(command: IAuthenticateCommand): Promise<string> { let accessToken = ""; const authParams = { scopes: [`${combine(command.resource, ".default")}`] }; try { // see if we have already the idtoken saved const resp = await app.acquireTokenSilent(authParams!); accessToken = resp.accessToken; } catch (e) { // per examples we fall back to popup const resp = await app.loginPopup(authParams!); app.setActiveAccount(resp.account); if (resp.idToken) { const resp2 = await app.acquireTokenSilent(authParams!); accessToken = resp2.accessToken; } else { // throw the error that brought us here throw e; } } return accessToken; } </code></pre> <h2 id="picked-item-results">Picked Item Results</h2> <p>When an item is selected the picker will return, through the messaging channel, an array of selected items. While there is a set of information that may be returned the following is always guaranteed to be included:</p> <pre><code class="lang-TS">{ "id": string, "parentReference": { "driveId": string }, "@sharePoint.endpoint": string } </code></pre> <p>Using this you can construct a URL to make a GET request to get any information you need about the selected file. It would generally be of the form:</p> <pre><code>@sharePoint.endpoint + /drives/ + parentReference.driveId + /items/ + id </code></pre> <p>You will need to include a valid token with appropriate rights to read the file in the request.</p> <h2 id="uploading-files">Uploading Files</h2> <p>If you grant <code>Files.ReadWrite.All</code> permissions to the application you are using for picker tokens a widget in the top menu will appear allowing you to upload files and folders to the OneDrive or SharePoint document library. No other configuration changes are required, this behavior is controlled by the application + user permissions. Note, that if the user does not have access to the location to upload, the picker will not show the option.</p> <h2 id="branding-guidance">Branding Guidance</h2> <p>Applications that integrate with the Microsoft OneDrive File Picker may also opt to promote their integration with OneDrive to customers. Because OneDrive has both a consumer and commercial offering, the following options are available to display in 3rd party application interfaces:</p> <ul> <li>Microsoft OneDrive (personal) <ul> <li>May also be displayed as Microsoft OneDrive for personal</li> </ul> </li> <li>Microsoft OneDrive (work/school) <ul> <li>May also be displayed as Microsoft OneDrive for work or school</li> </ul> </li> </ul> <!-- { "type": "#page.annotation", "description": "SDKs to make integrating with OneDrive easy.", "keywords": "sdk,windows,ios,android,js,javascript,C#,c-sharp,java,objective-c,python", "section": "sdks", "tocPath": "OneDrive SDKs", "tocBookmarks": { "OneDrive SDKs/Client libraries": "#microsoft-graph-sdks-and-sample-code", "OneDrive SDKs/File pickers": "#file-picker-sdks" } } --> </div><div id="ms--inline-notifications" class="margin-block-xs" data-bi-name="inline-notification"></div><div id="assertive-live-region" role="alert" aria-live="assertive" class="visually-hidden" aria-relevant="additions" aria-atomic="true"></div> <div id="polite-live-region" role="status" aria-live="polite" class="visually-hidden" aria-relevant="additions" aria-atomic="true"></div> <!-- </content> --> </main><!-- recommendations section --><!-- end recommendations section --> <!-- feedback section --><!-- end feedback section --> <!-- feedback report section --><!-- end feedback report section --><aside id="ms--additional-resources-mobile" aria-label="Additional resources" class="display-none-desktop display-none-print" > <hr class="hr" hidden /> <h2 id="ms--additional-resources-mobile-heading" class="title is-3" hidden>Additional resources</h2> <section id="right-rail-recommendations-mobile" data-bi-name="recommendations" hidden></section> <section id="right-rail-training-mobile" data-bi-name="learning-resources-card" hidden></section> <section id="right-rail-events-mobile" data-bi-name="events-card" hidden></section> <section id="right-rail-qna-mobile" data-bi-name="qna-link-card" hidden></section> </aside><div class="border-top is-visible-interactive has-default-focus margin-top-sm "><footer id="footer-interactive" data-bi-name="footer" class="footer-layout"><div class="display-flex gap-xs flex-wrap-wrap is-full-height padding-right-lg-desktop"><a data-mscc-ic="false" class="locale-selector-link button button-sm button-clear flex-shrink-0" href="#" data-bi-name="select-locale"> <span class="icon" aria-hidden="true"> <span class="docon docon-world"></span> </span> <span class="local-selector-link-text"></span></a><div class="ccpa-privacy-link" data-ccpa-privacy-link hidden> <a href="https://aka.ms/yourcaliforniaprivacychoices" class="button button-sm button-clear flex-shrink-0" data-mscc-ic="false" data-bi-name="your-privacy-choices" > <svg role="img" aria-label="California Consumer Privacy Act (CCPA) Opt-Out Icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 14" xml:space="preserve" height="16" width="43" focusable="false" > <title>California Consumer Privacy Act (CCPA) Opt-Out Icon</title> <path d="M7.4 12.8h6.8l3.1-11.6H7.4C4.2 1.2 1.6 3.8 1.6 7s2.6 5.8 5.8 5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#fff"></path> <path d="M22.6 0H7.4c-3.9 0-7 3.1-7 7s3.1 7 7 7h15.2c3.9 0 7-3.1 7-7s-3.2-7-7-7zm-21 7c0-3.2 2.6-5.8 5.8-5.8h9.9l-3.1 11.6H7.4c-3.2 0-5.8-2.6-5.8-5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#06f"></path> <path d="M24.6 4c.2.2.2.6 0 .8L22.5 7l2.2 2.2c.2.2.2.6 0 .8-.2.2-.6.2-.8 0l-2.2-2.2-2.2 2.2c-.2.2-.6.2-.8 0-.2-.2-.2-.6 0-.8L20.8 7l-2.2-2.2c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0l2.2 2.2L23.8 4c.2-.2.6-.2.8 0z" style="fill:#fff"></path> <path d="M12.7 4.1c.2.2.3.6.1.8L8.6 9.8c-.1.1-.2.2-.3.2-.2.1-.5.1-.7-.1L5.4 7.7c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0L8 8.6l3.8-4.5c.2-.2.6-.2.9 0z" style="fill:#06f"></path> </svg> <span>Your Privacy Choices</span> </a> </div> <div class="flex-shrink-0"> <div class="dropdown has-caret-up"> <button class="dropdown-trigger button button-clear button-sm has-inner-focus theme-dropdown-trigger" aria-controls="theme-menu-interactive" aria-expanded="false" title="Theme" data-bi-name="theme"> <span class="icon"> <span class="docon docon-sun" aria-hidden="true"></span> </span> <span>Theme</span> <span class="icon expanded-indicator" aria-hidden="true"> <span class="docon docon-chevron-down-light"></span> </span> </button> <div class="dropdown-menu" id="theme-menu-interactive" role="menu"> <ul class="theme-selector padding-xxs" role="none"> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="light"> <span class="theme-light margin-right-xxs"> <span class="theme-selector-icon border display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Light</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="dark"> <span class="theme-dark margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Dark</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="high-contrast"> <span class="theme-high-contrast margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>High contrast</span> </button> </li> </ul> </div> </div> </div> </div> <ul class="links" data-bi-name="footerlinks"> <li class="manage-cookies-holder" hidden></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/previous-versions/" data-bi-name="archivelink">Previous Versions</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="https://techcommunity.microsoft.com/t5/microsoft-learn-blog/bg-p/MicrosoftLearnBlog" data-bi-name="bloglink">Blog</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/contribute/" data-bi-name="contributorGuide">Contribute</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://go.microsoft.com/fwlink/?LinkId=521839" data-bi-name="privacy">Privacy</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/legal/termsofuse" data-bi-name="termsofuse">Terms of Use</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://www.microsoft.com/legal/intellectualproperty/Trademarks/" data-bi-name="trademarks">Trademarks</a></li><li>© Microsoft 2024</li> </ul> </footer></div></div><div id="ms--additional-resources" class="right-container column is-4-desktop display-none display-block-desktop" data-bi-name="pageactions" role="complementary" aria-label="Additional resources" > <div id="affixed-right-container" class="margin-top-sm-tablet" data-bi-name="right-column"> <h2 id="ms--additional-resources-heading" class="title is-6 margin-top-md" hidden>Additional resources</h2> <section id="right-rail-events" data-bi-name="events-card" hidden></section> <section id="right-rail-training" data-bi-name="learning-resources-card" hidden></section> <section id="right-rail-recommendations" data-bi-name="recommendations" hidden></section> <nav id="side-doc-outline" class="doc-outline" data-bi-name="intopic toc" aria-label="In this article"> <h3>In this article</h3> </nav> <section id="right-rail-qna" class="margin-top-xxs" data-bi-name="qna-link-card" hidden></section> </div> </div></div> <!--end of div.columns --> </section> <!--end of .primary-holder --> <!-- interactive container --> <aside id="interactive-container" class="interactive-container is-visible-interactive column has-body-background-dark "> </aside> <!-- end of interactive container --> </div> </div> <!--end of .mainContainer --> <section class="border-top has-default-focus is-hidden-interactive margin-top-sm "><footer id="footer" data-bi-name="footer" class="footer-layout uhf-container has-padding" role="contentinfo"><div class="display-flex gap-xs flex-wrap-wrap is-full-height padding-right-lg-desktop"><a data-mscc-ic="false" class="locale-selector-link button button-sm button-clear flex-shrink-0" href="#" data-bi-name="select-locale"> <span class="icon" aria-hidden="true"> <span class="docon docon-world"></span> </span> <span class="local-selector-link-text"></span></a><div class="ccpa-privacy-link" data-ccpa-privacy-link hidden> <a href="https://aka.ms/yourcaliforniaprivacychoices" class="button button-sm button-clear flex-shrink-0" data-mscc-ic="false" data-bi-name="your-privacy-choices" > <svg role="img" aria-label="California Consumer Privacy Act (CCPA) Opt-Out Icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 14" xml:space="preserve" height="16" width="43" focusable="false" > <title>California Consumer Privacy Act (CCPA) Opt-Out Icon</title> <path d="M7.4 12.8h6.8l3.1-11.6H7.4C4.2 1.2 1.6 3.8 1.6 7s2.6 5.8 5.8 5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#fff"></path> <path d="M22.6 0H7.4c-3.9 0-7 3.1-7 7s3.1 7 7 7h15.2c3.9 0 7-3.1 7-7s-3.2-7-7-7zm-21 7c0-3.2 2.6-5.8 5.8-5.8h9.9l-3.1 11.6H7.4c-3.2 0-5.8-2.6-5.8-5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#06f"></path> <path d="M24.6 4c.2.2.2.6 0 .8L22.5 7l2.2 2.2c.2.2.2.6 0 .8-.2.2-.6.2-.8 0l-2.2-2.2-2.2 2.2c-.2.2-.6.2-.8 0-.2-.2-.2-.6 0-.8L20.8 7l-2.2-2.2c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0l2.2 2.2L23.8 4c.2-.2.6-.2.8 0z" style="fill:#fff"></path> <path d="M12.7 4.1c.2.2.3.6.1.8L8.6 9.8c-.1.1-.2.2-.3.2-.2.1-.5.1-.7-.1L5.4 7.7c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0L8 8.6l3.8-4.5c.2-.2.6-.2.9 0z" style="fill:#06f"></path> </svg> <span>Your Privacy Choices</span> </a> </div> <div class="flex-shrink-0"> <div class="dropdown has-caret-up"> <button class="dropdown-trigger button button-clear button-sm has-inner-focus theme-dropdown-trigger" aria-controls="theme-menu" aria-expanded="false" title="Theme" data-bi-name="theme"> <span class="icon"> <span class="docon docon-sun" aria-hidden="true"></span> </span> <span>Theme</span> <span class="icon expanded-indicator" aria-hidden="true"> <span class="docon docon-chevron-down-light"></span> </span> </button> <div class="dropdown-menu" id="theme-menu" role="menu"> <ul class="theme-selector padding-xxs" role="none"> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="light"> <span class="theme-light margin-right-xxs"> <span class="theme-selector-icon border display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Light</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="dark"> <span class="theme-dark margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Dark</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="high-contrast"> <span class="theme-high-contrast margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>High contrast</span> </button> </li> </ul> </div> </div> </div> </div> <ul class="links" data-bi-name="footerlinks"> <li class="manage-cookies-holder" hidden></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/previous-versions/" data-bi-name="archivelink">Previous Versions</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="https://techcommunity.microsoft.com/t5/microsoft-learn-blog/bg-p/MicrosoftLearnBlog" data-bi-name="bloglink">Blog</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/contribute/" data-bi-name="contributorGuide">Contribute</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://go.microsoft.com/fwlink/?LinkId=521839" data-bi-name="privacy">Privacy</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/legal/termsofuse" data-bi-name="termsofuse">Terms of Use</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://www.microsoft.com/legal/intellectualproperty/Trademarks/" data-bi-name="trademarks">Trademarks</a></li><li>© Microsoft 2024</li> </ul> </footer> </section> <div id="action-panel" role="region" aria-label="Action Panel" class="action-panel has-default-focus" tabindex="-1"></div> </body> </html>