Search code examples
reactjsdjangoheroku

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

  • 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 .