question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JavaScript Collocation TagHelper

See original GitHub issue

This is in reference to a .NET 6 feature known as JavaScript collocation. https://docs.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/?view=aspnetcore-6.0#load-a-script-from-an-external-javascript-file-js-collocated-with-a-component

I wanted to submit a PR but noticed you are multi-targeting .NET 3.1 and .NET 4.7.1 with this package. Seeing that JavaScript collocation is part of .NET 6 I’m not sure what to do. In any case, I’ve included the code below in the chance you’d like to add it to your library.

using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.FileProviders;

public class ViewScriptTagHelper : TagHelper
{
    private readonly IWebHostEnvironment environment;
    private readonly IFileVersionProvider fileVersionProvider;
    private const string AppendVersionAttributeName = "append-version";

    public ViewScriptTagHelper(IWebHostEnvironment environment, IFileVersionProvider fileVersionProvider)
    {
        this.environment = environment;
        this.fileVersionProvider = fileVersionProvider;
    }

    [ViewContext] 
    public ViewContext? ViewContext { get; set; }
    
    /// <summary>
    /// Value indicating if file version should be appended to src urls.
    /// </summary>
    /// <remarks>
    /// A query string "v" with the encoded content of the file is added.
    /// </remarks>
    [HtmlAttributeName(AppendVersionAttributeName)]
    public bool? AppendVersion { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        // remove the `page-script` tag if script doesn't exist
        output.TagName = null;
        output.TagMode = TagMode.StartTagAndEndTag;

        var viewPath = ViewContext?.View.Path;
        var src = $"{viewPath}.js";
        
        /* When the app is published, the framework automatically moves the script to the web root.
           So we should check both places, with the content root first for development */
        var exists = environment.ContentRootFileProvider.GetFileInfo(src).Exists ||
                   environment.WebRootFileProvider.GetFileInfo(src).Exists;

        if (exists)
        {
            // switch it to script now
            output.TagName = "script";
            output.Content = new DefaultTagHelperContent();
            
            if (AppendVersion == true)
            {
                // people love their cache busting versions
                src = fileVersionProvider.AddFileVersionToPath(src, src);
            }
            
            output.Attributes.Add("src", src);
        }
    }
}

Usage

Add the following to the end of your _Layout.cshtml file.

<view-script append-version="true" />

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:15 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
khalidabuhakmehcommented, Aug 29, 2022

I’ve updated the code above for brave souls who don’t read below the big fancy code blocks.

2reactions
AlexZeitlercommented, Aug 26, 2022

I’m facing the same issue like @kfrancis. Tag works in dev but no script tag rendered in prod.

The problem is caused by this line:

    var fileInfo = environment.ContentRootFileProvider.GetFileInfo(src) ??
                   environment.WebRootFileProvider.GetFileInfo(src);

environment.ContentRootFileProvider.GetFileInfo(src) never becomes null hence fileInfo.Exists() will be false in prod.

environment.WebRootFileProvider.GetFileInfo(src).Exists() is true in prod as expected.

This works both in dev and prod:

    var exists = environment.ContentRootFileProvider.GetFileInfo(src).Exists ||
                   environment.WebRootFileProvider.GetFileInfo(src).Exists;

    if (exists)
Read more comments on GitHub >

github_iconTop Results From Across the Web

ASP.NET Core JavaScript Collocated TagHelper
An asp.net core tag helper to reference collocated javascript files automatically.
Read more >
Inlining a Stylesheet, a JavaScript, or an image file using ...
Let's see how to create this tag helper! First, we need a common class for all the tag helpers to handle the loading...
Read more >
Tag Helpers in ASP.NET Core
Learn what Tag Helpers are and how to use them in ASP.NET Core.
Read more >
How to create a custom Tag Helper for razor performed ...
1 Answer 1 ... The tag helper only exists server-side. It will be rewritten into some other HTML tag when the response is...
Read more >
How Tag Helpers for JavaScript and CSS Files Work with ASP ...
Next: https://youtu.be/0GZk0Z3Pb_Q ++++++++++ (Unit Testing Blazor ASP.NET 5) In this lecture, I have explained the Tag Helpers for ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found