Skip to content

Latest commit

 

History

History
121 lines (76 loc) · 5.02 KB

File metadata and controls

121 lines (76 loc) · 5.02 KB

Troubleshooting CCv2 components

Contents

  • Packaged assets and manifests (asset_dir, component key)
  • Renaming / placeholder drift
  • Inline strings vs file-backed assets (path heuristic)
  • Globs (0 matches or multiple matches)
  • Defaults, callbacks, and missing result attributes
  • Keys (Python key= vs frontend key)
  • Shadow DOM / isolate_styles surprises
  • Frontend build (Vite) gotchas
  • DOM clobbering (overwriting injected HTML/CSS)

Packaged assets and manifests (asset_dir, component key)

“Component '' must be declared in pyproject.toml with asset_dir to use file-backed js/css.”

You passed a path-like js=/css= string (like index-*.js or assets/index-*.js) but Streamlit can’t find an asset_dir for this component key.

Fix:

  • If you want inline JS/CSS, pass a multi-line string with the actual code (not a path).
  • If you want packaged assets, ensure:
    • Your wheel includes a pyproject.toml with [[tool.streamlit.component.components]] ... asset_dir = ...
    • You call st.components.v2.component("<project>.<component>", js="...", css="...") with the matching fully-qualified key.

Important context:

  • This error is expected if you test packaged wrappers via plain Python import in some environments.
  • Prefer streamlit run ... for packaged verification because manifest discovery is part of Streamlit runtime initialization.

Inline strings vs file-backed assets (path heuristic)

CCv2 uses a heuristic: strings that “look like” paths are treated as file references. A multi-line string is always treated as inline content.

Fix:

  • Prefer triple-quoted multi-line strings for inline html/css/js.
  • Avoid single-line minified JS/CSS in js=/css=; add a newline if you must.

Globs (0 matches or multiple matches)

Globs must match exactly one file under asset_dir.

Fix:

  • Clean the build output directory before rebuilding.
  • Make your bundler output a predictable index-<hash>.js / index-<hash>.css (or assets/index-<hash>... if you emit into an assets/ subdir).
  • If you started from Streamlit’s component-template, run npm run clean from your frontend/ directory to clear the build/ output so index-*.js matches exactly one file.

Renamed project/package still shows old template names

Symptoms:

  • Old names like streamlit-component-x / streamlit_component_x remain in paths or metadata.
  • Imports, manifest component keys, and registration keys no longer align.

Fix:

  • Rename/update all related surfaces together:
    • root pyproject.toml project name
    • import package folder and MANIFEST.in paths
    • [tool.setuptools.packages.find] and [tool.setuptools.package-data]
    • in-package manifest (<import_name>/pyproject.toml)
    • wrapper registration key ("<project.name>.<component.name>")
    • README/example imports and install commands
  • Rebuild frontend and reinstall editable package after rename.

Defaults, callbacks, and missing result attributes

default={...} doesn’t apply / missing result attributes

Defaults only apply to state keys, and Streamlit expects those keys to be declared via on_<key>_change callback parameters at mount time.

Fix:

  • If you pass default={"value": ...}, also pass on_value_change=lambda: None.
  • For triggers, don’t expect defaults; triggers are transient and default to None.

Keys (Python key= vs frontend key)

  • Python key= is the user-visible Streamlit element key.
  • The frontend also receives a key string that is generated by Streamlit and is not the same as the Python key unless you explicitly pass the user key through data.

Fix:

  • If your frontend needs a stable identifier, pass it in data={"user_key": key, ...}.

Shadow DOM / isolate_styles surprises

Shadow DOM (isolate_styles=True) surprises

With isolate_styles=True (default):

  • Your component is mounted in a shadow root.
  • parentElement is a ShadowRoot.
  • Global CSS (like Tailwind injected into the document) won’t automatically style your component.

Fix:

  • Keep isolate_styles=True for safety and use CSS variables and component-local styles.
  • Use isolate_styles=False only when you intentionally need global styling behavior.

Frontend build gotchas (Vite)

If you deviate from the template’s Vite config (or you’re wiring Vite into an existing repo), these are the common footguns:

  • Missing base: "./": relative asset URLs can break when served from Streamlit’s component URL path.
  • Stale build artifacts: Vite outputs hashed filenames; if you keep old builds around, index-*.js can match multiple files. Clean the build dir before rebuilding.

DOM clobbering (overwriting injected HTML/CSS)

Accidentally overwriting your component DOM

If you directly set parentElement.innerHTML = ..., you can overwrite the HTML/CSS that Streamlit injected from your html=/css= arguments.

Fix:

  • Prefer querySelector + modifying children.
  • If you need dynamic HTML, create a new child element and set that element’s innerHTML.