Need help integrating a custom React 19 + Vite bundle into Django Admin

Hi everyone,

I am building a custom infrastructure and I want to replace the default Django Admin homepage (admin.site.index_template) with a custom dashboard written in React 19, Vite, and Bootstrap (with Chart.js metrics).

Here is my setup:

  • Backend: Django 6.0 + PostgreSQL
  • Frontend: React 19 + Vite + Bootstrap
  • Binding: I overrode dashboard.html in my admin templates and configured STATICFILES_DIRS to point to Vite’s build directory (../static/frontend/assets/).

The Problem:
Vite builds perfectly and generates index.js and index.css inside Django’s static folder. However, React fails to activate inside the Django Admin structure:

  1. If I load the script normally, the browser blocks execution with: “Uncaught SyntaxError: Cannot use import statement outside a module”.
  2. If I force type="module", the browser blocks it due to a MIME type mismatch (“MIME type ‘text/plain’ is not executable”).

It seems Django Admin rejects modern SPA script injection within its default blocks ({% block content %}).

What is the recommended middleware or staticfiles configuration to allow Django to correctly serve and execute an ESM Javascript bundle from React 19 inside the native Django Admin panel?

Thanks for your help!

From the errors you described, I don’t think the issue is with Django Admin itself. Django Admin doesn’t prevent ES modules from being loaded inside admin.site.index_template.

The two errors point to different problems:

  • “Cannot use import statement outside a module” means the bundle is being loaded without type="module".
  • “MIME type ‘text/plain’ is not executable” usually means Django is not serving the file as JavaScript (often because the URL is incorrect, the file isn’t being found, or the static files configuration is incorrect).

I would first verify that opening the bundle directly (for example /static/assets/index.js) returns:


Content-Type: application/javascript

and not text/plain or an HTML 404 page.

If you’re using Vite, I also recommend avoiding pointing STATICFILES_DIRS directly at the generated asset directory. Instead, let Vite build into a dist directory, expose that through Django’s staticfiles system (or WhiteNoise in production), and load the generated bundle with:


{% load static %}

<script type="module" src="{% static 'assets/index.js' %}"></script>

(or better, use Vite’s manifest.json to resolve hashed filenames automatically).

  • Finally, could you share:
    your vite.config.js,

    your STATIC_URL, STATICFILES_DIRS, and STATIC_ROOT settings,

    how you’re including the script in dashboard.html,

    and whether you’re running Django’s development server, WhiteNoise, or another web server?Those details will probably reveal the root cause.