✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

Unable to load _dash-layout and _dash-dependencies from dash app running behind Nginx

Hi,

I am serving dash content inside a Flask app which uses blueprint for registering the routes.
App setup:

  1. Dash is initialised with route_pathname_prefix=/dashapp/
dash_app = dash.Dash(
        server=server,
        routes_pathname_prefix='/dashapp/',
    )

dash_app.css.config.serve_locally = True
dash_app.scripts.config.serve_locally = True
    
  1. Registered dash app with Flask server
  2. Used UWSGI to serve Flask app inside a docker container
[uwsgi]
wsgi-file = </path/to/app.py>
callable = app
http = 0.0.0.0:8080
processes = 4
threads = 2
master = true
chmod-socket = 660
vacuum = true
die-on-term = true

Upto this point everything was working fine locally. Once I added Nginx proxy, I got the below issue

Issue:
urls for _dash-layout and _dash-dependencies are missing the revers proxy uri. For example, I am serving my flask app at www.example.com/app/. But, on the browser, I saw that requests for _dash-layout and _dash-dependencies are coming at www.example.com/dashpp/_dash-layout instead of www.example.com/app/dashpp/_dash-layout.

I read the following forum discussion and tried applying the solution, and got this error,
requests_pathname_prefix needs to start with ‘/’`

This is my Nginx config,

location /app/ {
    proxy_pass http://localhost:<port>;
    proxy_redirect http://localhost:<port> http://example.com/app/;
    proxy_set_header Accept Encoding "";
    sub_filter_types *;
    sub_filter 'href="/' 'href="/app/';
    sub_filter 'src="/' 'src="/app/';
    sub_filter_once off;
}

Anyone has pointers to what is missing. I am new to dash. So, if I missed adding any information please let me know, I will be happy to give additional details

Thanks

Edit:

To add additional context, I found out that url for _dash-component-suites is generated as expected www.example.com/dashpp/_dash-component-suites. I went through the dash source code to understand how urls are generated. Both, _dash-component-suites and _dash-layout are prefixed with routes_pathname_prefix. Line 428 to 448 of dash.py in version 1.14.0 has the code for building urls.

This is confusing!!!.

My response from this GitHib thread:

I believe Dash doesn’t know that you’ve configured nginx with the additional app route prefix, so you need to make it aware of that. Try initialising the Dash instance with requests_pathname_prefix='/app/dashapp/' .

This forum thread looks like it could be relevant to your situation: Host dash under alternate path

And @kanishka’s response:

Hi @ned2 , thanks for the reply. I incorporated your suggestion and added requests_pathname_prefix='/app/dashapp/' . The dash UI is stuck and displayed Loading . Upon inspecting, I got this error in console

Uncaught ReferenceError: DashRenderer is not defined

I am attaching full error trace below

This is the change I made to dash instance which triggered the above error,

dash_app = dash.Dash(
        server=server,
        requests_pathname_prefix='/app/dashapp/',
    )

Previous version,

dash_app = dash.Dash(
        server=server,
        routes_pathname_prefix='/dashapp/',
    )

Nginx config remained the same between the 2 runs

Have you seen this forum post @kanishka? Uncaught ReferenceError: DashRenderer is not defined

there’s a workaround suggested of not using local assets, but also another link to this post: Mod_wsgi and dash - virtual host configuration

That looks like it could be describing your situation. I’d try opening up the network tab in the browser dev tools and then reload the page. If there’s any failed network requests, have a look at the URLs they’re sending to to diagnose how you might need to change the value of requests_pathname_prefix

Oh sorry, I meant to try setting both routes_pathname_prefix and requests_pathname_prefix. ie

dash_app = dash.Dash(
    server=server,
    routes_pathname_prefix='/dashapp/',
    requests_pathname_prefix='/app/dashapp/',
)

If Dash is going to be sending sending requests to the server at /app/dashapp/, with the app prefix coming from the nginx redirect, the dashapp part of the prefix still needs to be specified by the app itself.

But it has been a while since I’ve had my head in this space, so hopefully I’m on the right track :slight_smile:

Thanks for clarifying @nedned. I did try this config. When I gave requests_pathname_prefx=/app/dashapp/ and routes_pathname_prefix='/dashapp/', urls were being generated as www.example.com/app/app/dashpp/_dash-component-suites/
This is due to sub_filter I have in nginx config. I needed that subfilter because I have bunch of css files to render on the page.

Yes, I did try applying solutions 1 and 2. In both cases, urls for _dash-layout and _dash-dependecies were missing /app. For example, www.example.com/dashpp/_dash-layout instead of www.example.com/app/dashpp/_dash-layout

I’m actually not all that familiar with nginx, but can you test it out without the sub_filter just to verify whether that config works for the routes?

I wonder if there is a cleaner way to get the routes for your CSS assets working rather than string re-writing?

I was able to solve this the following way,

  1. I removed sub_filter directive from nginx config
  2. I added url_prefix while registering flask blueprint object (url_prefix=/app/)
  3. For identifying static content, I prefixed my app uri (static_path=/app/static)
  4. Updated routes_prefix_pathname to have app prefix (routes_prefix_pathname=/app/dashapp/)

@nedned, Thanks for sharing your thoughts on this.

1 Like