resources.Concat fails when mixing resources.Get and resources.GetRemote - MIME type error

I’m trying to concat a bunch of JavaScript resources from local and remote sources but am encountering a MIME type error e.g.:

{{- $js_remote_script := resources.GetRemote "https://my_cdn.com/remote.js" }}
{{- $js_local_script := resources.Get "js/local.js" }}
{{- $js_bundle := (slice $js_remote_script $js_local_script) | resources.Concat "/js/js_bundle.js" | minify }}

<script src="{{ $js_bundle.Permalink }}"></script>

My build (Hugo 0.92.1) fails with:

 error calling Concat: resources in Concat must be of the same Media Type, got "application/javascript" and "text/plain"

How do I get resources.Get or resources.Concat to recognise the js/local.js file as application/javascript MIME type instead of text/plain?

Looks like the remote js has the text/plain MIME, not the local js. You can try this (not tested):

{{- $js_local_script := resources.Get "js/local.js" }}
++{{- $js_remote_script := resources.GetRemote "https://my_cdn.com/remote.js" | resources.FromString "my-remote.js" }}
{{- $js_bundle := (slice $js_local_script $js_remote_script) | resources.Concat "/js/js_bundle.js" | minify }}

<script src="{{ $js_bundle.Permalink }}"></script>

Sorry I typed the resources in the wrong order. Will still try the resources.FromString

Thank you.

EDIT: resources.FromString doesn’t seem to solve the problem.

Operating system?

Ubuntu 20.04 - The build is inside a GitHub action runner

Please do this:

touch temp.jsm
mimetype temp.jsm

What’s it say?

inode/x-empty

cat /usr/share/mime/globs2 | grep javascript
50:application/javascript:*.jsm
50:application/javascript:*.mjs
50:application/javascript:*.js

Looks correct right?

Bingo.

This is a Hugo bug. The first two extensions are not internally associated with application/javascript. I’ll log it and submit a fix. I cannot think of a work-around at the moment.

Thank you for you help.

The files I’m fetching via resources.Get are regular *.js extension files that are giving the wrong Media Type text/plain. Could this bug be the cause of that error?

Yes.

With resources.GetRemote we do not blindly trust the content.

We perform some background checks, looking at the response header from the server, the file extension, and fingerprinting the file itself. Part of this depends on the MIME database on the system where Hugo is running. In this case, when we queried your system, the first extension for “application/javascript” is .jsm, and Hugo currently doesn’t recognize that as a valid extension for JS files.

Note that the user can configure its own mime type.

Please explain.

I’ve got a work-around.

Install the “hugo extended” snap package. The snap has an older version (Ubuntu 18.04?) of the mime database. Make sure the known limitations of the snap package aren’t going to be a problem for you.

sudo snap install hugo --channel=extended/stable

And another work-around. Per bep’s suggestion, in your site configuration:

[mediaTypes]
[mediaTypes."application/javascript"]
suffixes = ["js","jsm","mjs"]

Follow these:
https://github.com/gohugoio/hugo/issues/9483
https://github.com/gohugoio/hugo/pull/9484

2 Likes

I would not use the term work-around, as that sounds a little like a hack. I do agree that Hugo should have these configured by default, but we’re not going to ever have all the media types etc. in the world configured, which is why this can be added/modified via end user configuration.

I agree, but in this case a user would have no idea what to add. I had to debug to figure out which extension it was picking up, and from where. I think Go’s idea of loading MIME type databases from the local system is a bit sketchy.

Sure, and we could/should improve that error message.

Thank both for helping to resolve this. Much appreciated.