Connect OneDrive to Lovable by registering an Azure AD app, storing the client ID and secret in Lovable Cloud Secrets, and building a Supabase Edge Function that uses the Microsoft Graph API to proxy file operations server-side. OneDrive integrates with Microsoft 365 — the best choice when your users already work in Teams, SharePoint, or Office and need their Lovable app to access the same file ecosystem.
OneDrive Integration in Lovable: Microsoft 365 File Ecosystem
OneDrive is the cloud storage backbone of the Microsoft 365 ecosystem. When an organization uses Microsoft Teams for communication, SharePoint for document libraries, and Office for productivity, OneDrive is where all files live. For Lovable app developers building tools for organizations standardized on Microsoft 365, integrating with OneDrive means connecting to the files those organizations are already creating and managing daily.
The Microsoft Graph API is the unified gateway to all Microsoft 365 services, and it powers OneDrive integration. Through Graph, your Lovable app can list files, upload documents, generate download links, create shareable URLs, and navigate folder hierarchies — all with the same authentication model used across Teams, Outlook, Calendar, and other Microsoft services. If your roadmap ever includes reading Teams messages or Outlook email alongside file management, Graph's consistency means you learn one authentication pattern for all Microsoft services.
OneDrive's authentication uses Azure Active Directory (Azure AD), which gives it enterprise identity management features: conditional access policies, MFA enforcement, and audit logging through Azure. For organizations where IT controls application access (common in regulated industries, large enterprises, and government), Azure AD gives IT administrators fine-grained control over which apps can access which files — a governance advantage over consumer-focused storage APIs.
Integration method
OneDrive integrates with Lovable via a Supabase Edge Function that uses the Microsoft Graph API with Azure AD OAuth2 authentication. Register an Azure AD application to get a client ID and secret, store them in Lovable Cloud Secrets, and build an Edge Function that handles the OAuth2 client credentials flow to obtain access tokens and proxies all Graph API file operations server-side. The React frontend calls the Edge Function — never Microsoft Graph directly — keeping credentials secure.
Prerequisites
- An Azure account with access to the Azure Portal at portal.azure.com (a Microsoft 365 account or free Azure account works)
- An active Lovable project with Lovable Cloud/Supabase enabled
- Access to Lovable's Cloud tab → Secrets panel
- Basic understanding of OAuth2 authentication and API concepts
Step-by-step guide
Register an Azure AD application for Microsoft Graph API access
Register an Azure AD application for Microsoft Graph API access
All OneDrive API access requires an Azure Active Directory application registration. Go to portal.azure.com and sign in. In the search bar, type 'App registrations' and click the result. Click 'New registration'. Give the app a name (e.g., 'Lovable OneDrive Integration'), select 'Accounts in this organizational directory only' for single-tenant apps or 'Accounts in any organizational directory' for multi-tenant. For the redirect URI, select 'Web' and enter a placeholder URL for now (you can update this later if using delegated auth). Click Register. After registration, you land on the app's overview page. Note the Application (client) ID — this is your OAuth2 client ID. Also note the Directory (tenant) ID — this identifies your Azure AD tenant. These values are needed for authentication. Next, create a client secret. Go to Certificates & Secrets → New client secret. Enter a description ('Lovable production') and choose an expiry period (24 months is common — shorter is more secure, but requires rotation). Click Add. The secret value is shown only once — copy it immediately. This is your OAuth2 client secret. Finally, configure API permissions for OneDrive access. Go to API Permissions → Add a permission → Microsoft Graph. Choose Application permissions (for server-to-server access without user login). Add: Files.Read.All (for reading files), Files.ReadWrite.All (for reading and writing files), and Sites.Read.All (if you need SharePoint access). Click 'Grant admin consent for [your organization]' — this authorization step is required for Application permissions to work. Without it, all API calls return a 'Authorization_RequestDenied' error.
Pro tip: Application permissions (Files.ReadWrite.All) give the app access to ALL OneDrive content in the organization — use with care. For apps that should only access specific folders, use delegated permissions (which require user sign-in) or implement service account impersonation where the app acts as a specific limited user.
Expected result: You have an Azure AD app registration with: Application (client) ID, Directory (tenant) ID, client secret value, and Microsoft Graph Files.ReadWrite.All permission granted. Admin consent has been granted for the configured permissions.
Store Azure AD credentials in Lovable Cloud Secrets
Store Azure AD credentials in Lovable Cloud Secrets
Open your Lovable project's Cloud tab (click '+' next to Preview) and navigate to Secrets. Add the following credentials for Microsoft Graph access. Add AZURE_CLIENT_ID with your Application (client) ID from the Azure portal. Add AZURE_CLIENT_SECRET with the client secret value you copied. Add AZURE_TENANT_ID with your Directory (tenant) ID. Optionally add ONEDRIVE_USER_ID with the Microsoft user ID (or user principal name like user@organization.com) of the OneDrive account your app should access — this scopes the app to a specific user's OneDrive rather than searching across the entire organization. For each secret: click 'Add secret', enter the key name exactly as shown (case-sensitive), paste the value without surrounding whitespace, and save. These three values are all that is needed for the OAuth2 client credentials flow — the Edge Function uses them to obtain Microsoft Graph access tokens automatically. Client secrets in Azure AD expire after the period you chose (e.g., 24 months). When a secret expires, all API calls fail with authentication errors. Set a calendar reminder well before expiry to rotate the secret: generate a new client secret in Azure portal, update AZURE_CLIENT_SECRET in Lovable's Cloud Secrets, and the Edge Function will use the new secret on the next invocation. Lovable's encrypted secrets storage (SOC 2 Type II certified) ensures these credentials are protected at rest.
I've added AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID to Cloud Secrets, plus ONEDRIVE_USER_ID with the email address of the OneDrive account to access. Create a Supabase Edge Function called 'onedrive-api' that authenticates with Microsoft Graph using client credentials and handles OneDrive file operations.
Paste this in Lovable chat
Pro tip: The ONEDRIVE_USER_ID can be an email address (user@organization.com) or a Microsoft object ID (GUID). Using email addresses is more human-readable but Object IDs are more stable — if the user's email changes, the GUID remains constant. Find the Object ID in Azure Portal → Users → select user → Object ID.
Expected result: Four secrets are stored in Cloud Secrets: AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID, and ONEDRIVE_USER_ID. No credential values appear in any source code file.
Build the OneDrive Microsoft Graph Edge Function
Build the OneDrive Microsoft Graph Edge Function
The Edge Function authenticates with Azure AD using the OAuth2 client credentials flow and then makes Microsoft Graph API calls for OneDrive operations. The client credentials flow is straightforward: POST to Azure's token endpoint with the client ID, secret, and Graph scope, receiving a Bearer access token valid for 1 hour. Microsoft Graph API for OneDrive uses a consistent URL structure. For a specific user's OneDrive: https://graph.microsoft.com/v1.0/users/{userId}/drive/root for the root, https://graph.microsoft.com/v1.0/users/{userId}/drive/root:/{path}: for path-based access, and https://graph.microsoft.com/v1.0/users/{userId}/drive/items/{itemId} for ID-based access. The /children endpoint lists folder contents. The /content endpoint streams file contents. Graph API responses for drive items include rich metadata: name, size, lastModifiedDateTime, createdDateTime, file (for files, includes mimeType and hashes), folder (for folders, includes childCount), and @microsoft.graph.downloadUrl (a temporary pre-authenticated download URL). The downloadUrl is a direct download link that expires in a few minutes and works without any additional authorization headers — perfect for triggering browser downloads. For file uploads, Graph API accepts the file content as the request body with the Content-Type matching the file's MIME type. For files under 4 MB, use the simple upload endpoint: PUT to https://graph.microsoft.com/v1.0/users/{userId}/drive/root:/{path}/{filename}:/content. For larger files, use the resumable upload session (createUploadSession endpoint) which supports chunked uploads.
Create a Supabase Edge Function at supabase/functions/onedrive-api/index.ts. It should: 1) Get an Azure AD access token using client credentials (POST to https://login.microsoftonline.com/{AZURE_TENANT_ID}/oauth2/v2.0/token with client_id, client_secret, grant_type=client_credentials, scope=https://graph.microsoft.com/.default). 2) Use the token for Microsoft Graph API calls. 3) Handle these actions using ONEDRIVE_USER_ID from env: list-folder (list items at a given path, default root), get-download-url (return the @microsoft.graph.downloadUrl for a file by item ID), upload (upload base64 file to a given path), create-sharing-link (create a shareable link for an item), delete (delete by item ID). Include CORS headers and error handling.
Paste this in Lovable chat
1import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'23const GRAPH_BASE = 'https://graph.microsoft.com/v1.0'45const corsHeaders = {6 'Access-Control-Allow-Origin': '*',7 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',8 'Access-Control-Allow-Methods': 'POST, OPTIONS',9}1011async function getGraphToken(): Promise<string> {12 const tenantId = Deno.env.get('AZURE_TENANT_ID')!13 const clientId = Deno.env.get('AZURE_CLIENT_ID')!14 const clientSecret = Deno.env.get('AZURE_CLIENT_SECRET')!1516 const params = new URLSearchParams({17 grant_type: 'client_credentials',18 client_id: clientId,19 client_secret: clientSecret,20 scope: 'https://graph.microsoft.com/.default',21 })2223 const res = await fetch(24 `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,25 { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params }26 )27 const data = await res.json()28 if (!data.access_token) throw new Error(`Auth failed: ${data.error_description ?? JSON.stringify(data)}`)29 return data.access_token30}3132serve(async (req) => {33 if (req.method === 'OPTIONS') return new Response('ok', { headers: corsHeaders })3435 try {36 const token = await getGraphToken()37 const userId = Deno.env.get('ONEDRIVE_USER_ID')!38 const driveBase = `${GRAPH_BASE}/users/${userId}/drive`39 const authHeader = { Authorization: `Bearer ${token}` }4041 const { action, path, itemId, filename, content, contentType } = await req.json()4243 let result: unknown4445 if (action === 'list-folder') {46 const endpoint = path && path !== '/'47 ? `${driveBase}/root:/${encodeURIComponent(path)}:/children`48 : `${driveBase}/root/children`49 const res = await fetch(`${endpoint}?$select=id,name,size,file,folder,lastModifiedDateTime,@microsoft.graph.downloadUrl&$top=100`,50 { headers: authHeader })51 result = await res.json()5253 } else if (action === 'get-download-url') {54 const res = await fetch(55 `${driveBase}/items/${itemId}?$select=name,@microsoft.graph.downloadUrl`,56 { headers: authHeader }57 )58 const item = await res.json() as Record<string, unknown>59 result = { url: item['@microsoft.graph.downloadUrl'], name: item.name }6061 } else if (action === 'upload') {62 const bytes = Uint8Array.from(atob(content), c => c.charCodeAt(0))63 const uploadPath = path ? `${path}/${filename}` : filename64 const res = await fetch(65 `${driveBase}/root:/${encodeURIComponent(uploadPath)}:/content`,66 {67 method: 'PUT',68 headers: { ...authHeader, 'Content-Type': contentType || 'application/octet-stream' },69 body: bytes,70 }71 )72 result = await res.json()7374 } else if (action === 'create-sharing-link') {75 const res = await fetch(`${driveBase}/items/${itemId}/createLink`, {76 method: 'POST',77 headers: { ...authHeader, 'Content-Type': 'application/json' },78 body: JSON.stringify({ type: 'view', scope: 'anonymous' }),79 })80 result = await res.json()8182 } else if (action === 'delete') {83 await fetch(`${driveBase}/items/${itemId}`, { method: 'DELETE', headers: authHeader })84 result = { success: true }85 } else {86 throw new Error(`Unknown action: ${action}`)87 }8889 return new Response(JSON.stringify(result), {90 headers: { ...corsHeaders, 'Content-Type': 'application/json' },91 })92 } catch (err) {93 return new Response(94 JSON.stringify({ error: err instanceof Error ? err.message : 'Unknown error' }),95 { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }96 )97 }98})Pro tip: Microsoft Graph tokens from client credentials are valid for 1 hour. For efficiency in high-traffic apps, cache the token in a Supabase table (with the expiry timestamp) and reuse it across Edge Function invocations until it expires — this avoids a token request on every API call.
Expected result: The onedrive-api Edge Function is deployed and active. Test it with a list-folder action (path: '') to confirm it returns the root OneDrive folder contents including file names, sizes, and types.
Build the React OneDrive file browser UI
Build the React OneDrive file browser UI
With the Edge Function deployed, build the React file browser for OneDrive content. Microsoft Graph returns drive items in a consistent structure — each item has an id (unique item identifier), name, and either a file object (for files, containing mimeType) or folder object (for folders, containing childCount). Use these to distinguish files from folders and render appropriate icons. For folder navigation, maintain a path state string (e.g., '/Projects/Q1 Reports') and call the list-folder action with that path. Provide a breadcrumb component that shows the current path segments and allows clicking any ancestor to navigate back. Store the full path in state — OneDrive paths are human-readable strings unlike Box's numeric IDs. For file downloads, the @microsoft.graph.downloadUrl field in the list response provides an immediate download URL — no separate API call needed. However, this URL expires quickly (a few minutes). For a 'Download' button that triggers browser download, call the get-download-url action immediately when clicked and programmatically trigger the download: create a temporary anchor element, set href to the URL, and click it. For file uploads from the React component, read the File object as base64 using FileReader.readAsDataURL() (remove the data URL prefix), send it with the filename and content type to the Edge Function's upload action, and specify the current path as the destination folder. After upload, refresh the folder listing to show the new file. For SharePoint document libraries (different from personal OneDrive), the Graph API uses a slightly different path structure: /sites/{siteId}/drive/root instead of /users/{userId}/drive/root. If your users need to access shared SharePoint document libraries in addition to personal OneDrive files, RapidDev can help extend the Edge Function to support SharePoint site drives.
Build a OneDrive file browser component using the onedrive-api Edge Function. Features: 1) Start at the OneDrive root folder. List files and folders with icons (folder icon for folders, file icon based on extension for files). 2) Click a folder to navigate into it. Show a breadcrumb with the current path — clicking a breadcrumb segment navigates to that folder. 3) Each file row shows name, size (human-readable), last modified date, and a Download button. Clicking Download calls get-download-url and triggers a browser download. 4) An Upload Files button that accepts multiple files and uploads them to the current folder one at a time, showing a progress indicator. 5) Loading spinners during all operations. Error handling with toast notifications.
Paste this in Lovable chat
Pro tip: Microsoft Graph's $select query parameter reduces response payload size significantly. Always specify which fields you need: $select=id,name,size,file,folder,lastModifiedDateTime. Without $select, Graph returns 30+ fields per item including extended metadata your app does not need.
Expected result: A OneDrive file browser renders in your Lovable app. Folder navigation works with path-based routing and breadcrumbs. File downloads use temporary Graph API download URLs. Uploads send files to the correct OneDrive path and refresh the listing. All operations authenticate via Azure AD client credentials without user login.
Common use cases
Build a Microsoft 365 document portal for an organization's staff
Organizations using Microsoft 365 store operational documents in OneDrive and SharePoint. Build a Lovable app that surfaces specific OneDrive folders in a custom UI — project files, templates, reports — giving staff purpose-built navigation without requiring them to use OneDrive's generic interface for specialized workflows.
Build a document portal using the onedrive-api Edge Function. Show a folder browser starting from a configured OneDrive folder path. Users can navigate into subfolders, see files with their name, size, and last modified date, and download files by clicking a Download button that generates a temporary access URL. Add an upload button that sends files to the current folder. Show a loading state while operations are in progress.
Copy this prompt to try it in Lovable
Sync uploaded files to a Microsoft Teams-connected OneDrive folder
Teams channels have corresponding SharePoint folder libraries that sync to OneDrive. Building a Lovable app that uploads files to a Teams-connected OneDrive folder makes those files immediately visible in the Teams channel's Files tab. This bridges your custom Lovable workflow with the organization's existing Teams communication hub.
Create a file submission form in my Lovable app. When a user submits a file (PDF or image), upload it to our company's OneDrive folder at '/Projects/Submissions/{today's date}/' using the onedrive-api Edge Function. Create the date folder if it does not exist. Store the submission metadata (file name, submitter's name, upload timestamp, OneDrive item ID) in Supabase. Show a success confirmation with the file name after upload.
Copy this prompt to try it in Lovable
Build a template library from OneDrive documents
Many organizations maintain document templates (Word, PowerPoint, Excel) in a shared OneDrive folder. Build a Lovable app that lists available templates from OneDrive, lets users browse and preview them, and generates a download link for the user to open the template in Office. This replaces emailing templates or maintaining a separate template repository.
Build a template library that reads from a OneDrive templates folder via the onedrive-api Edge Function. Show templates grouped by category (the subfolder name). Each template card shows the file name, file type icon, size, and last modified date. A 'Use Template' button generates a download URL and opens it. Add a search box that filters templates by name. Cache the template list in Supabase for 30 minutes to reduce Graph API calls.
Copy this prompt to try it in Lovable
Troubleshooting
Edge Function returns 'Authorization_RequestDenied' or 'Insufficient privileges' from Microsoft Graph
Cause: The Azure AD app does not have admin consent granted for the configured API permissions. Application permissions (Files.ReadWrite.All) require explicit admin consent in the Azure portal — without it, all Graph API calls fail with authorization errors regardless of correct credentials.
Solution: Go to Azure Portal → App registrations → your app → API Permissions. Verify Files.ReadWrite.All (Application type) is listed. If there is a warning icon next to it, admin consent has not been granted. Click 'Grant admin consent for [your organization]'. If you do not have admin access, contact your Azure AD administrator and ask them to grant consent for your app registration's client ID.
Token request returns 'AADSTS700016: Application not found in directory'
Cause: The AZURE_TENANT_ID or AZURE_CLIENT_ID values are incorrect, or the app registration is in a different Azure AD tenant than the one specified in the token request URL.
Solution: Verify AZURE_TENANT_ID exactly matches the Directory (tenant) ID shown on the app registration's overview page in Azure Portal. Verify AZURE_CLIENT_ID matches the Application (client) ID on the same page. For multi-tenant apps, use 'common' as the tenant ID if your app should work across multiple Azure AD tenants.
File upload succeeds (Edge Function returns 201) but the file is not visible in OneDrive
Cause: The ONEDRIVE_USER_ID may point to a different user's OneDrive than expected, or the upload path uses characters that OneDrive encodes differently. Also occurs if the upload wrote to a subfolder path that does not exist (OneDrive creates missing folders in the path automatically for simple uploads, but may behave differently for nested paths).
Solution: Verify ONEDRIVE_USER_ID is the correct user's email or Object ID by testing the list-folder action first — if it returns the expected root folder contents, the user ID is correct. For path encoding issues, log the exact path being sent to Graph API in the Edge Function and verify it matches the expected OneDrive folder path. Check Cloud → Logs in Lovable to see Edge Function console output.
Best practices
- Always use $select in Microsoft Graph queries to request only the fields your app needs — Graph responses without $select include 30+ metadata fields that increase payload size and processing time.
- Request only the minimum necessary API permissions (Files.Read.All for read-only apps, Files.ReadWrite.All for read-write) — avoid Sites.FullControl.All or other over-broad permissions.
- Store the ONEDRIVE_USER_ID as a secret rather than hardcoding it — this makes it easier to switch which OneDrive account the app accesses without a code change.
- Implement token caching in Supabase: store the access token and expiry timestamp, reuse the cached token for up to 55 minutes (leaving a 5-minute buffer before the 1-hour expiry), and fetch a new token only when needed.
- Test with the Microsoft Graph Explorer (developer.microsoft.com/graph/graph-explorer) before writing Edge Function code — it lets you experiment with Graph API calls using your own credentials to verify the correct endpoint and response structure.
- Set calendar reminders for client secret expiry (typically 12-24 months) — expired client secrets cause all API calls to fail with authentication errors and can cause service outages if not rotated in advance.
- For production apps, add request retry logic to the Edge Function for transient Graph API failures — Microsoft Graph occasionally returns 503 Service Unavailable responses that succeed on retry.
Alternatives
Box offers broader compliance certifications (FedRAMP, HIPAA with BAA) and is not Microsoft-ecosystem-dependent — choose Box when compliance is the primary driver over Microsoft 365 integration.
Dropbox has a simpler API and is platform-agnostic — choose it for apps targeting users across multiple ecosystems rather than Microsoft 365 specifically.
AWS S3 is Lovable's native shared connector and is better for developer-focused raw object storage without the Microsoft 365 collaboration features.
Frequently asked questions
Does Lovable have a native OneDrive connector?
No, OneDrive is not one of Lovable's 17 official shared connectors. Integration requires building a custom Edge Function using the Microsoft Graph API as described in this guide. Lovable's native storage options are AWS S3 (shared connector) and Lovable Cloud Storage (built-in Supabase Storage).
Can my Lovable app access SharePoint document libraries in addition to OneDrive files?
Yes. The Microsoft Graph API provides access to both OneDrive (personal drives) and SharePoint document libraries through a similar API structure. SharePoint drives use /sites/{siteId}/drive/root instead of /users/{userId}/drive/root. You need to find your SharePoint site's siteId (obtainable via the Graph API at /sites?search=yoursite), then use the same Edge Function pattern with the site drive endpoint. Add Sites.Read.All permission to your Azure AD app registration for SharePoint access.
How does Azure AD client credentials differ from the OAuth2 flows used for Dropbox or Box?
Client credentials (used in this guide) is a server-to-server flow where your app authenticates directly to Microsoft as itself — no user is involved. The app gets a token representing the application's identity, not a user's identity. This is equivalent to Box's JWT service account approach. Dropbox uses OAuth2 authorization code (user-involved) for per-user access. The client credentials approach is simpler for organizational apps accessing shared content, but requires Application permissions with admin consent rather than Delegated permissions.
What is the difference between OneDrive Personal and OneDrive for Business for this integration?
OneDrive Personal (personal Microsoft accounts) and OneDrive for Business (Microsoft 365 organizational accounts) use different authentication endpoints. This guide uses Azure AD client credentials which works with OneDrive for Business organizational accounts. OneDrive Personal accounts use the Microsoft Account (MSA) authentication system, which requires different OAuth2 flow parameters. For most business Lovable apps, OneDrive for Business (the Microsoft 365 version) is the relevant target.
How do I let individual users in my Lovable app access their own OneDrive rather than a shared service account?
This requires delegated permissions and the OAuth2 authorization code flow. Users click 'Connect OneDrive', get redirected to Microsoft's sign-in page, authorize your Azure AD app, and return with an authorization code. The Edge Function exchanges this code for user-specific access and refresh tokens stored per-user in Supabase (with RLS). All subsequent Graph API calls are made on behalf of that user, accessing only their OneDrive content. This is more complex than the service account approach in this guide and requires Delegated permissions (Files.ReadWrite) instead of Application permissions. RapidDev can assist with implementing the full per-user OAuth2 flow.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation