Layouts
gui.div, gui.tag, gui.columns, gui.center, gui.expander, sidebar_layout
gui.columns ā Equal columns
gui.columns ā Weighted columns
gui.center
Centered content
Both horizontally and vertically
gui.div & gui.tag
gui.tag('span')any HTML tageven inline elements
sidebar_layout ā Collapsible sidebar
This page itself uses sidebar_layout for the left navigation panel.
Pattern used on this page:
from widgets.sidebar import sidebar_layout
# In your route handler:
sidebar, page_content = sidebar_layout(
key="my-sidebar",
session=request.session,
)
with sidebar:
# Sidebar content ā nav links, filters, etc.
gui.write("**Navigation**")
for section in sections:
with gui.tag("a", href=f"#section-{section.id}"):
gui.html(section.label)
with page_content:
# Main page content
render_page()
Open / close via JavaScript events:
// Open the sidebar
window.dispatchEvent(new Event('my-sidebar:open'))
// Close the sidebar
window.dispatchEvent(new Event('my-sidebar:close'))
Try it:
def demo_sidebar():
"""sidebar_layout returns (sidebar, page_content) context managers. Open/close via JS events."""
gui.write("This page itself uses `sidebar_layout` for the left navigation panel.")
gui.newline()
gui.write("**Pattern used on this page:**")
gui.write(
"```python\n"
"from widgets.sidebar import sidebar_layout\n"
"\n"
"# In your route handler:\n"
"sidebar, page_content = sidebar_layout(\n"
' key="my-sidebar",\n'
" session=request.session,\n"
")\n"
"\n"
"with sidebar:\n"
" # Sidebar content ā nav links, filters, etc.\n"
' gui.write("**Navigation**")\n'
" for section in sections:\n"
' with gui.tag("a", href=f"#section-{section.id}"):\n'
" gui.html(section.label)\n"
"\n"
"with page_content:\n"
" # Main page content\n"
" render_page()\n"
"```",
unsafe_allow_html=True,
)
gui.newline()
gui.write("**Open / close via JavaScript events:**")
gui.write(
"```javascript\n"
"// Open the sidebar\n"
"window.dispatchEvent(new Event('my-sidebar:open'))\n"
"\n"
"// Close the sidebar\n"
"window.dispatchEvent(new Event('my-sidebar:close'))\n"
"```",
unsafe_allow_html=True,
)
gui.newline()
open_js = f"window.dispatchEvent(new Event('{SIDEBAR_KEY}:open'))"
close_js = f"window.dispatchEvent(new Event('{SIDEBAR_KEY}:close'))"
gui.write("**Try it:**")
with gui.div(className="d-flex gap-2"):
with gui.tag("button", className="btn btn-sm btn-primary", onClick=open_js):
gui.html('<i class="fa-solid fa-bars"></i> Open sidebar')
with gui.tag(
"button", className="btn btn-sm btn-outline-secondary", onClick=close_js
):
gui.html('<i class="fa-solid fa-xmark"></i> Close sidebar')
Content & Text
gui.write, gui.markdown, gui.text, gui.html, gui.caption, gui.error, gui.success
gui.write ā Primary output (supports Markdown)
Bold, italic, and inline code
gui.html ā Raw HTML
Raw HTML with inline stylesgui.error & gui.success
ā
Operation completed successfully!
š„
Something went wrong, please try again.
gui.markdown ā Explicit Markdown block
Markdown heading
- List item one
- List item two
> Blockquote text
gui.text ā Preformatted text
This is preformatted text.
Indentation is preserved.
Like a <pre> block.gui.caption & gui.newline
Regular text above
This is a caption ā small and muted
After a gui.newline() break
Headings via gui.write
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Icons
Font Awesome 6 ā use tags with gui.html()
Icons in buttons
def demo_icons_in_buttons():
"""Combine icons with text in buttons using gui.button or gui.anchor."""
with gui.div(className="d-flex gap-2 flex-wrap"):
gui.button(
'<i class="fa-solid fa-plus"></i> Create',
key="demo_icon_btn_create",
type="primary",
)
gui.button(
'<i class="fa-solid fa-trash"></i> Delete',
key="demo_icon_btn_delete",
type="tertiary",
)
gui.button(
'<i class="fa-regular fa-download"></i> Download',
key="demo_icon_btn_download",
)
gui.anchor(
'<i class="fa-solid fa-arrow-up-right-from-square"></i> Open link',
href="https://fontawesome.com/search",
type="link",
new_tab=True,
unsafe_allow_html=True,
)
Navigation
gui.tabs, gui.controllable_tabs, gui.nav_tabs, gui.breadcrumbs
gui.tabs ā Rounded tabs
gui.nav_tabs ā Underline tabs
Content for the active tab
gui.controllable_tabs
Text Inputs
gui.text_input, gui.text_area, gui.password_input, gui.code_editor
gui.horizontal_radio
Output format
gui.button ā All types
def demo_buttons():
"""Button variants: primary, secondary, tertiary, link."""
with gui.div(className="d-flex gap-2 flex-wrap align-items-center"):
gui.button("Primary", key="demo_btn_primary", type="primary")
gui.button("Secondary", key="demo_btn_secondary")
gui.button("Tertiary", key="demo_btn_tertiary", type="tertiary")
gui.button("Link", key="demo_btn_link", type="link")
gui.button("Disabled", key="demo_btn_disabled", disabled=True)
gui.download_button
gui.download_button(label, url) ā renders a download link styled as a button.
gui.image
Random image via picsum.photos

gui.video
š„ Random video via YouTube
gui.audio
š§ Random audio
Overlays & Feedback
gui.tooltip, gui.popover, gui.pill, gui.modal_scaffold, gui.alert_dialog, gui.confirm_dialog
gui.pill
DefaultPrimarySecondaryDark
gui.alert_dialog
gui.button_with_confirm_dialog
Data Display
gui.table, gui.data_table, gui.json, gui.plotly_chart
gui.json ā Interactive JSON viewer
def demo_json():
"""Interactive, collapsible JSON viewer."""
gui.json(
{
"name": "Gooey.AI",
"components": 45,
"features": ["server-driven UI", "Bootstrap 5", "realtime updates"],
"nested": {"key": "value", "list": [1, 2, 3]},
},
expanded=True,
)
gui.data_table
Loading...
def demo_data_table():
"""Data table from a list of cell values."""
gui.data_table(
[
["Component", "Category", "Status"],
["gui.button", "Buttons", "Stable"],
["gui.switch", "Inputs", "Stable"],
["gui.styled", "Styling", "Stable"],
]
)
gui.plotly_chart
gui.plotly_chart(figure_or_data) ā pass a Plotly figure object or dict.
Requires plotly to be installed.
Styling & Scripting
gui.styled, gui.js, and Bootstrap 5 className
gui.styled ā Scoped CSS with & selector
This container has scoped gradient styles via gui.styled()Bootstrap 5 className
bg-dark + text-white + rounded
border-primary
bg-light + shadow-sm + fw-bold
gui.js ā Inject JavaScript
gui.js(src, **kwargs) injects a <script> tag. Used internally to load GooeyEmbed and other JS widgets.
State Management
gui.session_state
gui.session_state ā Per-user state dict
All input components automatically read from and write to gui.session_state.
# Read a value
name = gui.session_state.get('user_name', 'default')
# Write a value
gui.session_state['user_name'] = 'Alice'
# Use with inputs ā the key links the widget to state
gui.text_input('Name', key='user_name')