MrL
MrL

Reputation: 348

Flask 404'ing on static content I have in an assets directory

My project structure looks like this:

/project home
app.py
/templates/index.html
/templates/assets

and my index.html file has several references to relative stylesheets that look like this:

<link rel="stylesheet" href="assets/css/slick.css">
<link rel="stylesheet" href="assets/css/slick-theme.css">

Same for various JS files that exist in assets/js. Now when I load the page, I get this error:

Loading failed for the <script> with source “http://localhost:5000/assets/js/popper.min.js”. localhost:5000:564:1

There are many of these messages and in the python debugger I see:

127.0.0.1 - - [24/Dec/2019 18:29:16] "GET /assets/js/main.js HTTP/1.1" 404

I tried googling and changing this line in Flask

STATIC_URL_PATH = '/templates/assets/' # Where the css is stored
STATIC_FOLDER = '/templates/assets/'
app = flask.Flask(__name__, static_folder=STATIC_FOLDER,
            static_url_path=STATIC_URL_PATH)

But still when I click the index.html page in templates its able to load fine with all the CSS and JS and images, but from Flask, its like the CSS is stripped out.

Upvotes: 1

Views: 2212

Answers (1)

Gino Mempin
Gino Mempin

Reputation: 29546

First, make sure that the templates folder is in the same directory as your app.py:

.
├── app.py
└── templates
    └── assets

Then create the Flask instance like this:

STATIC_FOLDER = 'templates/assets'
app = Flask(__name__,
            static_folder=STATIC_FOLDER)

1st, /templates and templates (without /) are 2 different paths. The 1st one refers to a templates folder under the root path / of your system, which certainly isn't the one you want. The 2nd one refers to a templates folder in the same directory, which is the one you want.

2nd, there is no need to specify static_url_path if it's just the same as the static_folder, because that's the default behavior ("Defaults to the name of the static_folder folder").

Then, in your HTML files, instead of hardcoding the paths to the assets folder, let Flask build the URL for you. See the Static Files section of the Flask docs:

To generate URLs for static files, use the special 'static' endpoint name:

url_for('static', filename='style.css')

By default, it will look for static files under the static folder (ex. static/style.css) because that it is the default value for the static_folder parameter in the Flask constructor. When you set it to templates/assets, Flask will use that and will automatically build the correct URL with url_for.

<link rel="stylesheet" href="{{ url_for('static', filename='css/slick.css') }}">

Note:
Make sure that, when testing the loading of static files, clear your browser's cache first or test your app on private/incognito mode of your browser, to force re-downloading of static files.

Upvotes: 3

Related Questions