Installs into .claude/skills of the current project.
Are you the author of App Callback Workflows?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/vectorspacelab-app-callback-workflows)
---
name: app-callback-workflows
description: "Use for Plotly Dash app layouts, callbacks, pages, assets,
configuration, clientside callbacks, Jupyter display, CSP, and app-level
debugging."
disable-model-invocation: true
metadata:
disco-role: operating
license: MIT
---
# Dash App and Callback Workflows
Use this sub-skill when a task is about using Dash as an application framework:
creating layouts, registering callbacks, debugging ID/dependency validation,
configuring pages/assets, or moving work into clientside callbacks.
## Start here
1. For layout and callback API details, read
[references/callbacks-and-layouts.md](references/callbacks-and-layouts.md).
2. For pages, URL prefixes, assets, dev tools, Jupyter, and CSP, read
[references/pages-assets-and-config.md](references/pages-assets-and-config.md).
3. For browser-side callback functions, read
[references/clientside-callbacks.md](references/clientside-callbacks.md).
4. For common failures, read
[references/troubleshooting.md](references/troubleshooting.md).
5. Run [scripts/smoke_dash_app.py](scripts/smoke_dash_app.py) for a no-browser
import/layout/callback smoke check and
[scripts/smoke_pages_app.py](scripts/smoke_pages_app.py) for a page-registry
smoke check.
## Main routes
### Build a basic app
Use `Dash`, component modules, and a component tree:
```python
from dash import Dash, html, dcc
app = Dash(__name__)
app.layout = html.Div([
dcc.Input(id="input", value="initial"),
html.Div(id="output"),
])
```
Important rules:
- Layout children must be Dash components, strings, numbers, `None`, or lists of
those values. Raw arbitrary dicts are not valid component children.
- Component IDs can be strings or dictionaries. Use dictionary IDs for
pattern-matching callbacks.
- If a layout is generated dynamically, either ensure callback components exist
in the initial validation layout or configure dynamic-layout behavior
deliberately.
### Register server-side callbacks
Use `@app.callback` when you have an app object and `@dash.callback` when you
need module-level callback registration. Core dependency classes are `Output`,
`Input`, and `State`.
```python
from dash import Input, Output, State, callback, no_update
from dash.exceptions import PreventUpdate
@callback(Output("output", "children"), Input("input", "value"), State("store", "data"))
def update(value, stored):
if value is None:
raise PreventUpdate
if value == "keep":
return no_update
return f"{value}: {stored}"
```
Use [callback troubleshooting](references/troubleshooting.md) when callbacks do
not fire, fire too early, reference missing components, or form circular
dependencies.
### Use pattern-matching IDs
Route to dictionary IDs and wildcards when components are generated from data:
```python
from dash import MATCH, ALL, Input, Output
@app.callback(
Output({"type": "row-output", "index": MATCH}, "children"),
Input({"type": "row-input", "index": MATCH}, "value"),
)
def per_row(value):
return value
```
Use `MATCH` for one-to-one dynamic pairs, `ALL` for all matching components, and
`ALLSMALLER` when a callback needs earlier indexed values.
### Inspect callback context
Use `dash.ctx` or `dash.callback_context` inside callbacks for trigger metadata:
- `ctx.triggered_id` gives the component ID that triggered the callback.
- `ctx.triggered_prop_ids` maps changed `id.property` strings to IDs.
- `ctx.args_grouping` is useful with flexible callback signatures.
- `ctx.response` lets a callback set response cookies/headers in supported
backends.
- `ctx.websocket` is only available for WebSocket callbacks; route those tasks
to [server backends and async](../server-backends-and-async/SKILL.md).
### Use pages, assets, and URL prefixes
Use `Dash(__name__, use_pages=True)` plus `dash.register_page` and
`dash.page_container` for multi-page apps. Read
[pages-assets-and-config.md](references/pages-assets-and-config.md) before
changing URL prefixes, asset loading, or Jupyter display behavior.
### Move simple work clientside
Use clientside callbacks for simple browser-side transformations, browser
storage access, or UI work that should avoid a server round trip. Read
[clientside-callbacks.md](references/clientside-callbacks.md) for namespace
registration, `no_update`, `PreventUpdate`, and `set_props` behavior.
## Route elsewhere
- Background callbacks, async callbacks, WebSocket callbacks, backend classes,
Dash hooks, and MCP: [server-backends-and-async](../server-backends-and-async/SKILL.md).
- Component generation, renderer internals, React resource loading, and
`dash_component_api`: [component-renderer-development](../component-renderer-development/SKILL.md).
- Running Dash tests or choosing commands: [testing-and-maintenance](../testing-and-maintenance/SKILL.md).
## Validation checklist
Before declaring an app/callback fix complete:
- The app imports `Dash`, `html`, `dcc`, and dependency classes from `dash`.
- Every callback component ID exists in the layout, validation layout, or a
deliberate dynamic-layout configuration.
- Callback return shape matches the Output grouping.
- Browser console is clean for browser-backed tasks.
- If assets, pages, or URL prefixes changed, the generated URLs use
`app.get_asset_url`, `dash.get_relative_path`, or the app's configured
prefix-aware helpers.