title: How to correctly serve my React production build through Django. Currently having MIME type issues with current configuration
body: <p>I'm trying to deploy my react/django web-app to a linux-VM droplet. I'm not using a webpack for the JS content. Instead, I'm serving <code>npm run build</code> static files through a CDN sub-domain, digital ocean s3 bucket.</p>
  <p>I'm able to <code>python manage.py collectstatic</code> which then pushes my react production build folder to the CDN.</p>
  <p>When I visit my production website, it currently just loads up a blank page with these console errors:</p>
  <pre><code>Refused to apply style from 'https://www.my_website_URL.com/static/css/main.ce8d6426.chunk.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
  
  Refused to execute script from 'https://www.my_website_URL.com/static/js/2.ca12ac54.chunk.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
  
  Refused to execute script from 'https://www.my_website_URL.com/static/js/main.220624ac.chunk.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
  </code></pre>
  <p>There aren't any network errors that provide any useful information for this matter.</p>
  <p>The issue has to be server side (django)... I think.</p>
  <hr />
  <p><strong>Project set up:</strong></p>
  <p><a href="https://i.stack.imgur.com/03M7X.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/03M7X.png" alt="enter image description here" /></a></p>
  <p>The react production build is inside my core django folder.</p>
  <p>Here is how I link my React through django:</p>
  <p><code>core urls.py</code></p>
  <pre><code>def render_react(request):
      return render(request, &quot;index.html&quot;) 
      #index.html being created by react, not django templates 
      
  urlpatterns = [
     re_path(r&quot;^$&quot;, render_react),
     re_path(r&quot;^(?:.*)/?$&quot;, render_react),
     ...
  ]
  </code></pre>
  <p><strong>index.html</strong></p>
  <pre class="lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
      &lt;meta charset=&quot;utf-8&quot; /&gt;
      &lt;link rel=&quot;icon&quot; href=&quot;%PUBLIC_URL%/favicon.ico&quot; /&gt;
      &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot; /&gt;
      &lt;meta name=&quot;theme-color&quot; content=&quot;#000000&quot; /&gt;
      &lt;meta
        name=&quot;description&quot;
        content=&quot;Web site created using create-react-app&quot;
      /&gt;
      {% comment %} &lt;link rel=&quot;manifest&quot; href=&quot;%PUBLIC_URL%/manifest.json&quot; /&gt; {% endcomment %}
      &lt;link
        rel=&quot;stylesheet&quot;
        href=&quot;//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css&quot;
      /&gt;
      &lt;script src=&quot;//cdn.jsdelivr.net/chartist.js/latest/chartist.min.js&quot;&gt;&lt;/script&gt;
  
      &lt;link rel=&quot;apple-touch-icon&quot; href=&quot;%PUBLIC_URL%/logo192.png&quot; /&gt;
      &lt;!--
        manifest.json provides metadata used when your web app is installed on a
        user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
      --&gt;
      
  
      &lt;!--
        Notice the use of %PUBLIC_URL% in the tags above.
        It will be replaced with the URL of the `public` folder during the build.
        Only files inside the `public` folder can be referenced from the HTML.
  
        Unlike &quot;/favicon.ico&quot; or &quot;favicon.ico&quot;, &quot;%PUBLIC_URL%/favicon.ico&quot; will
        work correctly both with client-side routing and a non-root public URL.
        Learn how to configure a non-root public URL by running `npm run build`.
      --&gt;
      &lt;title&gt;React App&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
      &lt;noscript&gt;You need to enable JavaScript to run this app.&lt;/noscript&gt;
      &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
      &lt;!--
        This HTML file is a template.
        If you open it directly in the browser, you will see an empty page.
  
        You can add webfonts, meta tags, or analytics to this file.
        The build step will place the bundled scripts into the &lt;body&gt; tag.
  
        To begin the development, run `npm start` or `yarn start`.
        To create a production bundle, use `npm run build` or `yarn build`.
      --&gt;
    &lt;/body&gt;
  &lt;/html&gt;
  
  </code></pre>
  <p><strong>settings.py</strong></p>
  <pre><code>import os
  
  
  from pathlib import Path
  from decouple import config
  import dj_database_url
  
  from datetime import timedelta
  
  # Build paths inside the project like this: BASE_DIR / 'subdir'.
  # BASE_DIR = Path(__file__).resolve().parent.parent
  BASE_DIR = os.path.dirname(os.path.abspath(__file__))
  
  # SECURITY WARNING: keep the secret key used in production secret!
  SECRET_KEY = config('DJANGO_SECRET_KEY')
  
  # SECURITY WARNING: don't run with debug turned on in production!
  DEBUG = True
  
  ALLOWED_HOSTS = ['URL's']
  
  SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
  SESSION_COOKIE_SECURE = True
  CSRF_COOKIE_SECURE = True
  SECURE_SSL_REDIRECT = True
  SESSION_COOKIE_HTTPONLY = True
  
  
  INSTALLED_APPS = [
      'rest_framework',
      'django.contrib.admin',
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      'django.contrib.messages',
      'django.contrib.staticfiles',
  
  
      # Third Party Apps #
      'django_filters',
      'corsheaders',
      'django_extensions',
      'drf_yasg',
      'storages',
  
  
      # Apps
      'users',
      'bucket',
      'bucket_api',
      
      #oauth
      'oauth2_provider',
      'social_django',
      'drf_social_oauth2',
  ]
  
  MIDDLEWARE = [
      'django.middleware.security.SecurityMiddleware',
      'django.contrib.sessions.middleware.SessionMiddleware',
      'corsheaders.middleware.CorsMiddleware',
      'django.middleware.common.CommonMiddleware',
      'django.middleware.csrf.CsrfViewMiddleware',
      'oauth2_provider.middleware.OAuth2TokenMiddleware',
      'django.contrib.auth.middleware.AuthenticationMiddleware',
      'django.contrib.messages.middleware.MessageMiddleware',
      'django.middleware.clickjacking.XFrameOptionsMiddleware',
  ]
  
  ROOT_URLCONF = 'core.urls'
  
  
  TEMPLATES = [
      {
          'BACKEND': 'django.template.backends.django.DjangoTemplates',
          'DIRS' : [os.path.join(BASE_DIR, 'build')],
          'APP_DIRS': True,
          'OPTIONS': {
              'context_processors': [
                  'django.template.context_processors.debug',
                  'django.template.context_processors.request',
                  'django.contrib.auth.context_processors.auth',
                  'django.contrib.messages.context_processors.messages',
                  'social_django.context_processors.backends',
                  'social_django.context_processors.login_redirect',
              ],
          },
      },
  ]
  
  WSGI_APPLICATION = 'core.wsgi.application'
  
  DATABASES = {
      'default': {
          'ENGINE': 'django.db.backends.postgresql_psycopg2',
          'NAME': config('DJANGO_DB_NAME'),
          'USER' : config('DJANGO_DB_ADMIN'),
          'PASSWORD' : config('DJANGO_ADMIN_PASS'),
          'HOST' : config('DJANGO_DB_HOST'),
          'PORT' : config('DJANGO_DB_PORT'),
          'OPTIONS': {'sslmode':'disable'},
      }
  }
  
  
  db_from_env = dj_database_url.config(conn_max_age=600)
  DATABASES['default'].update(db_from_env)
  
  
  AUTH_PASSWORD_VALIDATORS = [
      {
          'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
      },
      {
          'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
      },
      {
          'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
      },
      {
          'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
      },
  ]
  
  
  # Internationalization
  # https://docs.djangoproject.com/en/3.1/topics/i18n/
  
  LANGUAGE_CODE = 'en-us'
  
  TIME_ZONE = 'America/New_York'
  
  USE_I18N = True
  
  USE_L10N = True
  
  USE_TZ = True
  
  
  # Static files (CSS, JavaScript, Images)
  # https://docs.djangoproject.com/en/3.1/howto/static-files/
  
  AWS_ACCESS_KEY_ID = config('AWS_ACCESS_KEY_ID')
  AWS_SECRET_ACCESS_KEY = config('AWS_SECRET_ACCESS_KEY')
  AWS_STORAGE_BUCKET_NAME = config('AWS_STORAGE_BUCKET_NAME')
  AWS_S3_ENDPOINT_URL = config('AWS_S3_ENDPOINT_URL')
  AWS_S3_CUSTOM_DOMAIN = config('AWS_S3_CUSTOM_DOMAIN')
  AWS_S3_OBJECT_PARAMETERS = {
      'CacheControl': 'max-age=86400',
  }
  AWS_LOCATION = config('AWS_LOCATION')
  AWS_DEFAULT_ACL = 'public-read'
  
  
  STATIC_URL = '{}/{}/'.format(AWS_S3_ENDPOINT_URL, AWS_LOCATION)
  STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
  DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
  
  
  STATIC_URL = '/static/'
  STATICFILES_DIRS = [
      os.path.join(BASE_DIR, 'static/templates'),
      os.path.join(BASE_DIR, 'build/static')
  ]
  
  STATIC_ROOT = os.path.join(BASE_DIR, 'static')
  </code></pre>
  <hr />
  <p>How can I fix my Django to properly serve production static chunk css and js files from my CDN? The pathing and location to CDN have to be correct if the chrome console is able to locate the files within the error.</p>
  <p>Please let me know if you need more information from my side. Currently stuck and do not have a simple solution to fix my MIME type errors and solving my website from loading only a blank page.</p>
  <p>Thank you for any help/tips/or guidance!</p>
  <p>If anyone is wondering, I'm using Gunicorn and Nginx.</p>
  <p>EDIT:
  added a bounty to draw attention to this question. I am not using Django webpack loader and babel. I would rather not rely on other libraries that could break things easily.</p>
  <p>EDIT #2:
  I have added my NGINX config file, should I redirect traffic to my CDN path here?</p>
  <pre><code>server {
      listen 80 default_server;
      listen [::]:80 default_server;
      server_name _;
      return 301 https://my_website_URL.io$request_uri;
  }
  server {
      listen [::]:443 ssl ipv6only=on;
      listen 443 ssl;
      server_name my_website_URL.com www.my_website_URL.com;
  
     #  Let's Encrypt parameters
      ssl_certificate /etc/letsencrypt/live/my_website_URL.com/fullchain.pem; # managed by Certbot
      ssl_certificate_key /etc/letsencrypt/live/my_website_URL.com/privkey.pem; # managed by Certbot
      include /etc/letsencrypt/options-ssl-nginx.conf;
      ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
  
      location = /favicon.ico { access_log off; log_not_found off; }
  
  
  
  
      location / {
          proxy_pass         http://unix:/run/gunicorn.sock;
          proxy_redirect     off;
  
          proxy_set_header   Host              $http_host;
          proxy_set_header   X-Real-IP         $remote_addr;
          proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
          proxy_set_header   X-Forwarded-Proto https;
          }
  </code></pre>
  <p>EDIT EDIT EDIT:
  I have added my gunicorn file because I'm getting a 502 bad gateway and my gunicorn service is giving me this error:</p>
  <pre><code>● gunicorn.socket - gunicorn socket
       Loaded: loaded (/etc/systemd/system/gunicorn.socket; enabled; vendor preset: enabled)
       Active: failed (Result: service-start-limit-hit) since Wed 2021-04-28 23:44:16 UTC; 1min 2s ago
     Triggers: ● gunicorn.service
       Listen: /run/gunicorn.sock (Stream)
  </code></pre>
  <p>here is my gunicorn config:</p>
  <pre><code>[Unit]
  Description=gunicorn daemon
  Requires=gunicorn.socket
  After=network.target
  
  [Service]
  User=alpha
  Group=www-data
  WorkingDirectory=/home/user/srv/project/backend
  ExecStart=/home/user/srv/project/backend/venv/bin/gunicorn \
            --access-logfile - \
            --workers 3 \
            --timeout 300 \
            --bind unix:/run/gunicorn.sock \
            core.wsgi:application
  
  [Install]
  WantedBy=multi-user.target
  
  </code></pre>