Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

When a browser reports that a CSS or JavaScript file was served as text/html, the response it received was HTML rather than the requested asset. In a normal Nginx configuration, .css maps to text/css and .js maps to application/javascript. The error therefore usually means the request missed the real file: the effective root is wrong, the file is absent, another location handled the request, an SPA fallback returned index.html, or a proxied application sent an HTML page.

Fix the path and routing first, then verify the MIME table. Inspect the response body and headers, identify the selected location and effective root, make missing assets return a clear 404, and keep any client-side route fallback away from CSS and JavaScript URLs.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What the browser error actually tells you

The browser checks the HTTP Content-Type header before applying a stylesheet or executing a script. If the header says text/html, the browser has evidence that the response is an HTML document. That does not prove that your CSS or JavaScript file contains HTML. It proves that the URL returned something else.

The returned HTML might be your single-page application’s shell, an Nginx-generated error page, a login page, or an error document produced by an upstream application. A successful HTTP status does not make the response an asset: an SPA commonly returns 200 OK with index.html for unknown paths, including misspelled asset paths.

#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter | 4Pack Type C Female to A Male Cable Converter for Apple Duo 17 16 15 14 Plus,iWatch Watch 12 11 10,iPad 9 8 Air,Airpods 5 4
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
What you observe What it usually means Where to look
200, Content-Type: text/html, body is your app shell A fallback rewrote the asset request to index.html try_files, rewrite rules, and the general application location
404, HTML error body The file was not found under the selected root, or the upstream generated an HTML 404 Filesystem path, root, selected location, and proxy response
200, HTML login or error page An upstream server answered the asset URL with an application page proxy_pass, upstream routing, and authentication middleware
200, actual CSS or JavaScript body, wrong MIME type The file was found but Nginx did not load the expected extension mapping or a location overrode the default type mime.types, default_type, and location inheritance

Do not solve this by forcing every response to text/css or application/javascript. If the body is HTML, changing the header only hides the routing problem and leaves the browser trying to parse an HTML document as an asset.

How Nginx decides what to return

The selected location controls the processing path

Nginx first selects a location for the URI. One location may serve files directly; another may pass requests to an application with proxy_pass. A broad application location can therefore intercept a request that you expected to be handled by a static-file rule.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The effective root becomes the filesystem path

For static content, root supplies the directory and Nginx appends the request URI. A request for /assets/app.css under root /srv/www/site; makes Nginx look for /srv/www/site/assets/app.css. The root is inherited when a selected location does not redefine it. If a nested location sets another root, or if the intended root is declared only in a location that did not win the match, Nginx searches a different directory.

The MIME table is applied after a file is selected

Nginx’s standard MIME table includes the mappings text/css css; and application/javascript js;. The extension mapping matters only after Nginx has selected the file response. It cannot turn an HTML fallback into the missing stylesheet or script.

try_files can intentionally create the HTML response

try_files tests candidate paths under the effective root. If none exists, its last argument is used as an internal redirect or a status code. The common SPA pattern try_files $uri $uri/ /index.html; is useful for client-side routes, but it also makes a missing .css or .js request return the application shell unless assets are checked separately.

Diagnose the failing URL before editing configuration

1. Inspect the request in browser developer tools

  1. Open the browser’s Developer Tools and select the Network panel.
  2. Reload the page with the failing request visible. Select the CSS or JavaScript request, not the document request.
  3. Record the request URL, status, response headers, and response body. Confirm the exact Content-Type value and whether the body starts with HTML such as <!doctype html> or contains your application’s root element.
  4. Check whether the URL includes a build directory, hash, or base path that differs from the file’s location on disk.

2. Reproduce it outside the browser

Fetching headers alone can conceal the important clue. Request headers first, then fetch the body as well:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter | USB C Dongle with 90W Max Power Delivery, 3×5Gbps USB A Data Ports, for MacBook, Dell, and More (Charger Not Included)
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
curl -I http://127.0.0.1/assets/app.css
curl -i http://127.0.0.1/assets/app.css

The first command quickly shows status and Content-Type. The second lets you identify index.html, an error page, or an upstream login response. Repeat the test for a JavaScript URL; a configuration can route one extension correctly and another incorrectly.

3. Confirm the file and the path Nginx is supposed to use

Find the built asset in the deployment directory and compare its full path with the URI-to-root calculation. If the browser asks for /static/main.abc123.js, verify that the effective root contains static/main.abc123.js, including capitalization. A file in a source directory, a previous release directory, or a different build output directory is not available merely because it exists somewhere on the server.

4. View the effective configuration

Inspect the complete configuration, including included files, rather than only the file you normally edit:

nginx -T

In that output, identify the active server block, every matching location, the inherited or overridden root, any try_files fallback, and any proxy_pass. This often reveals that the request is reaching a different virtual host or a more specific location than expected.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

5. Check access and error logs

After reproducing the request, inspect the access log for the exact URI and status and the error log for file paths, internal redirects, or upstream failures. Logs are especially useful when the browser displays a generic MIME warning while Nginx has already recorded a missing file or a proxy connection problem.

Fix a site that serves files directly from Nginx

Load the standard MIME mappings

The MIME table must be included in the http context so the server can apply extension mappings:

Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter | 85W Max PD, 2 USB 3.0 & 1 USBC Data Ports, SD/TF Card Reader, for Laptops/Mac and Other Type C Devices (Charger Not Included)
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
http {
    include       mime.types;
    default_type  application/octet-stream;

    # server blocks...
}

The exact location of mime.types depends on the installation. Use the path already supplied by your Nginx package if it is not in the main configuration directory. A missing include can leave Nginx using its default type, but it does not explain an HTML body when the request has been redirected to index.html.

Put the intended root at server scope or repeat it in the asset location

Declare the build directory where it is inherited by the locations that need it:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
server {
    listen 80;
    server_name example.invalid;
    root /srv/www/site;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location ~* .(?:css|js)$ {
        try_files $uri =404;
    }
}

The example’s asset rule makes Nginx look under /srv/www/site and return a real 404 when the file is absent. The general location can still send known client-side routes to /index.html. Replace the root with the directory that actually contains the deployed build.

If the asset location has its own root, use the correct directory there as well:

server {
    root /srv/www/site;

    location ~* .(?:css|js)$ {
        root /srv/www/site;
        try_files $uri =404;
    }
}

Nginx maintainer Maxim Dounin notes that when a location with a different default_type is added, the root may need to be repeated or moved to the server context because the new location can otherwise use the wrong root. The same inheritance issue is a useful warning whenever a new location is introduced.

Use an explicit asset existence check

The essential behavior is try_files $uri =404; in the location that handles static assets. It tests the requested file and stops with a status response when the file does not exist. That prevents a missing bundle from being silently converted into HTML and gives deployment monitoring a meaningful failure.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray | Data transfer & Fast charging for MacBook, iPhone 17/16/15, iPad, Samsung Galaxy, Apple Watch
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft

Some sites keep images, fonts, maps, or other extensions in the same build directory. Add those extensions to the asset rule only when they are genuinely static files, and retain an explicit fallback policy for each class of request. Do not place the SPA fallback as the final argument in the CSS/JS rule itself.

Keep an SPA fallback from catching assets

Client-side routing needs a fallback because a route such as /settings/profile may not have a physical file. An asset URL has a different contract: it must resolve to the built asset or fail. Separate those behaviors by making the asset location perform an existence check and letting the broader application location handle routes.

server {
    root /srv/www/site;

    location ~* .(?:css|js)$ {
        try_files $uri =404;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

After changing this, request a deliberately nonexistent asset such as /assets/not-installed.css. It should return 404, not the HTML shell. Then request a real client-side route; it should still return the document needed by the router. This two-request check proves that the fallback is scoped correctly.

If your build emits assets under a prefix such as /build/ or /static/, ensure the generated HTML references that exact prefix and that the corresponding directory exists below the root. A correct fallback cannot repair a wrong public path embedded in the build.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fix a reverse-proxy configuration

When Nginx proxies the request, Nginx may not be selecting or reading a local asset at all. It forwards the upstream response, including an HTML body and its media type, unless you explicitly configure different handling. The upstream may return an HTML 404, a login page, an application shell, or another route because its own public path is wrong.

Identify the proxying location

In the effective configuration, look for the location matching the asset URI and its proxy_pass. Verify whether the proxy target includes a URI suffix; that suffix changes the path sent upstream. Compare the path Nginx receives with the path the application serves for the built file.

Best Value
Sale
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display | 85W Max PD, 1 Powered USB-C 5Gbps & 2 Powered USB-A 3.0 5Gbps Data Ports, for MacBook Pro, MacBook Air, Dell and More (Black)
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.

Test the upstream response separately

Request the asset directly from the upstream service, using the upstream’s listening address and port. Compare its status, Content-Type, and body with the public Nginx response. If the upstream already returns HTML, fix its static-file mount, public path, or route handling. If the upstream returns correct JavaScript but Nginx changes the result, inspect Nginx rewrites, locations, and header directives.

Do not mask an upstream error with a forced MIME type

An HTML login page labeled as JavaScript remains a login page. Preserve the upstream status and body while correcting the route that produced it. If static assets belong on the filesystem, a dedicated Nginx static location can serve them directly and leave the proxy location for application requests.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Understand default_type and extensionless files

Extension mapping and the default type are separate mechanisms. Maxim Dounin states: “MIME types are determinded by nginx according to file extensions. For files without extensions the default type is used.” The spelling in that quotation is his. For ordinary .css and .js files, a working MIME table supplies the extension mapping. For extensionless responses, Nginx uses default_type unless another directive determines the type.

Changing default_type is therefore appropriate only when you intentionally serve content without an extension or have a narrowly defined location with a known response type. It is not a substitute for correcting a wrong root, a missing file, an internal redirect, or an upstream HTML response.

Validate, reload, and verify the result

  1. Run the configuration test and stop if it reports an error:
    nginx -t
  2. Reload Nginx using the service method used by your operating system, for example:
    systemctl reload nginx
  3. Repeat the curl -i request for the real CSS and JavaScript URLs.
  4. Confirm that the status is the one you expect, the body contains CSS or JavaScript rather than HTML, and the header is text/css for CSS or application/javascript for JavaScript.
  5. Reload the page and check the browser’s Network panel again. If a service worker or browser cache still shows an old response, perform a controlled cache-bypassing reload while diagnosing; do not treat a cached response as proof that the server remains misconfigured.
  6. Watch the access and error logs while requesting a missing asset and a real asset. The missing request should fail at the intended layer, and the real request should map to the deployed file without an internal redirect to the document shell.

Choose the fix that matches your architecture

Architecture Primary check Correct behavior for a missing asset Typical fix
Static files served by Nginx Effective root and file existence Clear 404 Load mime.types, set the correct root, and use try_files $uri =404;
Static files plus SPA routes Asset location versus general route location Asset 404; client route receives index.html Keep the asset check separate from try_files $uri $uri/ /index.html;
Nginx reverse proxy Matching location, proxy_pass path, and upstream body Whatever the upstream’s asset contract specifies, but not an accidental HTML page Correct upstream static mounting or route mapping; use a direct static location when appropriate
Extensionless or custom responses default_type and location inheritance The deliberately configured media type Set default_type only in the narrow location that needs it and keep the correct root there

Common failure patterns and their precise corrections

The file exists, but Nginx still returns the app shell

Usually the file exists outside the effective root, or the requested URI does not match its deployed path. Recalculate the URI plus root, inspect nginx -T, and verify the selected location. Once the physical path is correct, an asset-specific try_files rule prevents future fallbacks.

Only JavaScript fails while CSS works

Check whether JavaScript is served from a different directory, proxy location, or build prefix. Also verify that the MIME table contains the .js mapping and that no JavaScript location overrides the root or default type. Test both files with curl -i; comparing their bodies often exposes a route difference faster than comparing browser warnings.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The status is 404 and the body is HTML

An HTML body is normal for many 404 responses. The important question is whether the 404 was generated by Nginx because the file is absent or by an upstream application. The response headers, access log, error log, and a direct upstream request distinguish those cases. Restore the file or correct the path rather than changing the MIME header.

The response is correct after a reload, then breaks on the next deployment

This indicates a deployment path or generated public URL mismatch rather than a MIME-table problem. Check that the new build is placed beneath the root before HTML references it, that hashed filenames are present, and that the fallback cannot hide missing files. A deployment that publishes the document before its assets can briefly produce the same symptom even with valid configuration.

A new location changed behavior unexpectedly

Locations can inherit or override settings such as root, default_type, and proxy directives. Compare the new block with the server-level settings and repeat critical values where the location must be self-contained. Then test a real and nonexistent asset after reloading.

Deployment checklist

  • The browser’s failing URL is copied exactly, including its path and filename.
  • The file exists beneath the effective Nginx root at the URI-derived path.
  • The selected location is the intended static or proxy location.
  • mime.types is included in the http context.
  • CSS and JavaScript asset locations use an explicit existence check rather than the SPA document fallback.
  • The general fallback is reserved for client-side routes that genuinely need index.html.
  • Proxy configurations have been checked at both Nginx and the upstream service.
  • nginx -t succeeds before reload.
  • After reload, real assets return their actual bodies and expected media types, while nonexistent assets return a deliberate 404.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.