When you think of Power Automate, workflows, and automation probably come to mind. But did you know that Power Automate can also serve as a hosting platform for your Single Page Applications (SPA)? In this blog, I’ll walk you through how to build a modern SPA using HTML, CSS, and Power Automate to create a practical, interactive, and sleek user interface—all while storing data in a SharePoint List.
Why Use Power Automate for SPAs?
Hosting SPAs via Power Automate may sound unconventional, but it opens up new possibilities.
- Simplified Hosting: You don’t need an external web server to host your SPA—just embed it within Power Automate pages.
- Powerful Backend Integration: Seamlessly connect your app with SharePoint Lists, SQL databases, or any other Microsoft 365 services.
- Custom Workflows: Build workflows behind the scenes to automate actions triggered from your SPA.
- Cost-Efficiency: Utilize your existing Power Platform license for app hosting.
Use Case. SharePoint Site Creation Request SPA
Features of the SPA
For this guide, we’ll build an SPA to handle SharePoint Site Creation Requests.
- A responsive UI designed with HTML, CSS, and Bootstrap.
- A Dark Mode Toggle to improve user experience.
- A form to collect input data (e.g., site name, site type, purpose, owner name, and visibility) and store it directly in a SharePoint List using a Power Automate Flow.
Step-by-Step Guide
What are We going to do?
We will create two separate Power Automate flows to handle the SPA.
- Flow 1: Hosts the SPA page. This will embed the HTML, CSS, and JavaScript for the form UI and provide the front-end interface to the users.
- Flow 2: Handles data entry. When users submit the form, this flow will capture the submitted data and save it to the SharePoint List.
This separation ensures that the hosting flow only focuses on rendering the application while the second flow is dedicated to back-end data processing.
Prepare the SharePoint List
First, create a SharePoint List to store the data from the form. Here’s an example structure.
Column Name |
Type |
Site Name |
Single line of text |
Site Type |
Choice (Team, Communication) |
Business Purpose |
Multiple lines of text |
Primary Owner Name |
Single line of text |
Site Visibility |
Choice (Public, Private) |
Flow 1. Hosting the SPA
Step 1. Create an Instant Flow.
- Go to Power Automate and create a new Instant Flow with the trigger When an HTTP request is received.
- In the HTTP trigger, obtain the HTTP GET URL, which will serve as your SPA’s hosting URL.
- The URL will be generated once you save the flow. So just add compose with test text and save the flow.
- Initialize a variable to store the second flow’s URL (e.g., https://example.com). This will later be updated to the actual URL of the second flow.
Step 2. Add the HTML Code.
Use a Compose action to write your SPA code, including HTML, CSS, JS, and Bootstrap for styling. Here’s an example of the structure.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SharePoint Site Request</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css">
<link rel="icon" type="image/x-icon" href="https://cdn.icon-icons.com/icons2/3053/PNG/512/microsoft_sharepoint_alt_macos_bigsur_icon_189964.png">
<style>
:root {
--bg-dark: #2c2738;
--bg-light: #f8f9fa;
--card-dark: #2a2a40;
--card-light: #ffffff;
--text-dark: #fff;
--text-light: #212529;
--input-bg-dark: #fdfdfd;
--input-bg-light: #e9ecef;
--input-border-dark: #5b5b75;
--input-border-light: #ced4da;
--btn-primary-dark: #6c63ff;
--btn-primary-light: #6c63ff;
--btn-primary-hover-dark: #574be5;
--btn-primary-hover-light: #574be5;
}
body {
background-color: var(--bg-dark);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
color: var(--text-dark);
transition: all 0.3s;
}
.container {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
padding: 0 15px;
}
.form-wrapper {
display: flex;
max-width: 950px;
width: 100%;
background-color: var(--card-dark);
border-radius: 12px;
overflow: hidden;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25);
transition: background-color 0.3s;
}
.form-left {
background-image: url('https://7107021.fs1.hubspotusercontent-na1.net/hubfs/7107021/SharePoint-Logo.wine%20copia.png');
background-size: 50pc;
background-position: 50%;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 30px;
}
.form-left h1 {
font-size: 2.5rem;
color: var(--text-dark);
}
.form-left p {
font-size: 1rem;
color: #d1d1e0;
}
.form-right {
flex: 1;
padding: 40px;
background-color: var(--card-dark);
transition: background-color 0.3s;
}
.form-right h2 {
font-size: 1.8rem;
margin-bottom: 20px;
}
.form-control {
border: 1px solid var(--input-border-dark);
background-color: var(--input-bg-dark);
color: var(--text-dark);
border-radius: 8px;
margin-bottom: 15px;
transition: all 0.3s;
}
.form-control:focus {
border-color: var(--btn-primary-dark);
box-shadow: 0 0 8px rgba(108, 99, 255, 0.5);
}
.form-select {
border-radius: 8px;
}
.btn-submit {
background-color: var(--btn-primary-dark);
color: var(--text-dark);
padding: 12px;
font-size: 1rem;
font-weight: 500;
border: none;
border-radius: 8px;
width: 100%;
transition: background-color 0.3s;
}
.btn-submit:hover {
background-color: var(--btn-primary-hover-dark);
}
.form-footer {
text-align: center;
color: #d1d1e0;
font-size: 0.9rem;
margin-top: 15px;
}
.alert {
border-radius: 8px;
}
.dark-mode-toggle {
position: fixed;
top: 20px;
right: 20px;
display: flex;
align-items: center;
gap: 5px;
}
</style>
</head>
<body>
<div class="dark-mode-toggle">
<label class="form-check-label" for="darkModeSwitch">Dark Mode</label>
<input class="form-check-input" type="checkbox" id="darkModeSwitch" checked>
</div>
<div class="container">
<div class="form-wrapper">
<div class="form-left">
<h1>SharePoint Site Request</h1>
<p>Streamline your collaboration with ease. Submit your request for a SharePoint site effortlessly and track approvals.</p>
</div>
<div class="form-right">
<div id="alert-placeholder"></div>
<h2>Request Form</h2>
<form id="siteRequestForm">
<!-- Form Fields -->
</form>
<div class="form-footer">
Made with Power Automate | Powered by SharePoint
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
</body>
</html>
Step 3. Add a Response Action.
Use the Response action to return the composed HTML page as output.
Flow 2. Storing the Data
- Create another flow in Power Automate.
- Select When an HTTP request is received as the trigger.
- Add the Create Item action to add the form data to the SharePoint List.
- Also, update the HTTP POST URL from the second flow's trigger into the first flow's variable, which will trigger this flow when the user clicks on the submit button.
- The input JSON schema should match the form data.
{
"type": "object",
"properties": {
"siteName": {
"type": "string"
},
"siteType": {
"type": "string"
},
"businessPurpose": {
"type": "string"
},
"primaryOwner": {
"type": "string"
},
"siteVisibility": {
"type": "string"
}
}
}
Execution Photos
1. SPA Page Blank (Dark Mode - off).
In this, we can observe that we have hit the 'HTTP GET URL' of the first flow to execute and get the page.
2. SPA Page Blank (Dark Mode - on).
3. SPA Page Filled.
4. SPA Page request submitted.
5. SharePoint List Entry Created.
Conclusion
Using Power Automate to host SPAs unlocks incredible potential for merging lightweight apps with robust backend workflows. With a little creativity and some HTML/CSS skills, you can build powerful, user-friendly applications—all within the Power Platform ecosystem.
Feel free to experiment, and let me know about the amazing SPAs you create! If you’d like to explore more about this process, reach out or leave your thoughts below.
Happy building!