'White blank page when I deploy my (React.js & Django) app to Heroku

I'm beginner and the project works perfectly locally , but when I deploy on Heroku I get a blank page.

I also connected my Heroku to GitHub and and I made a build back with https://github.com/mars/create-react-app-buildpack but it still not working .

My database and Django in the admin dashboard (Backend) is working perfectly

Console:

My files:

My build folder:

My public folder:

My src folder:

package.json (I tried adding "homepage": "." but it didn't work to me even after rebuild again ):

   {
  "name": "frontend",
  "homepage": "aroundtheword.herokuapp.com/",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.2",
    "@testing-library/react": "^12.1.4",
    "@testing-library/user-event": "^13.5.0",
    "axios": "^0.26.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^6.2.2",
    "react-scripts": "^5.0.0",
    "uuid": "^8.3.2",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "postinstall": "npm run build"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "engines": {
    "node": "16.13.0",
    "npm": "8.1.0"
  }
}

index.html (public folder):

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    
    <link 
    rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" 
    integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" 
    crossorigin="anonymous" >
    <title>Around the world</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    
  </body>
</html>

index.html (build folder):

<!doctype html>

<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <link rel="icon" href="/favicon.ico"/>
        <meta name="viewport" content="width=device-width,initial-scale=1"/>
        <meta name="theme-color" content="#000000"/>
        <meta name="description" content="Web site created using create-react-app"/>
        <link rel="apple-touch-icon" href="/logo192.png"/>
        <link rel="manifest" href="/manifest.json"/>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
        <title>Around the world</title>
        <script defer="defer" src="/static/js/main.9bb6833f.js">

        </script>
    </head>
    <body>
        <noscript>You need to enable JavaScript to run this app.</noscript>
        <div id="root"></div>
    </body>
</html>

Procfile:

release: python manage.py migrate 
web: gunicorn blog_lyfe.wsgi --log-file -

App.js:

import { BrowserRouter as Router , Routes, Route } from "react-router-dom";
import Layout from './hocs/Layout';
import Blog from './components/Blog';
import BlogDetail from './components/BlogDetail';
import Category from './components/Category';

const App = () => (
  <Router >
    <Layout>
      <Routes>
        <Route exact path = '/' element = {<Blog/>} />
        <Route exact path = '/category/:category' element = {<Category/>} />
        <Route exact path = '/blog/:id' element = {<BlogDetail/>} />
      </Routes>
    </Layout>
  </Router>
);

export default App ; 

In settings.py some of codes in the settings.py are commented because it didn't work to me :

from pathlib import Path
import os 
# import psycopg2
# import dj_database_url

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-l-_lzjw2btw*&v^v7^fes6h&!#lbl&=4(-%v_i4jgpe-%neygg'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['aroundtheword.herokuapp.com','localhost:3000/']


# Application definition

INSTALLED_APPS = [
    # Our Apps: 
    'blog',
    
    # Third party Apps:
    'rest_framework',
    'corsheaders',# For API issues 
    'django_summernote',
    
    # Default Apps: 
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
]

STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" # Compress files with whitenoise

MIDDLEWARE = [
    # Default middleware:
    'django.middleware.security.SecurityMiddleware',
    "whitenoise.middleware.WhiteNoiseMiddleware", # whitenoise "Third party", should be the second middleware or we may get a problem 
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware', #To allow access to the API "CORS"
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CORS_ORIGIN_ALLOW_ALL = True # Allow access for all domains "CORS"


ROOT_URLCONF = 'blog_lyfe.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'build')], # When we run npm build it will create "build" folder to be our template
        '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',
            ],
        },
    },
]

WSGI_APPLICATION = 'blog_lyfe.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
        # 'ENGINE': 'django.db.backends.postgresql',
        # 'ENGINE': 'django.db.backends.postgresql_psycopg2',
        # 'NAME': 'd37cashvd4ogm7',
        # 'USER' : 'bparrgryetmpbd',
        # 'PASSWORD' : '0bd2d570a4969616e1bf2a08d1692e0e356d4979a871bbdcc7d00851fb48cbf9',
        # 'HOST' : 'ec2-3-209-61-239.compute-1.amazonaws.com',
        # 'PORT' : '5432',
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

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.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/' 

STATICFILES_DIR = [
    #After running npm run build we will get 'build' folder and we 
    # are going to have a static folder there 
    os.path.join(BASE_DIR, 'build/static') 
]

# Media path
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')


# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# Add Rest Framework settings
REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
        
    ]
}

STATIC_ROOT = BASE_DIR / "staticfiles"
# import django_heroku
# django_heroku.settings(locals())


# DataBase: 
# DATABASE_URL = os.environ['DATABASE_URL'] 
# conn = psycopg2.connect(DATABASE_URL, sslmode='require')

# DATABASES['default'] = dj_database_url.config(conn_max_age=600, ssl_require=True)

static.js :

    {
  "root": "public",
  "clean_urls": false,
  "error_page": "{ \"root\": \"public\", \"clean_urls\": false }",
  "routes": {
    "/*": "index.html"
  }
}


Solution 1:[1]

I have deployed React app on AWS , and Django on Heroku (separately) , but you can deploy Django on AWS as well .

Here is how I deployed React app

Here is how I deployed Django app

Don't forget to edit settings.py and write "'rest_framework.permissions.AllowAny'" in the REST_FRAMEWORK settings.py , so it will be like this ? :

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ]
}

Notice that it will not be secure to AllowAnay permissions .

Solution 2:[2]

Please use heroku-buildpack-static for this.

Before deploying please build the react app using the command npm run build

and your static files will be in the build folder. Use the following official guide to deploy it to Heroku

https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-static

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ahmad Kahil
Solution 2 Yasantha Hennayake