[Django]-How to serve django and gatsby on single vhost?

2👍

I’m sure you don’t need it anymore, but it may be useful for others.

I ran into the same problem and the solution turned out to be using assertPrefix specifically in gatsby-config.js (for example, "/static/", it replaces the path only for static files and does not change the path for .html files) instead of pathPrefix (which replaces the path of each file)

module.exports = {
   assetPrefix: "/static/",
   ...
}

Now in django settings it remains only to specify the same STATIC_URL = "/static/" and the absolute path to the folder with files that gatsby gives after gatsby build --prefix-paths

STATICFILES_DIRS = (os.path.join(BASE_DIR,"frontend/public/"),).

Also specify templates:

TEMPLATES = [
    {
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [str(BASE_DIR/'frontend/public')],
    ...
    }
]

Next, you need to create a url path in django. For example:

#main/urls
urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/',include('backend.urls')),
    path(r'', include('frontend.urls')),
] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT) # this line is optional, but if you use MEDIA_ROOT, then it can be written this way

and

#frontend/urls
urlpatterns = [
    path('', mainpage),
    path('app/',app),
    path('login/',login),
    path('user/<int:userid>',userid),
]

Views can look like this for example:

#frontend/views*
from django.views.generic import TemplateView
    
mainpage = TemplateView.as_view(template_name="index.html")
app = TemplateView.as_view(template_name="app/index.html")
user = TemplateView.as_view(template_name="user/index.html")
login = TemplateView.as_view(template_name="login/index.html")
error = TemplateView.as_view(template_name="404/index.html")
userid = TemplateView.as_view(template_name="user/[userid]/index.html")
👤jix

1👍

After compiling your gatsby project, it should be served by django as a static page.

First: The gatsby dist should be in your static_private path.

Second: In your django project, you will define a URL for / that will call an index view let’s say.

Finally: in your view you should render index.html of your gatsby dist.

urls.py:

from django.contrib import admin
from django.urls import path, re_path, include
from . import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('apis/', include('apps.urls')),
    path('/', views.index),
]

views.py:

from django.shortcuts import render

def index(request):
    return render(request, 'index.html')

Note that if you are handling routing in your frontend your url pattern for the index view should be like this : re_path('^.*$', views.index)

If you are hosting your django app on heroku you will need the whitenoise middleware and set it up in your settings.py :

MIDDLEWARE = [
    ...
    'whitenoise.middleware.WhiteNoiseMiddleware',
    ...
]

A doc is available here: https://devcenter.heroku.com/articles/django-assets#whitenoise

Leave a comment