Don’t worry, the HTML web resources for model-driven are not deprecated. I just don’t believe that I will ever make new ones again.
But there is that old problem of ClientGlobalContext deprecation. The ClientGlobalContext is an aspx site which we used to include in every HTML web resource in order to get access to information specific to the client, organization or user. Without that the HTML web resources are almost useless, because they are like ripped apart from the application.
The deprecation of the ClientGlobalContext was announced a long time ago, but the deadline was postponed already a few times. The current deadline is on April 1st, 2022. We should get a workaround this December. Let’s wait and see.

If you read the deprecation announcements, you have the feeling that the noose gradually tightens. A HTML web resource should now get access to the context using parent.Xrm.Utility.getGlobalContext, but on the other side, in the list with the client API deprecations also the parent.Xrm is listed as deprecated. There is a note that we can still use parent.Xrm from inside HTML web resources, but also that the parent.Xrm will be removed after the removal of the ClientGlobalContext.js.aspx. Very confusing.
For HTML web resources placed on form, there is still the workaround to pass the context using form scripting: getContentWindow
control.getContentWindow()
.then((contentWindow) => contentWindow.passContext(Xrm, formContext) )
Honestly, I’ve never took that seriously. I have developed a lot of generic HTML web resources; passing the context from the form, would mean to have a supplementary JavaScript resource for each form using it, only because I need to pass the context. Not very sure how safe this approach would be (the controls get unloaded sometimes).
Anyway, for HTML web resources outside the form there doesn’t seem to exist a good solution. Until now.
PCFs are the building bricks for the future
A lot of functionality we used to develop with HTML web resources, can be now made with PCFs. PCFs are way better because they are really integrated in the platform. We don’t need to hack accessing the form context, we get it provided by the platform. HTML web resources were just like “get your Iframe to play in your sandbox”, while PCFs are the real puzzle pieces you can mix and match to create the big picture.
PCF: Integrated in the platform
If it’s a field PCF we get the values, can change them if needed and pass them back to the framework runtime. We don’t need to save them in separate requests but have them saved together with the other columns. It’s “all or nothing”. It feels clean, not like the tricks we needed to do with HTML web resources.
If it’s a dataset PCF, we get the records provided by the platform, but we are free to add more columns or filter conditions to the dataset; we can select the records for the interaction with the ribbon or can navigate to the forms. Also the maker can choose on which data it applies.
PCF: Generic and configurable
The PCFs are by design generical. For a field PCF, the developer designs only the parameter types (when needed); the maker decides on which field it will be used. For a dataset PCF, the maker decides on which table/collection should be applied. Besides that, the PCF definition allows some other parameters/configurations from a list of options, which gives the maker a bigger flexibility.
The HTML web resources were usually not that generic or easy to be used for other tables. The generic ones needed some external configuration (placed in other JSON web resource/environment variable or even dedicated tables). The need to jump to an external web resource was not the best user experience for the maker, but the worst were the options (usually JSON properties) you needed to know to define the JSON.
Sometimes we needed to configure some fetchXMLs, sometimes with template allowing to inject some more filters or relations. I really hope the age of defining fetchXmls like this is over. No more obscure configurations. The maker can rely on a clear definition of PCFs using the build-in customizing experience.
Will the PCF cover everything HTML web resources used to?
We have only two types of PCFs: field and dataset. Do we need more? Some HTML web resources were very complex, sometimes being some kind of applications embeeded inside the model-driven apps.
Well, we can always use a dummy field and bind there a PCF where we are free to design whatever is needed. We can even define a PCF to expand the whole tab using Single-Component Tabs. But there were a still a few places where the PCFs were not the answer until now :
- in the home/sitemap area
- dialogs
- configuration pages for solutions
Custom Pages to the rescue
Custom Pages is a preview feature, which allows us to use the power of canvas apps inside model-driven apps. We can mix and match elements that we know from canvas apps together with model-driven elements. CustomPages can also work with components: both canvas components and code components (PCF)
Using Custom Pages, I’m pretty sure we can resolve all the problems the HTML web resources used to do in the past. But Custom Pages are much more! They let the maker combine the puzzle pieces using low-code. They add a huge flexibility to the big picture. For some requirements we’ll need to think using a new approach and split the HTML web resources in smaller pieces. Instead of designing a huge HTML-area, let’s split it in fields and collections/datasets and combine them using low-code inside Custom Pages.
PCFs inside Custom Pages: the best of both worlds
The PCFs work inside the Custom Pages the same as they work in Canvas Apps. We can combine bound fields together with datasets, that’s something wouldn’t be possible inside a form.
But Canvas Apps had some restrictions for PCFs: for instance, there we couldn’t use the “features” like WebAPI, Utility or Device. In Custom Pages we have these features too. And since the Custom Pages can use the Connectors just like Canvas Apps, we are able to let the PCFs be applied to a lot of datasources. We couldn’t do that in model-driven apps until now.
Inside Custom Pages we not necessarily need code components (PCFs). We could use canvas components too. The PCFs bring full power where the canvas components reach the limits or become hard to maintain. And there is another difference which we should consider when we make the design: we can use PCFs both inside Custom Pages and forms & views & subgrid, while the canvas components can only be used inside Custom Page.
The use-cases where HTML web resources couldn’t be replaced with PCFs until now
1. Home Navigation
Let’s see an example. I have a PCF for a dataset, showing the records in a calendar. Let’s think to a Delivery Calendar PCF, designed for a company who needs to make deliveries, and would like to see the orders in a calendar. If the delivery was made, we show the record for that delivery date, otherwise it will be shown for the date of the expected delivery. All the other column from the view will be shown in a HoverCard/extended tooltip.

The user can choose to see the records in a month view, week view or work week, and in the same time can interact with the ribbon:

It works also as a subgrid, if the user wants to see the deliveries for a single customer/account:

But the real power comes when the calendar is used inside a Custom Page: on select of an order, we can show data from related tables and also a gallery with the contained products. It opens so many possibilities.

The most important is that it’s not packed in a HTML web resource which is a “black box” for the maker. The only code component is the calendar, while the rest can be changed using low code. If the requirement changes, there won’t be a long development process to rewrite some code.
2. Dialogs
Thanks to the Custom Pages, we don’t need to create HTML web resources to show dialogs. Using the Xrm.Navigation.navigateTo with the pagetype=custom we can open Custom Pages as dialogs. Here is a blog about how to create dialogs with Custom Pages
3. Configuration page for solution
In case you are an ISV and the solution developed allows some configuration, you can use the solution configuration page. That’s a little tricky, because for now we can only choose a HTML web resource:

But what if the HTML web resource is just a host who redirects to a Custom Page?
<html>
<head>
<title>CustomPage loader</title>
<script>
window.onload = () => {
window.location.replace("../main.aspx?appname=diana_DeliverCalendarNoSiteMap&pagetype=custom&name=diana_deliverycalendarsolconfigpage_cdad6");
}
</script>
</head>
<body>
</body>
</head>
Well, the problem is that the CustomPage is shown together with the whole navigation area.


It works but it’s not really nice. Mehdi El Amri posted a blog about how to show the Custom Page without the navigation area: https://xrmtricks.com/2021/09/21/how-to-display-a-power-apps-canvas-application-in-full-screen-without-the-title-bar/. This inspired me to use the same possibility for config pages. I’m not so sure if it’s supported for now (Custom Pages are in preview too), but it let’s me hope that the possibilities will be opened some day.
First we need to create a new model-driven app inside the solution, and there create the Custom Page which will be the configuration page for the solution:



According to Mehdi’s blog, I just need to set the app to be opened without navigation area:
fetch(window.origin + "/api/data/v9.1/SaveSettingValue()", {
method: "POST",
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
AppUniqueName: "diana_DeliverCalendarNoSiteMap",
SettingName: "HideNavbar",
Value: "true"
})
}).then(console.log).catch(console.error)
The next step is to publish the app, and have a look to the result inside the solution configuration page:


It’s of course not perfect, since we’ve created an app only for the administration reasons, but only the admin needs the app so it shouldn’t be such a big deal.
I suppose that we will get more clean possibilities in the future, but I’m glad there is a way to use low-code to design the configuration page. Sometimes that page gets complex, depending on the settings, and using pure HTML web resource , requires a big effort. Now we don’t need it anymore.
Conclusion
The PCFs are the base of every construction we’ll make in Power Apps, and the Custom Pages are a game changer in model-driven apps. Of course, not everything is settled and clean right now. It’s just the beginning. But I see the big picture, I see a lot of possibilities where we can mix and match the pieces we need, so we can start thinking in components. The time of big “black boxes” is going to an end. I don’t think I’ll do HTML web resources ever again. Will you?
Photo by Ketut Subiyanto from Pexels
Deprecation of ClientGlobalContext and Xrm namespace is most terrible decision that can be imagined. I have created many applications that the PCF/Custom Pages functionality would not cope with. Microsoft is taking a step back, as it was with interface version 9.0. Managers don’t need tools like canvas app because they are too complex for managers. Developers don’t need these tools because they don’t allow you to do what the business needs. When it became possible to create web resources that are applications on React or Angular, it became possible to satisfy any desire of the customer.
I’ll have to wait and see if I’ll meet a requirement that is not possible to implement using all the current and upcomming possibilites: PCF, CustomPages, new Commanding, side panes, glued using PowerFx or not,
I think the PCFs should be able to replace any Webresource made, because is basically a place where you can include any React/Angular application (if you want to).
I understand the deprecation of clientGlobalContext, because it’s an aspx, which wouldn’t work offline; but the biggest problem is the time-horizon. There are so many HTMLWebResources out there, which will take a long time to be replaced. I guess we’ll have to wait and see, what is the workaround recommandation which is still to come.