resources.GetRemote returns nil pointer, but renders temporary file in `with` block, suspect bad MediaType handling?

I want this simple case of arbitrary file download/Publish to work, but sadly get a nil pointer dereference and the Copy fails:

{{ $jxl_wasm := resources.Get  "https://cdn.jsdelivr.net/gh/niutech/jxl.js/jxl_dec.wasm" | resources.Copy "wasm/jxl_dec.wasm" }}
{{ $jxl_wasm.Publish }}

I’m trying to use GetRemote to download/install 3rd party wasm and am getting a nil pointer return value assigned to my variable in the simple case. Within a with block, the context contains the temporary file that I can manipulate. It seems to me there is an issue with the simple case and error handling that I suspect is related to mediaType handling.

I duplicated the wasm mime type that exists in output format mediatypes (why are inputs and outputs not the same default list?) to hugos mediaTypes. This appears to have resolved the mimeType detection where the discussed solutions about passing a (dict "mediaType" "application/wasm") to GetRemote doesn’t seem to work.

Environment:
Alpine Linux 3.18
hugo v0.112.3+extended linux/amd64 BuildDate=unknown

Potentially related issues:

Potentially related documentation:

Server reports content type correctly:
curl -v https://cdn.jsdelivr.net/gh/niutech/jxl.js/jxl_dec.wasm 2>&1 >/dev/null | grep ' content-type:'

< content-type: application/wasm

Local OS reports content type correctly:
mimetype public/js/jxl_dec.wasm:

application/wasm

Hugo relevant configuration:

mediaTypes:
  application/wasm:
    suffixes:
      - wasm

params:
  cdn:
    base: "https://cdn.jsdelivr.net"
    jxl:
      loader: "https://cdn.jsdelivr.net/gh/niutech/jxl.js/jxl.min.js"
      decoder: "https://cdn.jsdelivr.net/gh/niutech/jxl.js/jxl_dec.js"
      wasm: "https://cdn.jsdelivr.net/gh/niutech/jxl.js/jxl_dec.wasm"

HTML head partial attempting to load the data:

<head>
<!--
// Render local js to final js
{{
	$jxl_loader := resources.Get "js/jxl.js"
		| resources.Copy "js/jxl.js"
}}

// Render remote js to final js
{{
	$jxl_decoder := resources.GetRemote .Site.Params.cdn.jxl.decoder
		| resources.Copy "js/jxl_dec.js"
}}

// Throws an error that the returned object is null
// Render remote wasm to final wasm
{
	$jxl_wasm := resources.Get .Site.Params.cdn.jxl.wasm
		| resources.Copy "wasm/jxl_dec.wasm"
}}

// Error handling is required to get a non-null reference that can be published
{{ with resources.GetRemote .Site.Params.cdn.jxl.wasm | resources.Copy "js/jxl_dec.wasm" }}
	{{ .Publish }}
{{ end }}

// Rendering the local tmp to the final copy works here
{{ $jxl_loader.Publish }}
{{ $jxl_decoder.Publish }}

// Trying to maintain the same semantics as javascript for wasm fails
{ $jxl_wasm.Publish }}
-->
</head>

It looks like you’re using resources.Get where you should be using resources.GetRemote.

And see:
https://discourse.gohugo.io/t/hugo-v0-112-0-additional-media-types-with-resources-getremote/44538

Also, application/wasm is a built-in media type, so there’s no need to define this in your site configuration.

Of all my stupid coding mistakes.

Thank you kindly for pointing out the error of my ways!

I would refactor this whole thing.

site config

params:
  cdn:
    jxl:
      decoder:
        remoteURL: 'https://cdn.jsdelivr.net/gh/niutech/jxl.js/jxl_dec.js'
        localURL: js/jxl_dec.js
      loader:
        remoteURL: 'https://cdn.jsdelivr.net/gh/niutech/jxl.js/jxl.min.js'
        localURL: js/jxl.js
      wasm:
        remoteURL: 'https://cdn.jsdelivr.net/gh/niutech/jxl.js/jxl_dec.wasm'
        localURL: wasm/jxl_dec.wasm

template

{{ range site.Params.cdn.jxl }}
  {{ $remoteURL := .remoteURL }}
  {{ $localURL := .localURL }}
  {{ with resources.GetRemote $remoteURL }}
    {{ with .Err }}
      {{ errorf "%s" . }}
    {{ else }}
      {{ with resources.Copy $localURL . }}
        {{ .Publish }}
      {{ end }}
    {{ end }}
  {{ else }}
    {{ errorf "Unable to get remote resource %q" $remoteURL }}
  {{ end }}
{{ end }}

rendered

public/
β”œβ”€β”€ js/
β”‚   β”œβ”€β”€ jxl_dec.js
β”‚   └── jxl.js
β”œβ”€β”€ posts/
β”‚   β”œβ”€β”€ post-1/
β”‚   β”‚   └── index.html
β”‚   └── index.html
β”œβ”€β”€ wasm/
β”‚   └── jxl_dec.wasm
β”œβ”€β”€ favicon.ico
└── index.html

Is there any way to have one-liner the getremote/publish?
{{ resources.GetRemote https://google.com | resources.Copy "tmp/junk.html" | .Publish }}

Not if you want to do error checking. Not doing any error checking would be a Very Bad Idea.

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.