Skip to content

๐ŸŒย ย Eval JavaScript

Submitted by Lukas Masuch

Summary

Evaluate JavaScript expressions in the browser and return results to Python.

Functions

eval_javascript

Evaluate a JavaScript expression in the browser and return the result.

This component evaluates a JavaScript expression in the user's browser using eval() and returns the serialized result to Python. The component itself is invisible (zero-height).

Parameters:

Name Type Description Default
expression str

The JavaScript expression to evaluate. Can be synchronous or return a Promise for async evaluation.

required
key str

A unique key for this component instance. Required to track state across reruns.

required

Returns:

Type Description
Any | None

The result of the JavaScript expression, serialized to a Python-compatible

Any | None

value. Returns None while the expression is being evaluated or if the

Any | None

expression is empty.

Note
  • The expression is evaluated with browser-side JavaScript eval()
  • Supports async expressions (Promises are automatically awaited)
  • Complex objects are serialized (Maps become dicts, Sets become lists, etc.)
  • Errors are captured and can be accessed via session state

Example:

```python
user_agent = eval_javascript("window.navigator.userAgent", key="ua")
if user_agent:
    st.write(f"Your browser: {user_agent}")
```
Source code in src/streamlit_extras/eval_javascript/__init__.py
@extra
def eval_javascript(expression: str, *, key: str) -> Any | None:
    """Evaluate a JavaScript expression in the browser and return the result.

    This component evaluates a JavaScript expression in the user's browser using
    `eval()` and returns the serialized result to Python. The component itself is
    invisible (zero-height).

    Args:
        expression: The JavaScript expression to evaluate. Can be synchronous or
            return a Promise for async evaluation.
        key: A unique key for this component instance. Required to track state
            across reruns.

    Returns:
        The result of the JavaScript expression, serialized to a Python-compatible
        value. Returns None while the expression is being evaluated or if the
        expression is empty.

    Note:
        - The expression is evaluated with browser-side JavaScript `eval()`
        - Supports async expressions (Promises are automatically awaited)
        - Complex objects are serialized (Maps become dicts, Sets become lists, etc.)
        - Errors are captured and can be accessed via session state

    Example:

        ```python
        user_agent = eval_javascript("window.navigator.userAgent", key="ua")
        if user_agent:
            st.write(f"Your browser: {user_agent}")
        ```
    """
    component_state = st.session_state.get(key, {})
    request_state_key = f"{key}__eval_javascript_request"
    request_state = st.session_state.get(
        request_state_key,
        {"expression": None, "request_id": 0},
    )

    if request_state["expression"] != expression:
        request_state = {
            "expression": expression,
            "request_id": request_state["request_id"] + 1,
        }
        st.session_state[request_state_key] = request_state

    request_id = request_state["request_id"]
    current_result = component_state.get("result")
    current_error = component_state.get("error")
    current_status = component_state.get("status", "idle")
    completed_request_id = component_state.get("completed_request_id", -1)

    # Use st._event container to avoid adding any visual space to the UI
    with st._event:
        _JAVASCRIPT_EVAL_COMPONENT(
            key=key,
            data={
                "expression": expression,
                "request_id": request_id,
                "result": current_result,
                "error": current_error,
                "status": current_status,
                "completed_request_id": completed_request_id,
            },
            default={
                "result": current_result,
                "error": current_error,
                "status": current_status,
                "completed_request_id": completed_request_id,
            },
            on_result_change=lambda: None,
            on_error_change=lambda: None,
            on_status_change=lambda: None,
            on_completed_request_id_change=lambda: None,
            width="stretch",
            height=0,
        )

    if completed_request_id != request_id:
        return None

    return current_result

Import:

from streamlit_extras.eval_javascript import eval_javascript # (1)!
  1. You should add this to the top of your .py file ๐Ÿ› 

Examples

example

def example() -> None:
    """Example usage of the eval_javascript component."""
    examples = {
        "User agent": "window.navigator.userAgent",
        "Window width": "window.innerWidth",
        "Location summary": "({ href: window.location.href, host: window.location.host })",
        "Async example": "Promise.resolve({ language: window.navigator.language })",
        "Thrown error": "(() => { throw new Error('Boom'); })()",
    }

    selected_example = st.selectbox("Example expression", list(examples))
    selected_expression = "window.navigator.userAgent" if selected_example is None else examples[selected_example]

    expression = st.text_area(
        "JavaScript expression",
        value=selected_expression,
        height=140,
        help="The expression is evaluated with browser-side JavaScript `eval(...)`.",
    )

    value = eval_javascript(expression, key="eval_javascript_demo")
    component_state = st.session_state.get("eval_javascript_demo", {})
    status = component_state.get("status", "idle")
    error = component_state.get("error")

    st.subheader("Python result")
    if status == "running":
        st.info("Evaluating in the browser...")
    elif error:
        error_name = error.get("name", "Error")
        error_message = error.get("message", "Unknown error")
        st.error(f"{error_name}: {error_message}")
        if error.get("stack"):
            st.code(error["stack"], language="text")
    else:
        st.write(value)