Skip to content

Conversation

@101100
Copy link

@101100 101100 commented Jan 1, 2026

Description

Summary

Using create_element_ns in BRaw::create_elements without a namespace and setting the inner HTML to the source for an SVG (with a proper xmlns attribute) fails in Chrome because the inner elements are fixed with no namespace. To address this issue, I've updated BRaw::create_elements to use create_element when the parent namespace is None.

The Story

When I upgraded to yew 0.22, I found that SVGs were not rendering properly. The way I was including an SVG was as follows (simplified to remove the ability to choose the icon).

#[component(Icon)]
pub fn icon(props: &IconProps) -> Html {
	let inner_svg = Html::from_html_unchecked(AttrValue::from(include_str!("assets/arrow-down.svg")));
	html! {
		<div class={classes!("svg-icon-container", props.class.clone())} title={props.title.clone()} onclick={props.onclick.clone()}>
			{inner_svg}
		</div>
	}
}

This renders properly in Firefox with both the old and new version, but does not render properly in Chrome with yew 0.22.

I was able to reproduce the issue that arose due to this commit. If you open a blank page in Chrome and run these commands at the console, an icon is added to the page.

let div1 = document.createElement("div");
div1.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>';
document.body.appendChild(div1.childNodes[0]);

If you change the first line to createElementNS with null for the namespace, an icon does not appear, but you can still see it if you inspect the page.

let div2 = document.createElementNS(null, "div");
div2.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>';
document.body.appendChild(div2.childNodes[0]);

Here is an image showing the <svg> in the inspect pane that is not rendered.

image

If you inspect the namespace of the two SVG elements, you can see that Chrome has left the namespace blank on the second one.

image

Checklist

I can't figure out a way to test this fix as it seems the tests are run in Firefox anyway.

  • I have reviewed my own code
  • I have added tests

@github-actions
Copy link

github-actions bot commented Jan 1, 2026

Visit the preview URL for this PR (updated for commit 74b1488):

https://yew-rs-api--pr3970-fix-static-svg-mefzjmn7.web.app

(expires Thu, 08 Jan 2026 19:11:08 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

@github-actions
Copy link

github-actions bot commented Jan 1, 2026

Benchmark - core

Yew Master

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  2.402 ns      │ 3.679 ns      │ 2.405 ns      │ 2.436 ns      │ 100     │ 1000000000

Pull Request

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  2.484 ns      │ 2.57 ns       │ 2.488 ns      │ 2.49 ns       │ 100     │ 1000000000

@github-actions
Copy link

github-actions bot commented Jan 1, 2026

Benchmark - SSR

Yew Master

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 290.822 296.883 291.722 1.831
Hello World 10 519.522 532.064 523.921 5.071
Function Router 10 1701.912 1751.093 1720.457 16.185
Concurrent Task 10 1005.111 1007.134 1006.450 0.656
Many Providers 10 1077.475 1138.656 1103.069 22.267

Pull Request

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 290.969 296.290 291.714 1.620
Hello World 10 516.788 531.424 520.441 4.274
Function Router 10 1720.778 1732.846 1725.639 3.652
Concurrent Task 10 1005.275 1006.811 1006.297 0.441
Many Providers 10 1107.187 1178.470 1126.615 24.365

@github-actions
Copy link

github-actions bot commented Jan 1, 2026

Size Comparison

Details
examples master (KB) pull request (KB) diff (KB) diff (%)
async_clock 98.187 98.238 +0.052 +0.053%
boids 167.638 167.689 +0.052 +0.031%
communication_child_to_parent 91.335 91.387 +0.052 +0.057%
communication_grandchild_with_grandparent 102.444 102.496 +0.052 +0.051%
communication_grandparent_to_grandchild 98.818 98.870 +0.052 +0.052%
communication_parent_to_child 88.697 88.749 +0.052 +0.058%
contexts 103.981 104.033 +0.052 +0.050%
counter 85.366 85.418 +0.052 +0.061%
counter_functional 85.731 85.783 +0.052 +0.060%
dyn_create_destroy_apps 88.454 88.506 +0.052 +0.059%
file_upload 97.965 98.012 +0.047 +0.048%
function_delayed_input 91.252 91.304 +0.052 +0.057%
function_memory_game 169.709 169.761 +0.052 +0.030%
function_router 329.024 329.071 +0.047 +0.014%
function_todomvc 161.576 161.628 +0.052 +0.032%
futures 234.319 234.371 +0.052 +0.022%
game_of_life 103.684 103.735 +0.052 +0.050%
immutable 244.990 245.058 +0.067 +0.028%
inner_html 79.850 79.901 +0.052 +0.065%
js_callback 107.761 107.812 +0.052 +0.048%
keyed_list 179.062 179.114 +0.052 +0.029%
mount_point 83.065 83.117 +0.052 +0.062%
nested_list 112.635 112.687 +0.052 +0.046%
node_refs 90.713 90.765 +0.052 +0.057%
password_strength 1738.836 1738.888 +0.052 +0.003%
portals 92.208 92.260 +0.052 +0.056%
router 302.138 302.185 +0.047 +0.016%
suspense 111.712 111.764 +0.052 +0.046%
timer 87.917 87.969 +0.052 +0.059%
timer_functional 95.997 96.051 +0.054 +0.056%
todomvc 141.378 141.430 +0.052 +0.037%
two_apps 85.229 85.281 +0.052 +0.061%
web_worker_fib 133.345 133.392 +0.047 +0.035%
web_worker_prime 184.916 184.963 +0.047 +0.025%
webgl 82.409 82.461 +0.052 +0.063%

✅ None of the examples has changed their size significantly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant