Search code examples
djangogatsbydjango-staticfiles

Staticfiles in Django coming from npm-run-build frontend throw Error 404


I want to add my Gatsby JS' public folder that I created with npm run build to be served to Django as_view. Django keeps throwing 404 Error at me when I'm trying to load the staticfiles and the index.html from STATICFILES_DIRS.

I don't understand how Django is not able to find the JSON file e.g /app-data.json even if I provide an absolute path.

Note: I tried python3 manage.py runserver --insecure (and without insecure as well) - didn't work.

Directory structure:

./frontend
- ./public
 - ./codeblock
 - ./codeblock/1-index
 - ./staticfiles
 - ./staticfiles/d
 - ./page-data
  - /app-data.json
 - ./index.html
 - ...

./backend
- ./backend
  -  settings.py

package.json

    "scripts": {
        "start": "gatsby develop",
        "build": "gatsby build --prefix-paths",
        "format": "prettier --write \"src/**/*.{js,jsx,css,json}\"",
        "lint": "eslint --fix \"src/**/*.{js,jsx}\""
    },

settings.py

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DEBUG = False

INSTALLED_APPS = [
    ...
    'django.contrib.staticfiles',

BACKEND_DIR = BASE_DIR

FRONTEND_DIR = os.path.abspath(
    os.path.join(BACKEND_DIR, '..', 'frontend'))

# STATIC_ROOT = os.path.join(BASE_DIR, 'static')

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(FRONTEND_DIR, 'public'),
    os.path.join(FRONTEND_DIR, 'public', 'page-data'),
    ]

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

urls.py

...imports 

urlpatterns = [
    url('test/', views.FrontendAppView.as_view()),
]+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

index.html

In the HTML file if I define the path with /static/, such as href="/static/webpack-runtime-4145e7520a88c179d990.js", then Django can pull in the JS static files, otherwise 404 Error.

<!DOCTYPE html>
<html lang="en">

<head>
    <link as="script" rel="preload" href="webpack-runtime-4145e7520a88c179d990.js" />
    <link as="script" rel="preload" href="commons-926e13980b7ff3c9526c.js" />
    <link as="script" rel="preload" href="app-425daa4026ff9a50d14f.js" />
    <link as="fetch" rel="preload" href="page-data/index/page-data.json" />
</head>
...

Solution

  • If anyone is interested, here's what solved this issue for me.

    • Issue 1: I didn't add {% static %} and {% load static %}

    • Issue 2: I had to make changes after npm run build each time in the HTML file

    Solution: If you are using Gatsby JS, edit your congif.js as seen below. It will add /static/ before the path and Django will be able to render your pages correctly. This way you don't have to add {% static %} and {% load static %}:

    const config = {
        gatsby: {
            pathPrefix: '/static/'
    }