dash-documentation-boilerplateβ the markdown-driven documentation template every*.2plot.devcomponent site is forked from. By Pip Install Python.
Live: boilerplate.2plot.dev Β· the template every 2plot.dev component documentation site is built from.
A comprehensive boilerplate for creating beautiful, interactive documentation for your Dash components, data science workflows, and applications. Features markdown-driven content, live code examples, and automatic theme persistence.
- Write documentation in Markdown with Python integration
- Custom directives for interactive examples, code highlighting, and component props
- Automatic page generation from markdown files with frontmatter metadata
- Table of contents generation for easy navigation
- Built with Dash Mantine Components
- Responsive design for mobile, tablet, and desktop
- Dark and light theme support with automatic preference persistence
- Smooth transitions and professional styling
- Customizable color schemes and theming
- Hot reload during development
- Searchable component navigation
- Syntax highlighting for multiple languages
- Interactive code examples with live callbacks
- Component props documentation auto-generation
LLMS_DOCpattern β write a module-level prose string per page; served verbatim at/<page>/llms.txt- Multi-backend β
add_llms_routes(app)auto-detects Flask, FastAPI, or Quart and dispatches to the matching adapter - MCP bridge β each page's prose registers as a
dash.mcpresource on Dash 4.3+ (silent no-op otherwise) - SEO β
sitemap.xmlwith intelligent priority inference; respectsmark_hidden() - Bot management β training crawlers blocked (configurable), AI search citations allowed, browsers untouched
- Privacy controls β
mark_hidden()to exclude pages from sitemap, robots, MCP, and crawler prerender - Share with AI β paste the app URL into ChatGPT/Claude/etc.; they fetch the prose docs directly
- Cross-host network directory β
lib/network_directory.pypublishes the sibling sites so an agent landing on one satellite can find the rest (docs) - Powered by dash-improve-my-llms 2.3.4
- Run the same app on Flask, FastAPI, or Quart β switch with a single
DASH_BACKENDenvironment variable - Backend selection centralized in
lib/backend.py; a live badge shows which backend is serving the page - FastAPI/Quart (ASGI) unlock async callbacks, websocket callbacks, OpenAPI docs, a native JSON API (
/api/backend,/api/pages,/healthz), and ASGI middleware - Dedicated docs: Pluggable Backends, Backend Deep Dive, and a FastAPI Showcase
- Docker and docker-compose support
- Gunicorn (WSGI) and Uvicorn (ASGI) production servers
- Optimized for deployment
- Environment-based configuration
- Dash 4.2.0 - Modern Plotly Dash framework with pluggable backends
- DMC 2.7.0 - Dash Mantine Components
- Mantine 8.3.6 - Beautiful React UI library
- React 18 - Latest React features
- Python 3.11+ - Modern Python
- Python: 3.11 or higher
- Node.js: 14+ (for npm dependencies)
- npm: 6+
- dash
~=4.4.1β see the support matrix below; not 4.3.0 - dash-mantine-components >= 2.7.0
- dash-ag-grid
- dash-improve-my-llms >= 2.3.4 (the 2plot network standard β see below)
- flask >= 3.0.0 (default backend)
- plotly >= 5.0.0
- pandas >= 1.2.3
- pydantic >= 2.3.0
- python-frontmatter >= 1.0.0
- markdown2dash (installed
--no-depsβ see below) - gunicorn >= 23.0.0 (WSGI production server; 21.x carried two request-smuggling CVEs)
Optional backends (install the matching extra to switch off Flask):
pip install "dash[fastapi]" # FastAPI (ASGI) backend
pip install "dash[quart]" # Quart (ASGI) backend
# then run with: DASH_BACKEND=fastapi python run.py (needs uvicorn)See requirements.txt for the complete list.
Verified against real apps on each backend, with the failure reproduced on a
stock Dash app with dash-improve-my-llms uninstalled:
| Dash | Flask | FastAPI | Quart |
|---|---|---|---|
| 4.1.0 | β | β no pluggable backends | β |
| 4.2.0 | β | β | β |
| 4.3.0 | β | β every non-root page 500s | β |
| 4.4.0 | β | β | β |
| 4.4.1 | β | β | β |
4.3.0 added an early-return path guard to the ASGI middleware that returns
before set_current_request, while the page catch-all still calls
get_current_request() β so it raises RuntimeError: No active request in context. The catch-all is byte-identical between 4.2.0 and 4.3.0; only the
middleware changed. 4.4.0 fixed it by setting the context inside the catch-all
too.
That distinction matters for the pin: 4.2.0 works only because a single upstream code path happens to cover it, whereas 4.4.x sets the context in both places, so a future middleware guard can't reintroduce the bug. 4.4.x isn't just currently-passing, it's structurally safer.
~=4.4.1 lets 4.4.2 patches flow without twenty pull requests but blocks
4.5.0, so a minor bump goes through the matrix deliberately. The pin is for the
most constrained backend network-wide, including Flask-only apps β
DASH_BACKEND is an environment variable and this repo is a shared template,
so a Flask deployment becomes a FastAPI deployment with one env change and no
code change.
Note on
dash-improve-my-llms. The floor is 2.3.4, the version 2plot.ai and 2plot.dev both run. It is what resolves this site's published identity:resolve_site_titletakes the/llms.txtH1 and the llms viewer's brand chip from the home page's registeredname, and skips generic candidates (Home,Index, and Dash's default titleDash) instead of publishing them. On a pre-2.3.4 build this host's viewer chip read a bare "Dash". There is no vendored copy of the package any more;vendor/holdsdash_clerk_authalone. See Network Standard.
Note on
markdown2dash. Version 0.1.2 declaresgunicorn>=21.2.0,<22.0.0β a markdown parser pinning a WSGI server, and directly against the CVE-drivengunicorn>=23floor. pip cannot resolve both, so it is installed without its dependency graph. Its real dependencies (docutils,jsonpath,mistune) are listed inrequirements.txtinstead. Every install path does the same two commands:pip install -r requirements.txt pip install --no-deps markdown2dash==0.1.2
git clone https://github.com/pip-install-python/Dash-Documentation-Boilerplate.git
cd Dash-Documentation-BoilerplatePython packages:
pip install -r requirements.txt
pip install --no-deps markdown2dash==0.1.2 # see the note aboveNode packages (for DMC frontend components):
npm install./scripts/dev.sh # backend from .env (default flask)
./scripts/dev.sh fastapi # override for one runVisit http://localhost:8559 in your browser.
scripts/dev.sh resolves the interpreter from its own location, so it always
uses this project's .venv. python run.py works too β but an IDE run
configuration pointing at another project's virtualenv starts the app
against that project's dependency versions, which is silent and expensive:
on dash-improve-my-llms 2.0.0 there is no viewer module at all, so
/<page>/llms.txt serves plain Markdown to everyone and nothing looks broken.
The app now refuses to boot below the pinned floors and prints
sys.executable, but the launcher avoids the question entirely.
Create your documentation in the docs folder:
docs/
βββ your-component/
β βββ your-component.md # Markdown documentation
β βββ examples.py # Python code examples (optional)dash-documentation-boilerplate/
βββ assets/ # Static assets and CSS
β βββ m2d.css # Markdown-to-Dash styling (theme-aware)
β βββ main.css # Custom styles (theme-aware)
β βββ llms_copy.js # "Copy for LLM" button handler
β
βββ components/ # Reusable UI components
β βββ appshell.py # Main app layout with MantineProvider
β βββ header.py # Header with search and theme toggle
β βββ navbar.py # Navigation sidebar and drawer
β βββ backend_badge.py # Badge showing the active backend
β
βββ docs/ # Documentation content
β βββ example/ # Getting Started guide
β βββ directives/ # Custom Directives guide
β βββ interactive-components/ # Callback patterns guide
β βββ data-visualization/ # Theme-aware charts guide
β βββ ai-integration/ # AI/LLM integration (dash-improve-my-llms 2.2)
β βββ networks/ # Multi-site network wiring for satellites
β βββ backends/ # Pluggable Backends guide
β βββ backend-comparison/ # Flask vs FastAPI vs Quart deep dive
β βββ fastapi-showcase/ # What the FastAPI backend unlocks
β
βββ lib/ # Utility libraries
β βββ constants.py # BASE_URL + guard, APP_VERSION, colors
β βββ network_directory.py # Cross-host directory shared by every satellite
β βββ backend.py # Backend selection (DASH_BACKEND)
β βββ asgi_middleware.py # ASGI middleware (FastAPI/Quart)
β βββ asgi_routes.py # Showcase routes (/healthz, /api/*)
β βββ analytics_tracker.py # Lightweight visitor analytics
β βββ directives/ # Custom markdown directives
β βββ kwargs.py # Component props table generator
β βββ source.py # Source code display directive
β βββ toc.py # Table of contents directive
β βββ headings.py # Heading ids that survive inline formatting
β βββ llms_copy.py # "Copy for LLM" button directive
β
βββ pages/ # Dash multi-page app pages
β βββ home.md # Home page content
β βββ home.py # Home page layout (exports LLMS_DOC)
β βββ markdown.py # Dynamic markdown page loader
β
βββ scripts/
β βββ smoke_live.py # Post-deploy checks against a live site
β
βββ tests/ # pytest suite (runs on all three backends)
β βββ conftest.py # Boots run.py once; one client per backend
β βββ test_pages.py # Every page loads and serves real content
β βββ test_llms_routes.py # llms.txt, sitemap, robots, canonicals
β βββ test_network_directory.py
β βββ test_docs_content.py # Frontmatter, directives, heading anchors
β βββ test_config.py # BASE_URL guard, index.html metadata
β βββ test_internal_traffic.py # The analytics contract, both directions
β βββ test_network_smoke.py # The battery, run against this app
β βββ test_site_identity.py # One brand, every surface
β βββ test_smoke_live.py # The CD script, run against this app
β
βββ templates/
β βββ index.html # SEO-optimized HTML template
β
βββ vendor/ # dash-clerk-auth sdist (not on PyPI)
β
βββ .github/
β βββ dependabot.yml # dash-network update group
β βββ workflows/
β βββ ci.yml # Lint, matrix, image build + boot + battery
β βββ cd.yml # Render deploy + live verification
β
βββ .flake8
βββ .gitignore
βββ CHANGELOG.md # Version history and changes
βββ Dockerfile # Docker container definition
βββ docker-compose.yml # Docker compose configuration
βββ package.json # Node.js dependencies
βββ package-lock.json # Locked npm versions
βββ pytest.ini
βββ README.md # This file
βββ render.yaml # Render Blueprint for boilerplate.2plot.dev
βββ requirements.txt # Python dependencies
βββ run.py # Application entry point
-
Create a new folder in the
docs/directory:mkdir -p docs/my-component
-
Create a markdown file with frontmatter:
--- name: My Component description: A description of my component endpoint: /components/my-component icon: mdi:code-tags --- ## My Component Your documentation content here...
-
Add interactive examples (optional):
# docs/my-component/example.py import dash_mantine_components as dmc component = dmc.Button("Click Me!", id="my-button")
-
Use directives in your markdown:
.. toc:: .. exec::docs.my-component.example .. source::docs/my-component/example.py
Generates a table of contents from your markdown headings.
Renders an executable Python component from a module.
Displays source code with syntax highlighting.
Generates a props documentation table for a component.
Adds a "Copy for LLM" button that copies the page's /<page>/llms.txt URL to the clipboard for sharing with ChatGPT, Claude, and other AI assistants.
Modify lib/constants.py to change the primary color:
PRIMARY_COLOR = "teal" # Change to any Mantine colorCustomize CSS in:
assets/main.css- General stylingassets/m2d.css- Markdown-specific styling
The boilerplate automatically saves user theme preference (light/dark) in localStorage:
- First visit: Detects browser preference or defaults to light
- Theme toggle: Saves preference automatically
- Return visits: Restores saved theme preference
The suite boots run.py itself rather than a test app assembled for the
occasion β almost everything worth catching here lives in the wiring
(registration order, which middleware runs first, whether a page's prose
survived to the response), and a test app that re-implements the wiring only
tests the re-implementation.
pip install pytest
pytest # whichever backend DASH_BACKEND / .env selects
DASH_BACKEND=flask pytest # the three backends, one at a time
DASH_BACKEND=fastapi pytest
DASH_BACKEND=quart pytest
flake8 lib components pages tests run.pyWhat it covers, and why each one is there:
| Area | The failure it catches |
|---|---|
| Page registration & reachability | A markdown file that silently stops registering β invisible to any test that iterates whatever did register |
| Crawler bodies | A page serving the JavaScript stub. This is the regression that cost the network 12 of 14 crawlable URLs |
| Rendered prose | Links, tables, code fences and rules coming through as literal text instead of HTML |
| Canonical tags | Exactly one per page, on this host. A wrong one deindexes the site and looks like nothing is wrong |
| sitemap / robots / llms.txt | Missing pages, foreign hosts, a sitemap line pointing elsewhere |
| Network directory | Self-listed peers, duplicate or overlapping tiers, entries missing from the published output |
| Docs content | Broken .. exec:: / .. source:: targets, duplicate endpoints, incomplete frontmatter |
| Heading anchors | A TOC link whose target id doesn't exist β clicking it does nothing, silently |
BASE_URL guard |
A fork deploying with the boilerplate's own canonical host |
scripts/smoke_live.py |
The CD script itself, run against the in-process app, so a typo can't turn every live check into a silent pass |
.github/workflows/ci.yml runs on every push and
pull request:
- lint β flake8, blocking
- test β the full suite on Flask, FastAPI and Quart (Python 3.12), plus
Python 3.11 and 3.13 on Flask. Asserts the installed Dash is β₯ 4.4 and
dash-improve-my-llmsis β₯ 2.1 before running anything - boot under gunicorn β a page can render under a test client and still fail under a real WSGI worker
- docker β builds the image, boots it, and probes the live routes
render.yaml is the Blueprint for the live deployment:
gunicorn with two workers, /healthz as the health check, a persistent disk
for the analytics ledger, and the custom domain attached.
render blueprint launch # or point a new Render service at this repoThe one environment variable you must set is APP_BASE_URL. It drives
<link rel="canonical">, sitemap.xml, and the absolute URLs in llms.txt.
A fork that leaves it unset inherits https://boilerplate.2plot.dev and tells
Google that every one of its pages is a duplicate of this one β traffic
disappears and nothing in the app looks broken. lib/constants.py refuses to
boot on Render without it, and rejects *.onrender.com values too, because
those keep resolving after a custom domain is attached and quietly split link
equity across two hosts.
APP_BASE_URL=https://yoursite.2plot.dev # required in production
DASH_BACKEND=flask # flask | fastapi | quart
CROSS_APP_WEBHOOK_SECRET=... # optional: network analytics
TRAFFIC_ANALYTICS_FILE=/var/data/visitor_analytics.json.github/workflows/cd.yml runs CI, POSTs to the
Render deploy hook in the RENDER_DEPLOY_HOOK_URL secret, waits for the new
instance to be reliably healthy, and then verifies the live site with
scripts/smoke_live.py.
Without that secret the deploy step skips itself and the workflow still verifies whatever is currently live β so a fork doesn't fail CD on day one over a secret it was never given.
You can run the same checks by hand against any satellite:
python scripts/smoke_live.py https://emojimart.2plot.devIt checks the four things that are silent in production: a canonical on the
wrong host, a page serving the JavaScript stub, a missing network directory,
and dead peer llms.txt links.
docker build -t dash-docs-boilerplate .
docker run -p 8550:8550 dash-docs-boilerplate # http://localhost:8550
docker-compose upThe image serves with gunicorn and declares a HEALTHCHECK against
/healthz. Note that vendor/ is copied in before the pip layer β while
dash-improve-my-llms installs from the sdist, the build fails without it.
This repo is the template the *.2plot.dev documentation sites are built
from, so changes here propagate. Four things to change when you fork it:
APP_BASE_URLin your host's environment, andDEFAULT_BASE_URLinlib/constants.py. See above for why this one matters more than everything else combined.lib/network_directory.pyβ keep it identical across every satellite. Twelve hand-maintained peer lists will drift, and a directory that disagrees with itself across hosts is worse than no directory. Only list hosts that are actually live.templates/index.htmlβ title, description, Open Graph card, and the Schema.org blocks.docs/β replace the example pages with your component's.
Leave warn_missing_llms_doc=True on. It names every page with no prose,
which is exactly the list of pages serving a stub to crawlers. Turning it off
hides the to-do list rather than shortening it. The full guide is at
boilerplate.2plot.dev/networks.
-
Create virtual environment:
python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt pip install --no-deps markdown2dash==0.1.2 npm install
-
Run in debug mode:
# Modify run.py app.run(debug=True, host='0.0.0.0', port='8553')
- Create your component in a separate module
- Add documentation in
docs/your-component/ - The app automatically discovers and registers pages from markdown files
- Restart the server to see your new documentation
Main layout components:
- Header:
components/header.py- Logo, search, theme toggle - Navbar:
components/navbar.py- Sidebar navigation - AppShell:
components/appshell.py- Overall layout structure
Create a .env file (optional):
DASH_DEBUG=False
DASH_HOST=0.0.0.0
DASH_PORT=8553
DASH_BACKEND=flask # flask | fastapi | quart (requires the matching dash extra)When deployed as a satellite of the 2plot network, this app reports its own
traffic to the hub so the owner-only /traffic dashboard can chart it. Two
signals, both hourly:
| Signal | How |
|---|---|
| Health | The hub probes /healthz (served on every backend) and records up/down + latency. |
| Traffic | lib/satellite_reporter POSTs a signed daily rollup to https://2plot.ai/api/satellite/traffic. |
CROSS_APP_WEBHOOK_SECRET=... # shared HMAC secret β without it, reporting is off
SATELLITE_APP_KEY=dev # this app's key in the hub network directory
# (falls back to AD_APP_ID, then "dev")
# Optional
SATELLITE_TRAFFIC_URL=https://2plot.ai/api/satellite/traffic
SATELLITE_REPORT_INTERVAL_S=3600
ANALYTICS_GEO_LOOKUP=1 # 0 to skip ip-api.com (unnecessary behind Cloudflare)
ANALYTICS_RETENTION_DAYS=45 # local ledger retention; the hub keeps the historyReporting is off by default β no secret, no POSTs, and the app logs that it is disabled. Check what would be sent without sending it:
python -m lib.satellite_reporter --dry-runThe numbers (visitors, sessions, median_session_s, top pages, countries)
are computed in lib/traffic_rollup.py using the hub's own definitions β a
visitor is an (IP, user-agent) pair, a session breaks on a 30-minute gap, and
the median session length counts multi-page sessions only, so single pageviews
are never padded in. Behind a proxy or CDN, the tracker reads
CF-Connecting-IP / X-Forwarded-For for the client address and
CF-IPCountry for the country; without that, every visitor would look like the
proxy.
Deployment note β give the ledger a persistent disk. The hub takes the last report for a given
(app, date). On an ephemeral filesystem (a plain Render/Heroku instance) a mid-day deploy wipesvisitor_analytics.json, and the next hourly report overwrites today's correct total with the handful of hits collected since the restart. Mount a disk and pointTRAFFIC_ANALYTICS_FILEat it (e.g./var/data/visitor_analytics.json) so a deploy doesn't cost you a day of numbers.
| File | Purpose |
|---|---|
lib/constants.py |
App-wide constants (colors, titles) |
assets/main.css |
Custom CSS styles |
templates/index.html |
HTML template (for analytics, meta tags) |
components/appshell.py |
Theme configuration, MantineProvider settings |
- Getting Started: This README
- Changelog: See CHANGELOG.md
- Examples: Check the
/docs/example/folder
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Test thoroughly: Ensure the app runs without errors
- Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow PEP 8 style guide for Python code
- Add docstrings to functions and classes
- Test your changes before submitting
- Update documentation if adding new features
- Keep commits atomic and well-described
Issue: ModuleNotFoundError: No module named 'dash_html_components'
- Solution: You're on an old version. Update to 1.0.0+ and import from the main package (
from dash import html, dcc); 1.0.0 runs on Dash 4.x.
Issue: DASH_BACKEND=fastapi (or quart) fails to start
- Solution: Install the matching extra β
pip install "dash[fastapi]"(or[quart]) β and serve with an ASGI server (uvicorn). The app falls back to Flask if the backend is unavailable.
Issue: Theme doesn't persist
- Solution: Check browser localStorage is enabled and not blocked
Issue: npm install fails
- Solution: Update Node.js to 14+ and npm to 6+
Issue: Port already in use
- Solution: Change port in
run.pyor stop the conflicting process
Issue: RuntimeError: APP_BASE_URL is not set on Render
- Solution: Working as intended. Set
APP_BASE_URLto this deployment's real origin. Without it the app would serve the boilerplate's canonical host on every page.
Issue: pip install -r requirements.txt fails with a gunicorn resolution conflict
- Solution:
markdown2dash0.1.2 pinsgunicorn<22against this project'sgunicorn>=23floor. Install it separately:pip install --no-deps markdown2dash==0.1.2.
Issue: the llms.txt viewer's brand chip says "Dash", or /llms.txt opens with the wrong # line
- Solution: You are on a pre-2.3.4
dash-improve-my-llms, orSITE_BRANDis unset.pip install -U "dash-improve-my-llms[flask]>=2.3.4"and see Network Standard.
Issue: the Docker container exits at boot with Could not import dash.backends._fastapi
- Solution: A local
.envwas copied into the image..dockerignoreexcludes it; make sure you have not removed that line.
Issue: Every non-root URL 500s with No active request in context
- Solution: You're on Dash 4.3.0 with the FastAPI backend. Upgrade to 4.4.0+;
requirements.txtalready floors it there.
For more issues, check GitHub Issues
Current Version: 1.2.0
| Component | Version |
|---|---|
| Dash | 4.4.0+ (4.3.0 excluded β broken FastAPI backend) |
| Dash Mantine Components | 2.7.0+ |
| Mantine | 8.3.6 |
| Python | 3.11+ |
| React | 18.2.0 |
| Flask / FastAPI / Quart | pluggable backends |
| dash-improve-my-llms | 2.3.4+ |
See CHANGELOG.md for version history.
The 2plot network standard, landed on this template so every satellite can copy it. See Network Standard.
- πͺͺ Explicit site identity (
lib/constants.SITE_BRAND) onDash(title=),register_page_metadata(path="/"),pages/home.mdandtemplates/index.html. Before this,/llms.txt's viewer chip published Dash's default title β a bare "Dash" β as the name of this site. - π The internal-traffic contract: network machinery is counted nowhere. Token-carrying requests are dropped at write time before bot classification,
/healthzis no longer stored, and every outbound call to another network host now sendsINTERNAL_UA. The ad client had been fetching a campaign from 2plot.dev on every page view aspython-requestsβ this satellite's readers were being charted as bots on the hub. - π§ͺ CI on the network baseline: least-privilege
permissions, per-jobtimeout-minutes, a buildx GHA cache, version fingerprints asserted inside the image, a secretless pytest suite,scripts/network_smoke.pyrun in three seats (container, production, in-process), Dependabot with adash-networkgroup, and an advisorypip-audit. - π gunicorn >= 23.0.0 (was 21.2.0, which carried CVE-2024-6827 and CVE-2024-1135).
markdown2dash's spuriousgunicorn<22pin is dodged with a--no-depsinstall. - π¦ dash-improve-my-llms >= 2.3.4.
- π
.dockerignoreβ a local.envwas being copied into the production image, which killed the container at boot on the first local run of the new battery. Secrets and dev config no longer reach an image layer.
- π§ͺ CI/CD: a pytest suite that boots the real app on all three backends, flake8, a Docker build, and a CD workflow that deploys to Render and then verifies the live site.
- π°οΈ Cross-host network directory (
lib/network_directory.py) plus a Multi-Site Networks guide for satellite authors. - π
APP_BASE_URLguard: production boots fail rather than silently serving another site's canonical host. - π― dash-improve-my-llms 2.2: merge semantics for page metadata, universal prerender, a Markdown renderer that emits real anchors, tables and code fences, a navigation block so a page's
llms.txtis no longer a dead end, and content negotiation on that URL β Markdown for agents, a rendered view with the network wordmark for browsers. - π Fixes: duplicate canonical tags on every page; a heading containing inline code crashing the renderer at startup; TOC anchors pointing at ids that didn't exist; MCP wiring that never ran because it imported a symbol that doesn't exist; dead
/page.jsonand/architecture.txtlinks; a broken Open Graph image;piratesbagain.com.
First stable release β a major architectural milestone:
- π Dash 4.x (4.2.0) and DMC 2.7.0 β modern framework with pluggable backends.
- π Pluggable backends: run the same app on Flask, FastAPI, or Quart by setting
DASH_BACKENDβ no code changes. ASGI backends add async/websocket callbacks, OpenAPI docs, a native JSON API, and ASGI middleware. New Pluggable Backends, Backend Deep Dive, and FastAPI Showcase docs. - π― dash-improve-my-llms 2.0: the
LLMS_DOCpattern (per-page prose served at/<page>/llms.txt), multi-backend AI/LLM surfaces, and an MCP resource bridge on Dash 4.3+. - π§Ή Removed the TOON format entirely β
lib/toon_generator.py, the TOON docs/dashboard, and/llms.toonroutes are gone (the package no longer exportsTOONConfig,toon_encode,generate_*_toon). β οΈ Removedmark_important()/mark_component_hidden()(now no-ops) and the/page.json//architecture.txtroutes β Dash 4.3 MCP covers structured introspection. Write emphasis directly into a page'sLLMS_DOCmarkdown.
This project is licensed under the MIT License - see the LICENSE file for details.
- Plotly Dash - The web framework
- Dash Mantine Components - Beautiful UI components
- Mantine - React component library
- dmc-docs - Documentation framework inspiration
- @AnnMarieW for suggested improvements
- The Dash community for continuous support
- Documentation: You're reading it!
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Dash Community: Plotly Community Forum
GitHub: @pip-install-python
YouTube: @2plotai β build-alongs and component walkthroughs
Check out open issues labeled good first issue
Made with β€οΈ by the Dash community
Pip Install Python LLC @ 2plot.ai
Star this repo if you find it useful! β

