Power Pages on a personal Azure developer subscription gets expensive fast. Provisioning and maintaining a site eats your monthly credit before you've shipped anything interesting.
There's another way: replace the Power Pages layer with an Azure Static Web App, and keep everything else.
You still get Dataverse — its security model, its flexibility, its multi-user group setup. Just run your Power Platform environment in developer mode and you're not paying for the database tier either. When you need server-side logic, bolt on a Node.js Web App as the SWA's linked API.
A note on the frontend: I'll keep this minimal — vanilla JS, no framework. Bootstrap 5 for styling and basic interaction — simple, lightweight, no jQuery, and familiar to everyone. The point is to show the architecture, not to sell you on Angular or React.
What the demo will show
Three users, three roles — procurement, general employee, administrator — each landing on the same site and seeing a different experience. The HTML and JavaScript content lives in Dataverse tables behind column-level security and gets rendered dynamically based on the user's group membership. No hardcoded role checks in the frontend, no duplicated pages — Dataverse decides what each user can see, and the SWA just renders it.
Multiple data sets, one key. Several Dataverse tables — SAP master data, qualifications, contracts, categories — all joined on the SAP vendor ID. The frontend stitches them together at query time, same way a real procurement system does. All data mocked in Mockaroo, so the demo is fully reproducible.
Client-side filtering at scale. Metadata of 60,000 records loaded once, then filtered live in the browser across multiple criteria — no round trip to the server as the user narrows down. The server is only hit when the user opens a specific record. This is a breeze to build with vanilla JS — no library, no framework. Modern JavaScript gives you everything: Map, Set with native union/difference/intersection, reduce for aggregations, and the DOM for rendering. That's the whole stack.
State persistence across navigation. Open a record, hit back, and you land exactly where you were — same scroll position, same filters applied, same selection — standard SPA behaviour when user experience is in focus.
I'll also walk through a working login_hint implementation for SWA EasyAuth — the one that's been sitting open as an unresolved issue on the Azure SWA GitHub for two years. It's a small thing, but it noticeably improves the sign-in experience, and the workaround is worth documenting.
The two setups
- SWA + MSAL Browser + Dataverse — the minimal stack. Static frontend, browser-acquired tokens, Dataverse Web API directly.
- SWA + MSAL Browser + Azure Storage + Dataverse + Node.js API (native, no deps) — same foundation, plus blob storage for files and a Node.js backend for anything the browser can't (or shouldn't) do.