I’m coming from a React background. In React, when I create a custom component and include it in a page, the HTML from the component is rendered as expected.
<div> Hello World </div>
Now I’m getting into Angular and I’ve discovered that a custom component called my-custom-component
renders an extra wrapper tag around the component.
<my-custom-component>
<div> Hello World </div>
</my-custom-component>
I like writing semantic HTML with <section/>
and <header/>
and <aside/>
tags and not use a bunch of unsupported tags. This just bloats the HTML in my opinion and makes the HTML hard to read.
So, what am I missing? I’ve read about this work-around on the Angular website but this seems like a hack. With Angular, did Google just decide not to care about semantic HTML anymore and just render whatever HTML tag it wants? I suspect it’s not hurting SEO because Angular is pretty popular.
2
Answers
I used to have the same attitude towards custom tags/selectors as you, but when you get familiar with Angular and Web Components it turns out that these actually don’t cause any issues and it is merely a matter of getting used to it.
There are some cases where the component element tag can cause issues. For example here in this question on Stackoverflow where the extra "wrapper tag" causes the table rendering to fail. But it could be resolved with a simple style hack.
In modern HTML it is not illegal to use custom elements with their own element tags/selectors. Here on MDN you can read more on Web Components and more specifically Custom Elements:
Angular components are autonomous custom elements which in its turn are classed extending the
HTMLElement
. For an Angular component you can set the element selector inside the component declaration. You could set it to any custom value, for exampleselector: 'my-custom-component'
resulting in the tag<my-custom-component>
but if you don’t declare a customselector
angular components will default tong-component
(<ng-component>
in the HTML output).As far as I know the renderer completely ignores the component selector (what you refer to as "wrapper tag") and only cares about the content of the custom element. But you can of course add custom styling by using the element selector in your global stylesheet or alternatively by using the
:host
pseudo css class to add styling to the custom component from within its shadow DOM (read more on the:host
selector here on MDN). In angular you do this in the component stylesheet (styleUrls
) orstyles
array.Here also a nice read on Web Components in this Medium blog post.
The "work around" you linked to is not what you thought it is. It is actually about using structural directives without adding new elements to the DOM, not about components and preventing the component tag/selector from rendering.
I will use the example given to explain; say you have some content that needs to be rendered depending on a condition:
If the condition evaluates to true the content will be rendered, but it will render in the DOM wrapped in the
div
tag on which the structural directive*ngIf
was used. To prevent this unnecessary (in many cases undesired)div
element you can do:In this last example there will be no output for the
ng-container
; the container will not be rendered in the DOM; theng-container
simply allows us to conditionally render its content.This example will probably get clear to you when you get more familiar with Angular.
UPDATE
A possible alternative to the element selector is an attribute selector which is commonly used for directives, but it can also be used for components.
I will refer to the other answer from @Eliseo nicely demonstrating the difference between component selectors and attribute selectors.
And here a nice blog post on Medium about using the attribute selector for Angular components.
In Briefly:
If you use as selector
[name-of-selector]
you apply to any "tag" of html -see the[
]
-. if you use as selectorname-of-selector
you use this selector as html tagor
Simple stackblitz