Black Lives Matter. Please consider donating to Black Girls Code today.

Adding meta tags to <head>?

I want to add the following tag to make our html Table more responsive
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

From what I’ve read on these forums, this doesn’t sound particularly simple to do, since Dash is mostly rendering in the <body>. But there should be a way using the underlying Flask server no? My Google-Fu has been failing me in this area. I take it I would probably have to create a Jinja2 template that would just be that tag and then load it somehow using app.server....

Monkey patch!

class Dash_responsive(dash.Dash):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    #Overriding from https://github.com/plotly/dash/blob/master/dash/dash.py#L282
    def index(self, *args, **kwargs):
        scripts = self._generate_scripts_html()
        css = self._generate_css_dist_html()
        config = self._generate_config_html()
        title = getattr(self, 'title', 'Dash')
        return ('''
        <!DOCTYPE html>
        <html>
            <head>
                <meta charset="UTF-8"/>
                <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
                <title>{}</title>
                {}
            </head>
            <body>
                <div id="react-entry-point">
                    <div class="_dash-loading">
                        Loading...
                    </div>
                </div>
            </body>
            <footer>
                {}
                {}
            </footer>
        </html>
        '''.format(title, css, config, scripts))


app = Dash_responsive()
# so on and so on 

I guess it would be nice to have a head and a footer variable so that users could set this without the need for a patch like this.

6 Likes

Having head and footer params that could take a list of additional elements to insert seems like a sensible idea to me.

2 Likes

Should we open an issue about this?

I got this working by adding a little custom JavaScript.

File Structure:

- app.py
- server.py
- static
    | -- js
        | -- javascript.js

In javascript.js:

var metaTag=document.createElement('meta');
metaTag.name = "viewport"
metaTag.content = "width=device-width, initial-scale=1.0, maximum-scale=1.0"
document.getElementsByTagName('head')[0].appendChild(metaTag);

And in app.py:

app.scripts.append_script({
    'external_url': '/static/ js/javascript.js?%s' % dt.now(),
})

For this to work, you also have to have the Flask server set up for serving static files:

In server.py

STATIC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static')
@server.route('/static/<resource>')
def serve_static(resource):
    return send_from_directory(STATIC_PATH, resource)

Where server is a flask.Flask object.

@rad, have you opened an issue about this? I definitely think that simply having this built into Dash with something like an html.Head and html.Footer would be beneficial (and fairly easy to do).

It’s not quite about having an html.Head and html.Footer because app.layout is rendered inside a div in the body. I’ve posted an issue outlining my thoughts for implementation.

Here is a PR that addresses this issue and others: https://github.com/plotly/dash/pull/171. Feedback welcome! (Please comment on the PR itself)

1 Like