how to use the app.css.config.serve_locally and app.scripts.config.serve_locally option for scripts and style sheets that are not part of the dash package? It seems like @app.server.route is ignored if serve_locally is active.
The warning message is comprehensible, because the custom style sheet is not part of dash:
A local version of /static/style.css is not available
Background: I’m behind a firewall and cannot access CDN to load the dash/react javascript files. But I also have a custom CSS style sheet, served by a flask route.
I’m not sure what is the final goal of your app, but assuming you want eventually to deploy it publically, most likely you will need the Nginx server for that. Said all that, I also reuse the Nginx server to serve the static assets, that Plotly Dash picks up. That includes scripts, css, images.
The application should run behind a company firewall. There should be no communication to the internet. Why should I use Nginx to to serve the static content?Is there no way to use serve_locally and static routes side by side?
I would say you by no means must use Nginx if you don’t serve your app in public. But you still can use it even on your private network.
In any case, I’m myself a physicist by background and cant really answer all the Whys. I’ve simply implemented Nginx->Gunicorn->Flask chain because internet recommends it as a best practice. As a part of this chain, I have also found a way how to utilize Nginx for serving static assets. Sort of win-win-win, all boxes ticked.
If you’re only deploying to a small number of users, then you can probably get away with just using Flask to serve your static content and also just using the Flask development server (as used in the Dash Guide).
Using a web server for hosting static content (like Nginx or Apache) will allow your app to scale to many more users, and using a WSGI server such as gunicorn will provide more robustness and again scalability of the of the app itself.
@HansG - For now, you can insert CSS with a html.Link component inside app.layout. This will bypass the unflexible append_css method. Here’s an example:
import dash
import dash_html_components as html
import os
from flask import send_from_directory
app = dash.Dash()
app.css.config.serve_locally = True
app.scripts.config.serve_locally = True
app.layout = html.Div([
html.Link(
rel='stylesheet',
href='/static/stylesheet.css'
),
html.Div('Hello world')
])
@app.server.route('/static/<path:path>')
def static_file(path):
static_folder = os.path.join(os.getcwd(), 'static')
return send_from_directory(static_folder, path)
if __name__ == '__main__':
app.run_server(debug=True)
I’m looking to update this behaviour (adding external CSS and JS) in this PR: https://github.com/plotly/dash/pull/171. Feedback welcome! (Please comment on the PR itself)
I’ve managed to use the html.Link solution above to serve local css files in my dash app, however, subsequent changes to the local css are not reflected in the app. The original css is being loaded instead. Is this being cached somewhere? Is there any way that I can purge this?
At the moment I basically have to change the name of the css file and the href in the main app to get it to load any changes.
I never liked the html.Link solution much myself, as for the app I tried it on it resulted in a momentary period of time where the styles were not applied, while the sheet was loaded. This is somewhat jarring, so I gave up on that. The other approach you can take until Dash properly supports adding you own entries in the header, is to subclass the Dash class and override the index method which includes any stylesheets you want.
I am following the following issue: It works perfectly untill I make any change at the .css file. For example, I change the background-color at the file and this does not apply any change to the interface. If I want to see the change I have to save the modified file with a different name (e.g. stylesheet_new.css), then change the href='/static/stylesheet_new.css and only then I will notice the changes.
Hello. We are using Dash to build a fairly straight forward web app. This app includes custom stylesheets, custom Dash components and other custom javascript. We have our own static content web server (not nginx but equivalent). We want to serve everything locally from this server including the javascript.
Dash will only apparently try to serve it’s own files and ignores ours even though we have added our files to app.css.append_css and app.scripts.append_script.
The work around given here (thanks for that!) using html.Link does work for css files but there seems to be no equivalent way of loading our custom javascript when serve_locally is true. Doing the same but with the html.Script component seems to have no effect.
Does anyone have any ideas or suggestions? The problem does not seem to be how we are serving things statically but rather in how Dash itself works.
If you’re silly like me and 1) didn’t know what f-strings were and 2) didn’t realize that they didn’t exist until python 3.6 and 3) you need to use python 2.7 for some reason… use:
while some of these answers work for single small settings, my situation is a bit different. I develop a larger server app, with flask pages and dash pages, moreover I am abroad and have only very limited internet resources, so I would like to develop the flask/dash app without internet connection.
I serve my css, and js files via a /static/ Flask route, which works when I set both of the next two lines to ‘False’
However, my Flask pages need also jQuery which I would like to server also via the static route.
If both set to “False” my static rout provides the relevant css and js files, all is well, but the React components needed to render dash pages are not loaded (no inet connection). If I set the lines to “True” and “False” as shown above, Flask is unhappy (as the locally stored jQuery et all. are not loaded) but the dash pages have the react scripts…
Any idea how to solve my offline problem?
In the end the server runs with an internet connection, but for development without internet the situation is rather daring. (When the React components are being tried to load from the iNet, the server start is rather long winded, as there are many timeouts to wait for, this makes offline development essentially not possible)
Help and ideas welcome!
Cheers
PS: Maybe the app.head functionality can help? I have not investigated that yet. See allow optional headers: