HTML#

Open this notebook in Jupyterlite | Download this notebook from GitHub (right-click to download).


import panel as pn

pn.extension()

The HTML pane allows rendering arbitrary HTML in a panel. It renders strings containing valid HTML as well as objects with a _repr_html_ method and may define custom CSS styles.

Parameters:#

For details on other options for customizing the component see the layout and styling how-to guides.

  • disable_math (boolean, default=True): Whether to disable MathJax math rendering for strings escaped with $$ delimiters.

  • enable_streaming (boolean, default=False): Whether to enable streaming of text updates. When enabled, each update to object is diffed against the previous value and only the changed portion is sent to the frontend, which is useful when text is built up incrementally, e.g. in a chat message.

  • object (str or object): The string or object with _repr_html_ method to display.

  • sanitize_html (boolean, default=False): Whether to sanitize HTML sent to the frontend.

  • sanitize_hook (Callable, default=nh3.clean): Sanitization callback to apply if sanitize_html=True.


The HTML pane accepts the entire HTML5 spec including any embedded script tags, which will be executed. The styles parameter accepts a dictionary of CSS properties which are applied to the <div> the HTML contents are rendered in.

styles = {
    'background-color': '#F6F6F6', 'border': '2px solid black',
    'border-radius': '5px', 'padding': '10px'
}

html_pane = pn.pane.HTML("""
<h1>This is an HTML pane</h1>

<code>
x = 5;<br>
y = 6;<br>
z = x + y;
</code>

<br>
<br>

<table>
  <tr>
    <th>Firstname</th>
    <th>Lastname</th> 
    <th>Age</th>
  </tr>
  <tr>
    <td>Jill</td>
    <td>Smith</td> 
    <td>50</td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td> 
    <td>94</td>
  </tr>
</table>
""", styles=styles)

html_pane

To update the object or styles, set the corresponding parameter:

html_pane.styles = dict(html_pane.styles, border='2px solid red')

Sanitizing HTML#

The HTML pane renders its content as is, including <script> tags and inline event handlers. When displaying HTML from an untrusted source, such as user input, set sanitize_html=True to strip unsafe elements and attributes using nh3 before the HTML is sent to the browser:

untrusted = """
<p>Hello <b>world</b>, here is a <a href="https://panel.holoviz.org" onclick="alert('Clicked!')">link</a>.</p>
<script>alert('Injected!')</script>
"""

sanitized = pn.pane.HTML(untrusted, sanitize_html=True)

print(sanitized.sanitize_hook(untrusted))

sanitized
<p>Hello <b>world</b>, here is a <a href="https://panel.holoviz.org" rel="noopener noreferrer">link</a>.</p>


A custom sanitize_hook can be provided to control exactly which tags and attributes are allowed. Here only <p> tags are kept:

import nh3

pn.pane.HTML(untrusted, sanitize_html=True, sanitize_hook=lambda html: nh3.clean(html, tags={'p'}))

HTML Documents#

The HTML pane is designed to insert HTML fragments into the page. Complete HTML documents, such as a standalone plot exported to an .html file, come with their own <head>, scripts and styles, which can conflict with the surrounding page.

To display a complete HTML document, escape its content and embed it in an iframe using the srcdoc attribute:

import html
from io import StringIO

import hvplot.pandas
import numpy as np
import pandas as pd

np.random.seed(1)

idx = pd.date_range("1/1/2000", periods=1000)
df = pd.DataFrame(np.random.randn(1000, 4), index=idx, columns=list("ABCD")).cumsum()

plot = df.hvplot()

# Save to a StringIO object to avoid writing a file to disk
plot_file = StringIO()
hvplot.save(plot, plot_file)
plot_file.seek(0)

escaped_html = html.escape(plot_file.read())

iframe_html = f'<iframe srcdoc="{escaped_html}" style="height:100%; width:100%" frameborder="0"></iframe>'

pn.pane.HTML(iframe_html, height=350, sizing_mode="stretch_width")

The iframe renders the document in its own isolated browsing context, so its scripts and styles cannot interfere with the rest of the Panel application. This is particularly useful for embedding standalone exports, such as interactive visualizations saved to HTML.


Open this notebook in Jupyterlite | Download this notebook from GitHub (right-click to download).