plotly / plotly/dash

Meta tags don't work for Dash pages when app is integrated into Flask app

Open
#2,790 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P3 sev-2
Dominant language
Python
Stars
24.4k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
13

Description

Describe your context

Please provide us your environment, so we can easily reproduce the issue.

dash                      2.16.1
dash_ag_grid              31.0.1
dash-bootstrap-components 1.5.0
dash-core-components      2.0.0
dash-html-components      2.0.0
dash-mantine-components   0.12.1
dash-table                5.0.0

Describe the bug

When integrating a Dash app that uses Dash pages into a Flask app, both methods outlined here result in (differently) incorrect behaviour of the page meta tags.

To reproduce, create a file assets/app.svg and then run the following minimal apps.

Method 1

import dash
import flask

server = flask.Flask(__name__)

app = dash.Dash(server=server, routes_pathname_prefix="/dash/", use_pages=True, pages_folder=""")
dash.register_page("page", layout=dash.html.P("Hello, Dash!"))
app.layout = dash.page_container
app.run()

Go to http://localhost:8050/dash/page. The page renders ok but if you check the source then the meta tags have no content:

<meta property="twitter:image" content="">

Method 2

import dash
import flask
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from werkzeug.serving import run_simple

server = flask.Flask(__name__)

app = dash.Dash(requests_pathname_prefix="/dash/", use_pages=True, pages_folder="")
dash.register_page("page", layout=html.P("Hello, Dash!"))
app.layout = dash.page_container
application = DispatcherMiddleware(server, {"/dash": app.server})
run_simple("localhost", 8050, application)

Go to http://localhost:8050/dash/page. The page renders ok but if you check the source then the meta tags point to the wrong place - note the doubled up dash:

<meta property="twitter:image" content="http://127.0.0.1:8050/dash/dash/assets/app.svg">

Expected behaviour

In both the above cases, the meta tag should be as follows:

<meta property="twitter:image" content="http://127.0.0.1:8050/dash/assets/app.svg">

Source of problem

For Method 1, the code in _path_to_page cannot find the right page and so returns an empty dictionary. The reason for this is that flask.request.path.strip("/") returns dash/page rather than just page, which is the value to match against in the page registry page["path"]:
https://github.com/plotly/dash/blob/78ebf0db5f297989b4b07ec004a3c7f9e11ee412/dash/_pages.py#L386
Suggested fix: use flask.request.view_args["path"] instead, which gives just page.

For Method 2, the call to app.get_asset_url already includes the requests_pathname_prefix, as does flask.request.url_root, and so you end up with this being repeated:
https://github.com/plotly/dash/blob/78ebf0db5f297989b4b07ec004a3c7f9e11ee412/dash/_pages.py#L393
Suggested fix: use flask.request.host_url instead, which gives just http://localhost:8050.

These suggested fixes come about just from inspecting flask.request and looking for a suitable string. They work on the above two examples but I haven't carefully tested them, so there might be other cases that they don't solve (or worse, cases that currently work but the suggested solutions break). Hopefully someone who knows more about flask routing than me can comment on whether these are the right fixes.

This is a very small bug so I guess will not be high priority to fix, although the fix should also be quick and easy. I'd be happy to raise a PR if the above suggestions seem correct or if someone makes a better suggestion.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing both integration methods from the issue, then inspect dash/_pages.py around _path_to_page and the meta-tag URL construction at the linked lines. Compare Flask request path and URL values in each setup; done means both methods produce the expected /dash/assets/app.svg URL without empty or duplicated prefixes.

Written by the indexing model from the issue text.

Assessment

Tech stack
flask, python
Domain
backend, web-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.