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.JSXView on GitHub ↗ (pinned to 8a468df065)
Solutions
- 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.
- Rename the entry file to a standard extension, or add a mediaTypes/suffixes config entry mapping your extension to a script media type.
- 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
- Pass only JS/TS/JSX/TSX resources to js.Build — give source files proper extensions so Hugo infers the right media type
- If serving unusual extensions, register them under a supported media type in your config
- Don't pipe CSS/JSON resources through js.Build; use the appropriate pipe (css.Sass, resources.Minify) instead
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
- inject: absolute paths not supported, must be relative to /a
- inject: file %q not found
- invalid engine version: %q
- unsupported target: %v
- invalid loader: %q
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/63aa131d562270f1.json.
Report an issue: GitHub ↗.