gohugoio/hugo · error

unsupported Media Type: %q

Error message

unsupported Media Type: %q

What it means

When picking the loader for the entry-point resource, Hugo switches on the resource's media type: JavaScript, TypeScript, TSX, JSX, and CSS map to the corresponding esbuild loader. Any other media type (e.g. text/html, image/png) can't be a js.Build entry point, so option compilation fails naming the media type.

Source

Thrown at internal/js/esbuild/options.go:340

	mediaType := opts.MediaType
	if mediaType.IsZero() {
		mediaType = media.Builtin.JavascriptType
	}

	var loader api.Loader
	switch mediaType.SubType {
	case media.Builtin.JavascriptType.SubType:
		loader = api.LoaderJS
	case media.Builtin.TypeScriptType.SubType:
		loader = api.LoaderTS
	case media.Builtin.TSXType.SubType:
		loader = api.LoaderTSX
	case media.Builtin.JSXType.SubType:
		loader = api.LoaderJSX
	case media.Builtin.CSSType.SubType:
		loader = api.LoaderCSS
	default:
		err = fmt.Errorf("unsupported Media Type: %q", opts.MediaType)
		return
	}

	var format api.Format
	// One of: iife, cjs, esm
	switch opts.Format {
	case "", "iife":
		format = api.FormatIIFE
	case "esm":
		format = api.FormatESModule
	case "cjs":
		format = api.FormatCommonJS
	default:
		err = fmt.Errorf("unsupported script output format: %q", opts.Format)
		return
	}

	var jsx api.JSX

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Only pass script or CSS resources to js.Build — the entry point must be .js/.jsx/.ts/.tsx (or CSS for the CSS pipeline); import JSON from within your JS instead of building it directly.
  2. Rename the entry file to a standard extension, or add a mediaTypes/suffixes config entry mapping your extension to a script media type.
  3. If the source is templated, run resources.ExecuteAsTemplate to produce a .js resource before js.Build.

Example fix

{{/* before */}}
{{ $bundle := resources.Get "data/config.json" | js.Build }}
{{/* after: import the JSON from the JS entry point */}}
{{ $bundle := resources.Get "js/main.js" | js.Build }}
// main.js
import config from '../data/config.json';
Defensive patterns

Strategy: validation

Validate before calling

switch mediaType {
case "text/javascript", "text/typescript", "text/tsx", "text/jsx":
    // ok
default:
    return fmt.Errorf("js.Build cannot process media type %q", mediaType)
}

Prevention

When it happens

Trigger: Piping a resource whose media type isn't JS/TS/TSX/JSX/CSS into `js.Build`, e.g. `resources.Get "data.json" | js.Build` or a file whose extension Hugo maps to an unknown/plain-text media type.

Common situations: Passing the wrong resource variable into js.Build; entry files with nonstandard extensions (.mjs/.cjs on older Hugo versions, or custom extensions) that don't resolve to a script media type; templated (.js.tmpl) sources not executed with resources.ExecuteAsTemplate first.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/63aa131d562270f1.json. Report an issue: GitHub ↗.