nteract elements

OutputArea

Wrapper component for rendering multiple Jupyter outputs with collapsible state and scroll behavior

Processing data... Loading model...

OutputArea handles rendering multiple Jupyter outputs with:

  • Output type routing - Automatically routes to the right renderer for each output type
  • Secure isolation - HTML, Markdown, SVG, and widgets render in sandboxed iframes
  • Collapsible state - Toggle output visibility with a collapse button
  • Scroll behavior - Set maxHeight to enable scrolling for large outputs
  • Empty state - Renders nothing when there are no outputs

Installation

npx shadcn@latest add @nteract/output-area

New to @nteract? pnpm dlx shadcn@latest registry add @nteract

Copy from nteract/elements.

Usage

import { OutputArea } from "@/components/cell/OutputArea"

export function CellWithOutputs({ cell }) {
  const [collapsed, setCollapsed] = useState(false)

  return (
    <OutputArea
      outputs={cell.outputs}
      collapsed={collapsed}
      onToggleCollapse={() => setCollapsed(!collapsed)}
      maxHeight={400}
    />
  )
}

Examples

Simple Output

42
<OutputArea outputs={[{
  output_type: "execute_result",
  data: { "text/plain": "42" },
  execution_count: 1,
}]} />

Stream and Result

Processing data... Loading model...
<OutputArea outputs={[
  {
    output_type: "stream",
    name: "stdout",
    text: "Processing data...\nLoading model...\n",
  },
  {
    output_type: "execute_result",
    data: { "text/plain": "{'accuracy': 0.95}" },
    execution_count: 2,
  },
]} />

Error Output

ValueError: invalid literal for int() with base 10: 'hello'
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[1], line 1 ----> 1 int('hello') ValueError: invalid literal for int() with base 10: 'hello'
<OutputArea outputs={[{
  output_type: "error",
  ename: "ValueError",
  evalue: "invalid literal for int()",
  traceback: ["..."],
}]} />

Collapsible

Processing data... Loading model...
const [collapsed, setCollapsed] = useState(false)

<OutputArea
  outputs={outputs}
  collapsed={collapsed}
  onToggleCollapse={() => setCollapsed(!collapsed)}
/>

With Max Height

Processing data... Loading model...
Processing data... Loading model...
Processing data... Loading model...
<OutputArea
  outputs={largeOutputs}
  maxHeight={150}
/>

Output Types

OutputArea handles all Jupyter output types:

TypeDescriptionRenderer
execute_resultCell execution resultMediaRouter
display_dataRich display outputMediaRouter
streamstdout/stderr textAnsiStreamOutput
errorException tracebackAnsiErrorOutput

Isolated Rendering

HTML outputs render inside a sandboxed iframe for security:

Certain output types can contain executable JavaScript and must be rendered in a secure iframe:

MIME TypeWhy Isolation
text/htmlCan contain <script> tags
text/markdownRendered HTML may include scripts
image/svg+xmlSVG can contain embedded scripts
application/vnd.jupyter.widget-view+jsonWidgets run JavaScript
application/vnd.plotly.v1+jsonPlotly runs JavaScript
application/vnd.vegalite.*Vega-Lite runs JavaScript

By default (isolated="auto"), OutputArea automatically detects when isolation is needed and renders those outputs in an IsolatedFrame.

Widget Output in Iframe

Widgets are rendered inside the isolated iframe. The widget state syncs between parent and iframe via the CommBridge:

Loading widget...

OutputWidget (ipywidgets.Output) in Iframe

The OutputWidget captures outputs like ipywidgets.Output(). When it contains HTML content, the whole widget renders in an iframe:

Loading widget...

Force Isolation Mode

// Always use iframe (most secure)
<OutputArea outputs={outputs} isolated={true} />

// Auto-detect (default) - uses iframe only when needed
<OutputArea outputs={outputs} isolated="auto" />

// Never use iframe (fastest, but less secure)
<OutputArea outputs={outputs} isolated={false} />

Preload Iframe

For instant output rendering, preload the iframe before outputs arrive:

<OutputArea
  outputs={[]}
  preloadIframe={true}  // Bootstrap iframe ahead of time
/>

Links clicked inside isolated outputs fire the onLinkClick callback:

<OutputArea
  outputs={htmlOutputs}
  onLinkClick={(url, newTab) => {
    // Handle link click (e.g., open in browser)
    window.open(url, newTab ? "_blank" : "_self")
  }}
/>

Props

PropTypeDefaultDescription
outputsJupyterOutput[]Array of Jupyter outputs to render
collapsedbooleanfalseWhether outputs are collapsed
onToggleCollapse() => voidCallback when collapse is toggled
maxHeightnumberMaximum height in pixels before scrolling
classNamestringAdditional CSS classes
renderersRecord<string, CustomRenderer>Custom renderers for MediaRouter
priorityreadonly string[]MIME type priority for MediaRouter
isolatedboolean | "auto""auto"Force isolation mode (true), auto-detect ("auto"), or disable (false)
preloadIframebooleanfalsePre-create iframe for instant rendering
onLinkClick(url: string, newTab: boolean) => voidCallback when link is clicked in isolated output
onWidgetUpdate(commId: string, state: object) => voidWidget state update callback (deprecated)

JupyterOutput Type

type JupyterOutput =
  | {
      output_type: "execute_result" | "display_data";
      data: Record<string, unknown>;
      metadata?: Record<string, unknown>;
      execution_count?: number | null;
    }
  | {
      output_type: "stream";
      name: "stdout" | "stderr";
      text: string | string[];
    }
  | {
      output_type: "error";
      ename: string;
      evalue: string;
      traceback: string[];
    };

On this page