# A “script” element with a “src” attribute must not have a “type” attribute whose value is anything other than the empty string, a JavaScript MIME type, or “module”.

> Canonical HTML version: https://rocketvalidator.com/html-validation/a-script-element-with-a-src-attribute-must-not-have-a-type-attribute-whose-value-is-anything-other-than-the-empty-string-a-javascript-mime-type-or-module
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The `<script>` element serves two distinct purposes in HTML: loading executable scripts and embedding non-executable data blocks. When the `src` attribute is present, the element is always being used to load an external script, so the `type` attribute must reflect a valid script type. Setting `type` to something like `"text/html"`, `"text/plain"`, or an invented value like `"wrong"` tells the browser this is not JavaScript, which means the external file referenced by `src` will be fetched but never executed — almost certainly not what the author intended.

The HTML specification restricts the allowed `type` values for `<script src="...">` to three categories:

- **An empty string** (`type=""`): Treated the same as the default, which is JavaScript.
- **A JavaScript MIME type**: This includes `text/javascript`, `application/javascript`, and other legacy JavaScript MIME types. Since `text/javascript` is the default, specifying it is redundant.
- **`module`**: Indicates the script should be treated as a JavaScript module, enabling `import`/`export` syntax and deferred execution by default.

Any value outside these categories — such as `text/html`, `application/json`, or a made-up string — is invalid when `src` is present.

### Why this matters

**Broken functionality:** A non-JavaScript `type` on a `<script>` with `src` prevents the browser from executing the loaded file. The script is effectively dead code that still costs a network request.

**Standards compliance:** The HTML living standard explicitly forbids this combination. Validators flag it because it almost always indicates a mistake — either the wrong `type` was applied, or the `src` attribute was added by accident.

**Maintainability:** Future developers reading the code may be confused about whether the script is supposed to execute or serve as an inert data block. Keeping markup valid makes intent clear.

### How to fix it

1. **Remove the `type` attribute entirely.** This is the best approach for classic JavaScript. The default behavior is `text/javascript`, so no `type` is needed.
2. **Use `type="module"`** if the script uses ES module syntax (`import`/`export`).
3. **If you intended a data block** (e.g., embedding JSON or a template), remove the `src` attribute and place the content inline inside the `<script>` element instead. Data blocks with non-JavaScript types cannot use `src`.

## Examples

### Invalid: non-JavaScript types with `src`

These all trigger the validation error because the `type` value is not a JavaScript MIME type, an empty string, or `"module"`:

```html
<script type="text/html" src="template.html"></script>

<script type="application/json" src="data.json"></script>

<script type="text/plain" src="app.js"></script>

<script type="wrong" src="app.js"></script>
```

### Valid: omitting the `type` attribute

The simplest and recommended fix for classic scripts — just drop `type`:

```html
<script src="app.js"></script>
```

### Valid: using a JavaScript MIME type

This is valid but redundant, since `text/javascript` is already the default. The validator may suggest omitting it:

```html
<script type="text/javascript" src="app.js"></script>
```

### Valid: using `type="module"`

Use this when the external script uses ES module syntax:

```html
<script type="module" src="app.js"></script>
```

### Valid: using an empty `type` attribute

An empty string is treated as the default. It's valid but unnecessary, and the validator may suggest removing it:

```html
<script type="" src="app.js"></script>
```

### Valid: data blocks without `src`

If you need a non-JavaScript `type` for an inline data block, remove the `src` attribute and place the content directly inside the element:

```html
<script type="application/json" id="config">
  {
    "apiUrl": "https://example.com/api",
    "debug": false
  }
</script>
```
