Search code examples
djangocreate-react-appfavicon

How to add favicon to django app with React front end


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!


Solution

  • In production you usually use nginx or whatever server you have in front of your wsgi server to serve static files.

    Specifically for the favicon, you can setup a location in nginx just for that:

    location = /favicon.ico {
        alias /var/www/mysite/img/favicon.ico;
    }