yewstack/yew · warning

event target should be of type HtmlElement

Error message

event target should be of type HtmlElement

What it means

After obtaining the target, the tutorial casts it with dyn_into::<HtmlElement>() and expects success. The cast fails whenever the target is not an HtmlElement - most commonly an SVGElement: moving the pointer over an inline <svg> icon makes the SVG element the event target, and SVGElement does not inherit from HTMLElement. Document or Window targets fail the same way, and then the expect panics.

Source

Thrown at website/versioned_docs/version-0.21/concepts/basic-web-technologies/web-sys.mdx:175

features = [
    "console",
    "Document",
    "HtmlElement",
    "MouseEvent",
    "DomRect",
]
```

```rust ,no_run
use wasm_bindgen::{prelude::Closure, JsCast};
use web_sys::{console, Document, HtmlElement, MouseEvent};

let mousemove = Closure::<dyn Fn(MouseEvent)>::wrap(Box::new(|e| {
    let rect = e
        .target()
        .expect("mouse event doesn't have a target")
        .dyn_into::<HtmlElement>()
        .expect("event target should be of type HtmlElement")
        .get_bounding_client_rect();
    let x = (e.client_x() as f64) - rect.left();
    let y = (e.client_y() as f64) - rect.top();
    console::log_1(&format!("Left? : {} ; Top? : {}", x, y).into());
}));

Document::new()
    .expect("global document not set")
    .get_element_by_id("mousemoveme")
    .expect("element with id `mousemoveme` not present")
    .unchecked_into::<HtmlElement>()
    .set_onmousemove(mousemove.as_ref().dyn_ref());

// we now need to save the `mousemove` Closure so that when
// this event fires the closure is still in memory.
```

This version is much more verbose, but you will probably notice part of that is because of failure

View on GitHub (pinned to 0e4a05472f)

Solutions

  1. Cast to web_sys::Element instead - get_bounding_client_rect() exists on Element and covers SVG and HTML alike
  2. Or use dyn_ref::<HtmlElement>() with an if-let fallback instead of dyn_into + expect
  3. Or bind to a known HtmlElement host and use current_target()
  4. Test with the pointer over SVG content before shipping

Example fix

// before: panics whenever the pointer is over inline <svg>
let rect = e.target().unwrap()
    .dyn_into::<HtmlElement>()
    .expect("event target should be of type HtmlElement")
    .get_bounding_client_rect();

// after: Element covers SVG and HTML elements alike
let rect = e.current_target()
    .dyn_into::<web_sys::Element>()
    .expect("listener is bound to an Element")
    .get_bounding_client_rect();
Defensive patterns

Strategy: type-guard

Type guard

fn as_html_element(target: &web_sys::EventTarget) -> Option<&web_sys::HtmlElement> {
    target.dyn_ref::<web_sys::HtmlElement>()
}

Prevention

When it happens

Trigger: Capturing mouse position while the pointer is over inline SVG (icons, charts); targets that are Document/Window for certain event types; any event whose target is an Element but not an HtmlElement.

Common situations: Pages with SVG icon sets or chart libraries rendering SVG; copy-pasted tutorial code meeting real-world targets; events delegated at document level.

Related errors


AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22). Data as JSON: /api/errors/7d9ad458aea92486. Report an issue: GitHub.