A dcc.DocumentTitle Component for Updating the Page Title Dynamically
This would enable users to update the tab:
- When navigating pages with
dcc.Location - When updating tabs with
dcc.Tabs
I've helped a customer with a similar component with an implementation below:
import {Component} from 'react';
import PropTypes from 'prop-types';
export default class DocumentTitle extends Component {
componentDidMount() {
document.title = this.props.children;
}
componentWillReceiveProps(nextProps) {
document.title = nextProps.children;
}
render() {
return null;
}
}
DocumentTitle.defaultProps = {
children: 'Dash'
}
DocumentTitle.propTypes = {
children: PropTypes.string,
id: PropTypes.string
}
To bring this into the library, we would need to:
- incorporate that code as a new component
- then add some tests
- Modify
componentWillReceivePropsto the non-deprecated way of doing things with React - Add docs to:
-
dash.plotly.com/urls -
dash.plotly.com/dash-core-comoponents/documenttitle. Provide a cross link to/external-resourcesto mention how to set the page title via the server side template, which would provide the page title on page load rather than dynamically. Doing this on page load would be better for SEO. - Provide a link to these docs from the
external-resourcespage where we discuss how to set thetitlein the server-side template and mention the limitations of that method (it will only update the page title on page load, not on subsequent navigation viadcc.Link)
-
If any community member takes this on before we get around to, please comment below!
As a workaround before we have this component, users could do a clientside callback with a side affect that would update document.title as a side effect. I have not tested this, but here is how it might work in principle:
app.layout = app.layout = html.Div([
html.Div(id='dummy'),
dcc.Tabs(id='tabs-example', value='tab-1', children=[
dcc.Tab(label='Tab one', value='tab-1'),
dcc.Tab(label='Tab two', value='tab-2'),
]),
html.Div(id='tabs-example-content')
])
app.clientside_callback(
"""
function(tab_value) {
document.title = tab_value;
return null; // dummy output
}
""",
Output('dummy', 'children'),
[Input('tabs-example', 'value')]
)
unfortunately the title change using the above workaround gets reverted as soon as the clientside callback exits as you can see by adding an alert:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
app.layout = app.layout = html.Div([
html.Div(id='dummy'),
dcc.Tabs(id='tabs-example', value='tab-1', children=[
dcc.Tab(label='Tab one', value='tab-1'),
dcc.Tab(label='Tab two', value='tab-2'),
]),
html.Div(id='tabs-example-content')
])
app.clientside_callback(
"""
function(tab_value) {
console.log(tab_value);
document.title = tab_value;
alert(document.title)
}
""",
Output('dummy', 'children'),
[Input('tabs-example', 'value')]
)
if __name__ == '__main__':
app.run_server(debug=True, port=8074)
Looks like we actually need to fix the title overriding behavior in Dash itself. Added a fix in https://github.com/plotly/dash/pull/1343
OK, this feature is now available in dash==1.14.0. and is documented in http://dash.plotly.com/external-resources. See the "Update the Document Title Dynamically based off of the URL or Tab" example.
I'll keep this issue open to consider a dcc.DocumentTitle component which would enable a Python interface to updating the title. The current example documented above uses a clientside callback (JavaScript).
I would like a dcc.DocumentTitle but your work around worked great for me in Dash==1.15.0
If someone finds this and wished they had a function to get a SPECIFIC url param, in this case subject, what's below worked for me.
In the python:
dcc.Location(id='url', refresh=True),
html.Div(id='blank-output'),
In the callbacks:
app.clientside_callback(
"""
function(url) {
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
if (decodeURIComponent(pair[0]) == variable) {
return decodeURIComponent(pair[1]);
}
}
console.log('Query variable %s not found', variable);
}
document.title = getQueryVariable('subject')
}
""",
Output('blank-output', 'children'),
[Input('url', 'search')]
)
+1 for a dcc.DocumentTitle or an html.title - its docs already exist, but the component is non-functional. I'd like to be able to add this object to a page's layout object and have it override the global app title set in dash.Dash(title="Dash").
Using Dash 1.16.0, I haven't successfully gotten the "Update the Document Title Dynamically" clientside callback workaround to work for a dcc.Location. I suspect this is because my app is organized in multiple files, so this may be mitigated by 2.0's ability to make clientside callbacks from the dash module.
Hi there, I tried to set the "app.title" and the "app._favicon" for a monitoring app, searched and found this discussion. But I slightly disagree with your suggestion. From the view of the user (me), my fist attempt was to simply create the "app.id" attribute for the use as the output target with usual callback mechanism. This of course doesnt worked, but instead of creating more specialiced dcc function, this would be a way more compatible solution. First drawback: I dont know the dash code, so this maybe wont be easy to implement Second drawback: A consequence would be a change "app.layout" to the formal better "app.children" to make the app a proper parent. kr, Tx.