Adding meta tags to <head>?


#1

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....


#2

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.


Including page titles, favicon, etc in dash app?
Cannot modify the page title and html.meta doesnt exist?
#3

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


#4

Should we open an issue about this?


#5

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).


#6

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.


#7

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)