I'm building a Django app with a React front end, built using react-create-app. I can't get the favicon to show up in production.
I'm using Django 2.10.0.
When I build the React app, the build output files are put in the assets/static/ folder. This includes image files used as backgrounds via css, and all works fine. These are included in the build because they are referenced in the stylesheets. The favicon is referenced from index.html and therefore isn't picked up by the build process.
However I don't know how to get the server to serve up the favicons. If I put them in the frontend/public folder, the Django server doesn't find them.
If I manually copy them into the static/ folder, they show up but that folder is managed by Webpack and the contents are removed when the app is built.
Copying the favicons into the project root doesn't work. They are in the same folder as index.html, which is served up, but Django server won't serve those co-located image files.
The only documentation I can find deals with either Django or create-react-app; I can't find anything that explains how to tie them together for favicons.
In settings.py:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'assets/static'),
os.path.join(BASE_DIR, 'assets'),
]
In index.html:
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
In the browser, this is converted to:
<link rel="shortcut icon" href="/favicon.ico">
which doesn't work - the file is not served up. I'm not sure why this doesn't work given that I've added 'assets' to STATICFILES_DIRS in settings.py and have copied the favicons into the root of 'assets'.
All the working css and image links include the static folder, e.g.:
http://localhost:8000/static/media/private.d7365d01.svg
It seems like there are two problems:
1) how to get the build process to copy the favicon and related files into the assets folder so they can be served up
2) how to get index.html to look in the right place for the favicon
If I could customise PUBLIC_URL to point to static/ that might do it, but that might break other bits of code that reference it?
I am sure I'm missing something simple. I'd be grateful for any help!
Edit: I have now got the favicon to show up in a built version running on my local machine, but it isn't being served by the production server.
Base.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'assets/static'),
os.path.join(BASE_DIR, 'assets'),
]
index.html
<link rel="shortcut icon" href="%PUBLIC_URL%/static/favicon.ico" />
And favicon.ico is in the 'assets' folder. After building my React app and running the development server locally, the url http://localhost:8000/static/favicon.ico displays my favicon. But after deploying this to the server, the url https://example.com/static/favicon.ico finds nothing. I have checked and the favicon.ico file is present on the server, in the assets folder. Settings.py is the same. I can't figure out why the production server isn't serving up the favicon?
Edit: I've tried adding this to my settings.py, but it still doesn't work:
STATIC_ROOT = os.path.join(BASE_DIR, 'assets')
'assets' is the name of the folder on the server that contains my build files. The favicons are in assets, as is index.html, and the React files in assets/static.
Edit: this is my Passenger config file for Nginx:
server {
listen 80;
server_name 178.62.85.245;
passenger_python /var/www/myappname/venv36/bin/python3.6;
# Tell Nginx where your app's 'public' directory is
root /var/www/myappname/myappname/myappname;
# Turn on Passenger
passenger_enabled on;
# Tell Nginx the location of the build output files
location /static/ {
autoindex on;
alias /var/www/myappname/myappname/assets/;
}
}
Nginx finds the file index.html and all the files that React built. I don't know why it can't find the favicon in the same folder!
Edit: I finally solved this thanks to Sune Kjærgård's help. From reading the Django docs about deployment, I had thought I needed to configure all the static file locations in settings.py. However that seems to be only for the Django development server, even when running with production settings. On the production server I am using Nginx via Passenger to serve the app. It is Nginx that needs to know where all my static files are located. And both 'root' and 'location' need to be set correctly.
Here is my working code. The favicons are served on the production server, and in development on port 3000 when running the frontend separately. I haven't got them served when testing the build locally on port 8000, but I can live with that and maybe find a solution later.
STATIC_ROOT doesn't seem to be required, nor am I running buildstatic.
My favicons are located in frontend/public, the same folder as index.html. The Webpack build process copies them all into the assets folder.
server {
listen 80;
server_name 178.62.85.245;
passenger_python /var/www/myappname/venv36/bin/python3.6;
# Tell Nginx where your app's 'public' directory is
root /var/www/myappname/myappname/assets;
# Turn on Passenger
passenger_enabled on;
# Tell Nginx the location of the build output files
location /static/ {
autoindex on;
alias /var/www/myappname/myappname/assets/;
}
}
In settings.py:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'assets/static'),
os.path.join(BASE_DIR, 'assets'),
]
In index.html:
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
In the browser, this is converted to:
<link rel="shortcut icon" href="/favicon.ico">
And I can see the icon in a browser at the address https://example.com/favicon.ico
Happy dance!