You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have searched for existing issues that already report this problem, without success.
Stencil Version
4.30.0
Current Behavior
A functional component rendering an <svg> element was rendering it and its children incorrectly as HTML elements (presumably via document.createElement('svg');) rather than SVG elements (i.e. via document.createElementNS('http://www.w3.org/2000/svg', 'svg');). Therefore, the elements are in the DOM, but since they're not "real" SVG elements, the browser ignores them and doesn't display the SVG as expected.
After much trial and error, we eventually found a solution: We were importing our functional component's module with a .js extension (i.e. import FooComponent from '../Foo.js';). When we removed that (i.e. import FooComponent from '../Foo';), it rendered as a "genuine" SVG. So, in both cases, functional compononent is successfully imported and used. It's just that when the .js extension is there it doesn't render SVG elements correctly.
We use other functional components that just render HTML elements and those work fine when imported with .js extensions.
Expected Behavior
<svg> in a functional component's JSX should render the correct DOM elements, regardless of how they are imported.
System Info
System: node 20.19.0
Platform: darwin (24.4.0)
CPU Model: Apple M2 Pro (12 cpus)
Compiler: /Users/james.nash/code/investec-design-system/node_modules/@stencil/core/compiler/stencil.js
Build: 1745512551
Stencil: 4.30.0 🌺
TypeScript: 5.5.4
Rollup: 4.34.9
Parse5: 7.2.1
jQuery: 4.0.0-pre
Terser: 5.37.0
Viewed in current versions of Firefox and Chrome - same result in both.
Steps to Reproduce
We have a monorepo setup (for a design system) and one of the packages within it contains Stencil web components (which a built using the dist-custom-elements output target). We have a number of Stencil functional components for stuff shared by multiple web components.
One of the functional components renders an <svg> element (it's used for displaying icons). That component's code is as follows:
Nothing appears visibly (it's supposed to display an X icon)
As shown in the console, that <svg> DOM element is an instance of HTMLElement, notSVGElement, as it's supposed to be.
And, more or less by fluke, we discovered when we change the import statement to not use the .js extension:
-import { IdsIcon } from '../../html/Icon/Icon.js';+import { IdsIcon } from '../../html/Icon/Icon';
...it suddenly works as expected:
Code Reproduction URL
n/a
Additional Information
Our code is not (yet) open source, so I'm afraid I can't share it.
I did try to make a simplified reproduction and, weirdly, I couldn't get it to fail. The SVG rendered correctly regardless of whether I imported it with a .js extension or not. I was using the same Stencil version and the same output target config.
I appreciate this will be difficult (impossible?) to investigate, but still wanted to raise it for awareness. Perhaps others have encountered similar issues and some of what I've shared here will provide some useful clues 🤞
Whatever this is, it certainly smells like a bug, since I wouldn't expect Stencil to render JSX differently just because a .js extension on an import.
The text was updated successfully, but these errors were encountered:
james-nash
changed the title
bug:
bug: SVG JSX sometimes don't get rendered as the correct DOM elements
May 27, 2025
I appreciate this will be difficult (impossible?) to investigate
Unfortunately there is not much we can do until we can work on something that allows us to reproduce the issue. Let me know if you manage to put together a reproduction case. I am happy to take a look then.
Prerequisites
Stencil Version
4.30.0
Current Behavior
A functional component rendering an
<svg>
element was rendering it and its children incorrectly as HTML elements (presumably viadocument.createElement('svg');
) rather than SVG elements (i.e. viadocument.createElementNS('http://www.w3.org/2000/svg', 'svg');
). Therefore, the elements are in the DOM, but since they're not "real" SVG elements, the browser ignores them and doesn't display the SVG as expected.After much trial and error, we eventually found a solution: We were importing our functional component's module with a
.js
extension (i.e.import FooComponent from '../Foo.js';
). When we removed that (i.e.import FooComponent from '../Foo';
), it rendered as a "genuine" SVG. So, in both cases, functional compononent is successfully imported and used. It's just that when the.js
extension is there it doesn't render SVG elements correctly.We use other functional components that just render HTML elements and those work fine when imported with
.js
extensions.Expected Behavior
<svg>
in a functional component's JSX should render the correct DOM elements, regardless of how they are imported.System Info
Steps to Reproduce
We have a monorepo setup (for a design system) and one of the packages within it contains Stencil web components (which a built using the
dist-custom-elements
output target). We have a number of Stencil functional components for stuff shared by multiple web components.One of the functional components renders an
<svg>
element (it's used for displaying icons). That component's code is as follows:It's then imported into a web component and used in its
render()
method:The result (previewed here in Storybook) is:
...as you can see:
<svg>
element in the DOM, but...<svg>
DOM element is an instance ofHTMLElement
, notSVGElement
, as it's supposed to be.And, more or less by fluke, we discovered when we change the
import
statement to not use the.js
extension:...it suddenly works as expected:
Code Reproduction URL
n/a
Additional Information
Our code is not (yet) open source, so I'm afraid I can't share it.
I did try to make a simplified reproduction and, weirdly, I couldn't get it to fail. The SVG rendered correctly regardless of whether I imported it with a
.js
extension or not. I was using the same Stencil version and the same output target config.I appreciate this will be difficult (impossible?) to investigate, but still wanted to raise it for awareness. Perhaps others have encountered similar issues and some of what I've shared here will provide some useful clues 🤞
Whatever this is, it certainly smells like a bug, since I wouldn't expect Stencil to render JSX differently just because a
.js
extension on animport
.The text was updated successfully, but these errors were encountered: