What it does
Virtual files stored as records in Dataverse and served over a URL — HTML, JavaScript, CSS, XML, images, XSL and RESX. They're solution components, so they export and import with everything else, and they're how client script gets onto a form in the first place.
Key facts
- The Learn page states there are 10 file formats, then lists 12 rows in its own table, including SVG (type 11) and RESX (type 12). The table is the useful part; the count in the prose hasn't kept up.
- No web resource type can execute server-side code. They're static files, or files the browser processes. Anything server-side is a plugin.
- Access is through the Dataverse security context. Only licensed users with the right privileges can retrieve them.
- Maximum upload size is governed by
Organization.MaxUploadFileSize, set on the Email tab of System Settings. The default is 5 MB, and the same setting caps email attachments and notes. - Only references using the
$webresource:directive create solution dependencies. References between web resources don't, and neither do relative URLs. - The full URL form includes a version token that updates when you publish customisations. That token is what busts the browser cache — which is exactly why you should use the
$webresource:directive, a relative path, orXrm.Navigation.openWebResourcerather than a hand-built absolute URL. - Don't use
/WebResources/<name>as a root-relative path. It resolves against the user's default organisation, which produces a File Not Found for users working in a different one. - Neither web resources nor PCF support iframing content that sits behind an authentication boundary. Embedding a form inside an iframe on another form isn't supported — use the form component control for that.
When to use / skip
Script web resources are still the only way to attach JavaScript to model-driven form and grid events, so that use isn't going anywhere. CSS, image and RESX resources remain the sensible home for shared assets. Where they've been superseded is UI: Microsoft's own steer is to use PCF code components and custom pages for anything configurable, reusable or integrated with an external system, because those render in the same context rather than in an iframe. An HTML web resource doing a job a custom page could do is technical debt you're choosing.
Configuration decisions
- The naming convention, and whether it simulates a folder structure with the publisher prefix as the virtual root — relative references depend on it.
- Whether references use
$webresource:and therefore create dependencies, or relative paths and therefore don't. - Which assets belong in web resources versus somewhere with a CDN, given the upload size cap and the Dataverse security context.
- Whether the client edits text-based resources in the application or only through source control and a pipeline. Both are possible; only one is maintainable.
- Whether the caching behaviour is acceptable, since resources only refresh when customisations are published.
Gotchas
- Build an absolute URL by hand and you lose the version token, which means users get a cached copy of an old file. On large files that's a visible performance problem as well as a correctness one.
- Nothing stops you referencing a web resource without creating a dependency. The solution then exports cleanly and breaks in the target environment.
- The 5 MB default upload limit catches image and library uploads, and the setting lives somewhere nobody expects — the Email tab of System Settings.
- HTML web resources render in an iframe. Anything requiring authentication to a third party inside that iframe is unsupported, and where it appears to work in a browser it will fail on mobile and tablet.
- Silverlight (XAP) is still listed as a type. It is not a suggestion.
Consultant notes
- When you find HTML web resources in an inherited environment, work out what they do before you cost anything. They're usually the oldest and least documented code in the org.
- Migrating HTML web resources to custom pages or PCF is a good story for a modernisation phase, but only where they're genuinely UI. Script libraries should stay script libraries.
- Publishing is the cache boundary. If a client reports "the fix didn't take effect", ask whether customisations were published before you look at anything else.
- Keep web resources in source control and deploy them through the pipeline. Editing JavaScript in the browser is possible, which is precisely the problem.
Flag the 10-versus-12 file type discrepancy on the Learn page if it's ever corrected, and revisit if the upload limit default changes.