Adding CSS & JS and Overriding the Page-Load Template

Dash applications are rendered in the web browser with CSS and JavaScript.
On page load, Dash serves a small HTML template that includes references to
the CSS and JavaScript that are required to render the application.
This chapter covers everything that you need to know about configuring
this HTML file and about including external CSS and JavaScript in Dash
applications.

Table of Contents
- Adding Your Own CSS and JavaScript to Dash Apps
- Embedding Images in Your Dash Apps
- Changing the Favicon
- Adding External CSS and JavaScript
- Customizing Dash’s HTML Index Template
- Adding Meta Tags
- Serving Dash’s Component Libraries Locally or from a CDN
- Sample Dash CSS Stylesheet


Adding Your Own CSS and JavaScript to Dash Apps

New in dash 0.22.0

Including custom CSS or JavaScript in your Dash apps is simple.
Just create a folder named assets in the root of your app directory
and include your CSS and JavaScript
files in that folder. Dash will automatically serve all of the files that
are included in this folder. By default the url to request the assets will
be /assets but you can customize this with the assets_url_path argument
to dash.Dash.

Important: For these examples, you need to include __name__ in your Dash constructor.

That is, app = dash.Dash(__name__) instead of app = dash.Dash(). Here’s why.

Example: Including Local CSS and JavaScript

We’ll create several files: app.py, a folder named assets, and
three files in that folder:

- app.py
- assets/
    |-- typography.css
    |-- header.css
    |-- custom-script.js

 

app.py

import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([
    html.Div(
        className="app-header",
        children=[
            html.Div('Plotly Dash', className="app-header--title")
        ]
    ),
    html.Div(
        children=html.Div([
            html.H5('Overview'),
            html.Div('''
                This is an example of a simple Dash app with
                local, customized CSS.
            ''')
        ])
    )
])

if __name__ == '__main__':
    app.run_server(debug=True)

typography.css

body {
    font-family: sans-serif;
}
h1, h2, h3, h4, h5, h6 {
    color: hotpink
}

header.css

.app-header {
    height: 60px;
    line-height: 60px;
    border-bottom: thin lightgrey solid;
}

.app-header .app-header--title {
    font-size: 22px;
    padding-left: 5px;
}

custom-script.js

alert('If you see this alert, then your custom JavaScript script has run!')

When you run app.py, your app should look something like this:
(Note that there may be some slight differences in appearance as
the CSS from this Dash User Guide is applied to all of these embedded
examples.)

Plotly Dash
Overview
This is an example of a simple Dash app with local, customized CSS.

There are a few things to keep in mind when including assets automatically:

1 - The following file types will automatically be included:

A - CSS files suffixed with .css

B - JavaScript files suffixed with .js

C - A single file named favicon.ico (the page tab’s icon)

2 - Dash will include the files in alphanumerical order by filename.
So, we recommend prefixing your filenames with numbers if you need to ensure
their order (e.g. 10_typography.css, 20_header.css)

3 - You can ignore certain files in your assets folder with a regex filter
using app = dash.Dash(assets_ignore='.*ignored.*'). This will prevent Dash from
loading files which contain the above pattern.

4 - If you want to include CSS from a remote URL, then see the next section.

5 - Your custom CSS will be included after the Dash component CSS

6 - It is recommended to add __name__ to the dash init to ensure the resources
in the assets folder are loaded, eg: app = dash.Dash(__name__, meta_tags=[...]).
When you run your application through some other command line (like the
flask command or gunicorn/waitress), the __main__ module will no
longer be located where app.py is. By explicitly setting __name__,
Dash will be able to locate the relative assets folder correctly.

Hot Reloading

By default, Dash includes “hot-reloading”. This means that Dash will automatically refresh your browser when you make a change in your Python code and your CSS code.

Give it a try: Change the color in typography.css from hotpink to orange and see your application update.

Don’t like hot-reloading? You can turn this off with app.run_server(dev_tools_hot_reload=False).
Learn more in Dash Dev Tools documentation. Questions? See the community forum hot reloading discussion.


Load Assets from a Folder Hosted on a CDN

If you duplicate the file structure of your local assets folder to a folder hosted
externally to your Dash app, you can use assets_external_path='http://your-external-assets-folder-url'
in the Dash constructor to load the files from there instead of locally. Dash will index your local
assets folder to find all of your assets, map their relative path onto assets_external_path
and then request the resources from there.
app.scripts.config.serve_locally = False must also be set in order for this to work.

NOTE: In Dash 0.43.0 and before, app.scripts.config.serve_locally = False
was the default, except when dev bundles are served (such as during debugging).
Starting with Dash 1.0.0, serve_locally defaults to True.

Example:

import dash
import dash_html_components as html

app = dash.Dash(
    __name__,
    assets_external_path='http://your-external-assets-folder-url/'
)
app.scripts.config.serve_locally = False

Embedding Images in Your Dash Apps

In addition to CSS and javascript files, you can include images in
the assets folder. An example of the folder structure:

- app.py
- assets/
    |-- image.png

 

In your app.py file you can use the relative path to that image:

import dash
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([
    html.Img(src='/assets/image.png')
])

if __name__ == '__main__':
    app.run_server(debug=True)

Changing the Favicon

It is possible to override the default favicon by adding
a file named favicon.ico to your /assets folder. Changes to
this file will implement cache-busting automatically.

- app.py
- assets/
    |-- favicon.ico


Adding external CSS/Javascript

You can add resources hosted externally to your Dash app with the
external_stylesheets/stylesheets init keywords.

The resources can be either a string or a dict containing the tag attributes
(src, integrity, crossorigin, etc). You can mix both.

External css/js files are loaded before the assets.

Example:

import dash
import dash_html_components as html


# external JavaScript files
external_scripts = [
    'https://www.google-analytics.com/analytics.js',
    {'src': 'https://cdn.polyfill.io/v2/polyfill.min.js'},
    {
        'src': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.core.js',
        'integrity': 'sha256-Qqd/EfdABZUcAxjOkMi8eGEivtdTkh3b65xCZL4qAQA=',
        'crossorigin': 'anonymous'
    }
]

# external CSS stylesheets
external_stylesheets = [
    'https://codepen.io/chriddyp/pen/bWLwgP.css',
    {
        'href': 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css',
        'rel': 'stylesheet',
        'integrity': 'sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO',
        'crossorigin': 'anonymous'
    }
]


app = dash.Dash(__name__,
                external_scripts=external_scripts,
                external_stylesheets=external_stylesheets)

app.layout = html.Div()

if __name__ == '__main__':
    app.run_server(debug=True)


Customizing Dash’s HTML Index Template

New in dash 0.22.0

Dash’s UI is generated dynamically with Dash’s React.js front-end. So,
on page load, Dash serves a very small HTML template string that includes
the CSS and JavaScript that is necessary to render the page and some simple
HTML meta tags.

This simple HTML string is customizable. You might want to customize this
string if you wanted to:
- Include a different <title> for your app (the <title> tag is the name
that appears in your brower’s tab. By default, it is “Dash”)
- Customize the way that your CSS or JavaScript is included in the page.
For example, if you wanted to include remote scripts or if you wanted to
include the CSS before the Dash component CSS
- Include custom meta tags in your app. Note that meta tags can also be
added with the meta_tags argument (example below).
- Include a custom version of dash-renderer, by instantiating the
DashRenderer class yourself. You can add request hooks this way, by providing
a hooks config object as in the example below.

Usage

Option 1 - index_string

Add an index_string to modify the default HTML Index Template:

import dash
import dash_html_components as html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.index_string = '''
<!DOCTYPE html>
&lt;html&gt;
    &lt;head&gt;
        {%metas%}
        &lt;title&gt;{%title%}&lt;title&gt;
        {%favicon%}
        {%css%}
    &lt;head&gt;
    &lt;body&gt;
        &lt;div&gt;My Custom header&lt;div&gt;
        {%app_entry%}
        &lt;footer&gt;
            {%config%}
            {%scripts%}
            {%renderer%}
        &lt;footer&gt;
        &lt;div&gt;My Custom footer&lt;div&gt;
    &lt;body&gt;
&lt;html&gt;
'''

app.layout = html.Div('Simple Dash App')

if __name__ == '__main__':
    app.run_server(debug=True)

The {%key%}s are template variables that Dash will fill in automatically
with default properties. The available keys are:

{%metas%} (optional)

The registered meta tags included by the meta_tags argument in dash.Dash

{%favicon%} (optional)

A favicon link tag if found in the assets folder.

{%css%} (optional)

&lt;link&gt; tags to css resources. These resources include the Dash component
library CSS resources as well as any CSS resources found in the assets folder.

{%title%} (optional)

The contents of the page &lt;title&gt; tag.
Learn more about &lt;title&gt;

{%config%} (required)

An auto-generated tag that includes configuration settings passed from
Dash’s backend to Dash’s front-end (dash-renderer).

{%app_entry%} (required)

The container in which the Dash layout is rendered.

{%scripts%} (required)

The set of JavaScript scripts required to render the Dash app.
This includes the Dash component JavaScript files as well as any
JavaScript files found in the assets folder.

{%renderer%} (required)

The JavaScript script that instantiates dash-renderer by calling
new DashRenderer()

Option 2 - interpolate_index

If your HTML content isn’t static or if you would like to introspect or modify
the templated variables, then you can override the Dash.interpolate_index
method.

import dash
import dash_html_components as html


class CustomDash(dash.Dash):
    def interpolate_index(self, **kwargs):
        # Inspect the arguments by printing them
        print(kwargs)
        return '''
        <!DOCTYPE html>
        &lt;html&gt;
            &lt;head&gt;
                &lt;title&gt;My App&lt;title&gt;
            &lt;head&gt;
            &lt;body&gt;

                &lt;div&gt;My custom header&lt;div&gt;
                {app_entry}
                {config}
                {scripts}
                {renderer}
                &lt;div&gt;My custom footer&lt;div&gt;
            &lt;body&gt;
        &lt;html&gt;
        '''.format(
            app_entry=kwargs['app_entry'],
            config=kwargs['config'],
            scripts=kwargs['scripts'],
            renderer=kwargs['renderer'])

app = CustomDash()

app.layout = html.Div('Simple Dash App')

if __name__ == '__main__':
    app.run_server(debug=True)

Unlike the index_string method, where we worked with template string
variables, the keyword variables that are passed into interpolate_index
are already evaluated.

In the example above, when we print the input arguments of
interpolate_index we should see an output like this:

{
    'title': 'Dash',
    'app_entry': '\n&lt;div&gt;\n    &lt;div&gt;\n        Loading...\n    &lt;div&gt;\n&lt;div&gt;\n',
    'favicon': '',
    'metas': '&lt;meta&gt;',
    'scripts': '&lt;script&gt;&lt;script&gt;\n&lt;script&gt;&lt;script&gt;\n&lt;script&gt;&lt;script&gt;\n&lt;script&gt;&lt;script&gt;',
    'renderer': '&lt;script&gt;var renderer = new DashRenderer();&lt;script&gt;',
    'config': '&lt;script&gt;{"requests_pathname_prefix": "/", "url_base_pathname": "/"}&lt;script&gt;',
    'css': ''
}

The values of the scripts and css keys may be different depending on
which component libraries you have included or which files
might be in your assets folder.


Customizing dash-renderer with request hooks

To instantiate your own version of dash-renderer, you can override Dash’s HTML Index Template and provide your own script that will be used instead of the standard script. This script should
somewhere call var renderer = new DashRenderer();, which instantiates the DashRenderer class. You can add this script to your index HTML when you’re setting
app.index_string, or you could simply override app.renderer like so:

import dash
import dash_html_components as html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.renderer = 'var renderer = new DashRenderer();'

app.layout = html.Div('Simple Dash App')

if __name__ == '__main__':
    app.run_server(debug=True)

When you provide your own DashRenderer, you can also pass in a hooks object that holds request_pre and request_post functions. These request hooks will be fired
before and after Dash makes a request to its backend. Here’s an example:

import dash
import dash_html_components as html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.renderer = '''
var renderer = new DashRenderer({
    request_pre: (payload) => {
        // print out payload parameter
        console.log(payload);
    },
    request_post: (payload, response) => {
        // print out payload and response parameter
        console.log(payload);
        console.log(response);
    }
})
'''

app.layout = html.Div('Simple Dash App')

if __name__ == '__main__':
    app.run_server(debug=True)

Notice the request_pre function takes the payload of the request being sent as its argument, and the request_post fuction takes both the payload and the response of the server
as arguments. These can be altered in our function, allowing you to modify the response and request objects that Dash sends to the server. In the example above, the request_pre
function is fired before each server call, and in the case of this example, it will console.log() the request parameter. The request_post function will fire after each server
call, and in our example will also print out the response parameter.


Customizing Meta Tags

Not sure what meta tags are?
Check out this tutorial on meta tags and why you might want to use them.

To add custom meta tags to your application, you can always override Dash’s
HTML Index Template. Alternatively, Dash provides a shortcut:
you can specify meta tags directly in the Dash constructor:

import dash
import dash_html_components as html

app = dash.Dash(meta_tags=[
    # A description of the app, used by e.g.
    # search engines when displaying search results.
    {
        'name': 'description',
        'content': 'My description'
    },
    # A tag that tells Internet Explorer (IE)
    # to use the latest renderer version available
    # to that browser (e.g. Edge)
    {
        'http-equiv': 'X-UA-Compatible',
        'content': 'IE=edge'
    },
    # A tag that tells the browser not to scale
    # desktop widths to fit mobile screens.
    # Sets the width of the viewport (browser)
    # to the width of the device, and the zoom level
    # (initial scale) to 1.
    #
    # Necessary for "true" mobile support.
    {
      'name': 'viewport',
      'content': 'width=device-width, initial-scale=1.0'
    }
])

app.layout = html.Div('Simple Dash App')

if __name__ == '__main__':
    app.run_server(debug=True)

If you inspect the source of your app, you should see the meta tags appear:

Dash App with Custom Meta Tags

Serving Dash’s Component Libraries Locally or from a CDN

Changed in Dash 1.0.0 - now serve_locally defaults to True,
previously it defaulted to False

Dash’s component libraries, like dash_core_components and dash_html_components,
are bundled with JavaScript and CSS files. Dash automatically checks with
component libraries are being used in your application and will automatically
serve these files in order to render the application.

By default, dash serves the JavaScript and CSS resources from the
local files on the server where Dash is running. This is the more flexible
and robust option: in some cases, such as firewalled or airgapped
environments, it is the only option. It also avoids some hard-to-debug
problems like packages that have not been published to NPM or CDN downtime,
and the unlikely but possible scenario of the CDN being hacked. And of
course, component developers will want the local version while changing the
code, so when dev bundles are requested (such as with debug=True) we
always serve locally.

However, for performance-critical apps served beyond an intranet, online
CDNs can often deliver these files much faster than loading the resources
from the file system, and will reduce the load on the Dash server.

Here’s how to enable CDN serving. app.scripts is the most important one,
that controls the JavaScript files, but app.css can sometimes help too:

```python
from dash import Dash

app = Dash()

app.css.config.serve_locally = False
app.scripts.config.serve_locally = False

Note that in the future, we will likely make “offline” the default option.
Follow dash#284 for more information.


Sample Dash CSS Stylesheet

Currently, Dash does not include styles by default.

To get started with Dash styles, we recommend starting with this CSS stylesheet hosted
on Codepen.

To include this stylesheet in your application, copy and paste it into a file
in your assets folder. You can view the raw CSS source here:
https://codepen.io/chriddyp/pen/bWLwgP.css.

Here is an embedded version of this stylesheet.


Syntax Highlighting With Markdown

Both dash-table and
dash-core-components
support markdown formatting; this includes syntax highlighting for
inline code.

Highlighting is taken care of by
highlight.js. By default, only
certain languages are recognized, and there is only one color
scheme available. However, you can override this by downloading a
custom highlight.js package. To do this, visit
https://highlightjs.org/download/,
and in the “Custom package” section, check off all of the
languages that you require, download your package, and place the
resultant highlight.pack.js file into the assets/ folder for
your app. The package should also come with a styles/ directory;
to use a different color scheme, simply copy the corresponding
stylesheet into your app’s assets/ folder.