Failed to load module script

The browser asked for your app’s JavaScript and got an HTML page back, so it refused to run it and the page stayed blank.

Browser console
Failed to load module script: Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.

Also appears as

  • Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.
  • Loading module from “https://my-app.com/assets/index-B7xk2Lq9.js” was blocked because of a disallowed MIME type (“text/html”).

Prompt to fix it

After deploying, my app shows a blank page and the console says "Failed to load module script: Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of text/html". Find out why the built JavaScript URL returns HTML. Check base in vite.config, the host’s build command and output directory, rewrite rules, and any custom server’s static file setup. Set base to the absolute path the app is served from (avoid "./" with client-side routes) and make sure the fallback to index.html never answers for real files under /assets. Don’t hand-edit MIME types to force it.

Paste into Layerwise or any AI coding tool.

What it means

Vite builds your app into an index.html plus JavaScript files in assets/, loaded with <script type="module">. Browsers only run module scripts that the server labels as JavaScript. This error says the server labeled the file text/html: an HTML page arrived where JavaScript should be, usually a 404 page or your own index.html.

So the real question is why the script’s URL doesn’t point to a real file. Open the failed request in the Network tab. If its response is your app’s HTML, the path is wrong and a single-page app fallback answered in place of the missing file.

A common trap is base: './' in vite.config.ts. Relative paths work on the home page, but on a deep link like /dashboard/settings the browser asks for /dashboard/assets/index.js, which doesn’t exist. Apps with client-side routes need an absolute base, such as '/'.

Common causes

  • The app is served from a subfolder, such as GitHub Pages at /my-repo/, but was built with the default base of /.
  • base is set to ./, so asset paths break on nested routes.
  • The host publishes the wrong folder, such as the project root instead of dist, so the page requests the unbuilt /src/main.tsx.
  • A new deploy replaced the hashed files, and a cached index.html or an open tab still asks for the old ones.
  • A custom server’s catch-all route returns index.html for every path, including /assets/*.

How to fix it

  1. Open DevTools → Network, reload, and click the failed .js request. Note its full URL and check the Response tab.
  2. Compare that URL with the files in your build’s dist/assets folder.
  3. Set base in vite.config.ts to the path the app lives at: / for a domain root, /my-repo/ for a GitHub Pages project site. Rebuild and redeploy.
  4. Check the host’s settings: the build command should be npm run build and the output directory dist.
  5. On a custom server, register static files before the catch-all, for example app.use(express.static('dist')) above the route that returns index.html.
  6. For tabs left open across a deploy, listen for Vite’s vite:preloadError event and reload the page.

Example fix

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  // The absolute path the app is served from.
  // Use '/my-repo/' for a GitHub Pages project site.
  base: '/'
});
All errors
TypeError: Failed to fetch dynamically imported module: https://my-app.com/assets/Settings-B7x2kQ9d.js

Failed to fetch dynamically imported module

The browser asked for a piece of your app that no longer exists, usually because a new deploy replaced it while the page was open.

404: NOT_FOUND This page doesn’t exist It may have been moved, removed, or never existed. 404 NOT_FOUND sfo1::ntg68-1793091406762-e6fdeff1eb27

404 on page refresh

Your single-page app works from the home page, but the host has no file for deeper URLs, so reloads and shared links hit a 404.

SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON

Unexpected token '<', "<!DOCTYPE "... is not valid JSON

Your code expected JSON, but the server sent back an HTML page, usually a 404 page or your app’s own index.html.

[plugin:vite:import-analysis] Failed to resolve import "./components/Header" from "src/App.tsx". Does the file exist?

Failed to resolve import

Vite couldn’t find the file or package an import points to, so it can’t serve or build the page until the import matches something real.

Build with an agent that checks its work

The Layerwise agent clicks through the live preview and reads the console, so it catches errors before you do.