Search code examples
dotnetnuke2sxc

Script Link in Header - EnableOptimizations Strips Attributes


Not sure if this is a bug or if 2sxc is doing this on purpose, "for reasons."

First, here is the goal. I am in a 2sxc App, in a View using Razor/C#. I need to get the following JS module linked up in the <head> like this:

<script src="//unpkg.com/@dnncommunity/dnn-elements/dist/dnn/dnn.esm.js" 
  type="module" async="async" defer="defer" crossorigin="anonymous">
</script>

Obviously if I just put it in as-is, it gets on the page, but not in the <head>.

If I add the attribute, data-enableoptimizations="true" then its in the <head> but all 4 of my attributes get stripped:

<script src="https://unpkg.com/@dnncommunity/dnn-elements/dist/dnn/dnn.esm.js" type="text/javascript"></script>

Additionally, notice that the src had only the leading "//unpkg...", and for some reason, the optimizations have added back "https:" which I do not want.

And where did type="text/javascript" come from? That hasn't been required for years.

I can solve this in the theme/skin by using the DnnJsInclude control like this. It uses ClientResourceManagement and allows me to specify all the attributes in HtmlAttributesAsString like this:

<dnn:DnnJsInclude
  FilePath="//unpkg.com/@dnncommunity/dnn-elements/dist/esm/dnn.js"
  ForceProvider="DnnPageHeaderProvider"
  HtmlAttributesAsString="type:module,async:async,defer:defer,crossorigin:anonymous" 
  Priority="1001"
  runat="server"
/>

This gets me the correct result, but it means my standard content editors now need the ability to edit page settings to use my 2sxc App. Which I do not want (the permissions or the training complication).

I realize I can probably use that DnnJsInclude control from my Razor code, but it seems like this is a valid use case that data-enableoptimizations should handle. Yes? No? Maybe? Maybe it already does it but I don't know the right syntax?

Anyone know how to get 2sxc to do this? Or is this a bug worth reporting regarding data-enableoptimizations? I was especially surprised that it just stripped my valid attributes.


Solution

  • Okay, so I worked it out in code using the DnnJsInclude control. Here is the solution in a nutshell:

    @using DotNetNuke.Web.Client.ClientResourceManagement
    
    @{
      // Add a <script> tag in the head as a JS module
      var include = new DnnJsInclude 
      {
        FilePath = "https://unpkg.com/@dnncommunity/dnn-elements/dist/dnn/dnn.esm.js", 
        ForceProvider = "DnnPageHeaderProvider",
        Priority = 1001, // stay out of the way?
        HtmlAttributesAsString = "type:module,async:async,defer:defer,crossorigin:anonymous",
      };
      var loader = (Context.CurrentHandler as Page).FindControl("ClientResourceIncludes");
      if (loader != null)
      {
        loader.Controls.Add(include);
      }  
    }
    

    Which gets the exact output needed thanks to the HtmlAttributesAsString parameter.

    I even wrote it up as a blog post with a lot of details.

    DNN Details 004: Using the New Dnn-Elements in a 2sxc View?

    Since this is dependent on Dnn, it doesn't benefit the Oqtane/hybrid coders.