{"id":1179,"date":"2020-12-03T12:08:06","date_gmt":"2020-12-03T12:08:06","guid":{"rendered":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/?p=1179"},"modified":"2021-05-19T06:18:27","modified_gmt":"2021-05-19T06:18:27","slug":"web-components-part-1","status":"publish","type":"post","link":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/","title":{"rendered":"Web Components (Part 1) \u2013 Building Your Own Components"},"content":{"rendered":"\n<p>So-called \u201cweb components\u201d are one way of building reusable UI components for web applications. Unlike common single-page app frameworks such as React or Angular, the component model is based on web standards. Since SPA frameworks can, in fact, do far more than just build components, web components do not compete directly with the established frameworks. They can, however, be a useful addition. Whenever components are meant to be reused for applications with different technology stacks, web components can be very useful indeed.<\/p>\n\n\n\n<p>Still, using web components in single-page applications presents some difficulties when you go into detail: While the integration into Angular applications is relatively simple, a few things have to be observed, in particular when using React applications.<\/p>\n\n\n\n<p>Whether the \u201cfault\u201d lies on React or the web component standard depends on one\u2019s point of view and is not easily answered. Furthermore, there are some aspects where web components are disadvantageous even with respect to their core competency of building components because they are unnecessarily complicated or inflexible, e.g. compared to React.<\/p>\n\n\n\n<figure class=\"wp-block-image size-medium\"><img decoding=\"async\" src=\"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2020\/11\/202011_WebComponents_SPA-600x319.png\" alt=\"\" class=\"wp-image-1856\"\/><figcaption><em>Figure 1: Web components and SPA frameworks<\/em><\/figcaption><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/topic\/web-components\/\">This series of blog posts<\/a> deals with these and other aspects regarding the interaction of web components and SPA frameworks, in particular React. The first part of the series focuses only on web components, what the term means, and how to build web components.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">What are web components, and how do you build your own components?<\/h2>\n\n\n\n<p>The term \u201cweb components\u201d refers to several separate HTML specifications that deal with various aspects of the development of one\u2019s own components. Consequently, there is no such thing as \u201cone\u201d standard for web components; rather, it is a <a href=\"https:\/\/github.com\/WICG\/webcomponents\" target=\"_blank\" rel=\"noreferrer noopener\">combination of several specifications<\/a>.<\/p>\n\n\n\n<p>The two most important ones are \u201cCustom Elements\u201d and \u201cShadow DOM\u201d. The Custom Elements specification describes the JavaScript base class \u201cHTMLElement\u201d, among others, from which individual components have to be derived. This class provides numerous lifecycle methods that allow you to respond to various events in the component\u2019s life cycle. You can, for example, program a response to the component being integrated into a document or attributes of the component being set. The developers of a component can then update the presentation of the component. Custom Elements furthermore comprise the possibility to register individual component classes under a specific HTML tag so that the component is then available throughout the entire document.<\/p>\n\n\n\n<p>\u201cShadow DOM\u201d means a method that allows for a separate DOM tree, which is largely isolated from the rest of the document, to be created for a component. This means, for example, that CSS properties set globally in the document do not take effect in the Shadow DOM, and on the other hand, CSS definitions within a component do not affect other elements in the document. The goal is to better encapsulate the components and avoid unwanted side effects when integrating foreign web components.<\/p>\n\n\n\n<p>The following code block shows a simple Hello World component that comprises a property for the name of the person to be greeted.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class HelloWorld extends HTMLElement {\n\n    person = \"\"\n\n    constructor() {\n        super();\n\n        this.attachShadow({mode: \"open\"})\n\n        this.shadowRoot.innerHTML = `\n            &lt;div>\n                &lt;p>Hello &lt;span id=\"personGreeting\">&lt;\/span>&lt;\/p>\n            &lt;\/div>\n        `\n    }\n\n    static get observedAttributes() {\n        return ['person']\n    }\n\n    attributeChangedCallback(name, oldValue, newValue) {\n        if(name === \"person\") {\n            if(this.person !== newValue) {\n                this.person = newValue\n                this.update()\n            }\n        }\n    }\n\n    update() {\n        this.shadowRoot.querySelector(\"#personGreeting\").textContent = this.person\n    }\n\n}\nwindow.customElements.define(\"app-hello-world\", HelloWorld)<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Firstly, a separate Shadow DOM tree is created for the component in the constructor of the component. \u201cMode: open\u201d ensures that it is possible to access the DOM tree of the component from the outside with JavaScript despite the Shadow DOM barrier.<\/p>\n\n\n\n<p>Then, the \u201cshadowRoot\u201d, i.e. the root node of the Shadow DOM, is created according to our requirements\u2014in this case, with \u201cinnerHTML\u201d.<\/p>\n\n\n\n<p>With \u201cobservedAttributes\u201d, we describe which attributes the component is supposed to have and\/or which attributes we want to be notified of (we can also specify standard attributes such as \u201cclass\u201d at this point).<\/p>\n\n\n\n<p>The notification is done by means of the \u201cattributeChangedCallback\u201d method, with the name of the changed attribute and both the old and the new value as parameters. Since we only specified one attribute in \u201cobservedAttributes\u201d in this case, checking the name of the attribute is not really necessary. In the case of several attributes, however, it is important to always check which attribute has been changed in each case.<\/p>\n\n\n\n<p>In our case, we first check whether the new value is actually different from the previous one (we will see how this can happen later on). Then, we set the \u201cperson\u201d property that we created as class variable to the value of the submitted attribute.<\/p>\n\n\n\n<p>To update the presentation of the component, the \u201cupdate\u201d method was created in this example. This method is not part of the Custom Elements standard, but only serves to gather the update logic in one place in this case. We retrieve the previously created span element with the ID \u201cperson\u201d from the Shadow DOM and set its text to the value of the \u201cperson\u201d property.<\/p>\n\n\n\n<figure class=\"wp-block-image size-medium\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"424\" src=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/12\/202011_WebComponents_Shadow_DOM_en-600x424.png\" alt=\"\" class=\"wp-image-1185\" srcset=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/12\/202011_WebComponents_Shadow_DOM_en-600x424.png 600w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/12\/202011_WebComponents_Shadow_DOM_en-1024x724.png 1024w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/12\/202011_WebComponents_Shadow_DOM_en-768x543.png 768w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/12\/202011_WebComponents_Shadow_DOM_en-640x452.png 640w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/12\/202011_WebComponents_Shadow_DOM_en.png 1125w\" sizes=\"auto, (max-width: 639px) 98vw, (max-width: 1199px) 64vw, 600px\" \/><figcaption><em>Figure 2: Shadow DOM<\/em><\/figcaption><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The code example shows how, in a final step, our component class is registered with the tag name \u201capp-hello-world\u201d. It is important that the name comprises at least one minus sign. This rule was defined in order to avoid possible name collisions with future standard HTML tags. Choosing a meaningful prefix for one\u2019s own components has also proven to be useful to prevent collisions with other component libraries as far as possible (the prefix \u201capp\u201d used in the example is, in fact, not a very good example in this respect). However, there is no sure way to prevent conflicts.<\/p>\n\n\n\n<p>We are now able to submit simple data to the component by means of attributes. \u201cAttributes\u201d have a few more particularities and pitfalls, but we are going to deal with those in <a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-2\/\">the next part of this series of blog posts<\/a>. For this general introduction, we will leave it at that.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Slots<\/h2>\n\n\n\n<p>The so-called \u201cslots\u201d are another important feature of web components that will be dealt with again in a later part of <a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/topic\/web-components\/\">this series<\/a>. Slots allow for HTML snippets to be submitted to a component. The component then decides how to present the submitted elements. For example, if we want to build a message box that presents both a text and an icon inside a frame, it is advisable to submit the message text to the component by means of a slot instead of an attribute. This way, we are not limited to plain text, but we can use any HTML content we want.<\/p>\n\n\n\n<p>Here is an example of how this can look in the application:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;app-notification-box>\n\t&lt;p>Some Text with additional &lt;strong>tags&lt;\/strong>&lt;\/p>\n&lt;\/app-notification-box><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>We only have to write the HTML tags we want as child elements. Within the component, there has to be a &lt;slot&gt; element in the Shadow root for this purpose. When the component is rendered, the submitted content is then displayed instead of the slot element.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;div>\n    &lt;div>Icon&lt;\/div>\n    &lt;div id=\"content\">\n        &lt;slot>&lt;\/slot>\n    &lt;\/div>\n&lt;\/div><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>A component can also contain several slots. In order for the browser to be able to decide which HTML elements to assign to which slot, so-called \u201cnamed slots\u201d have to be used in this case, i.e. the slots are given a specific name attribute. A component must not contain more than one slot without a name attribute. This one is called the \u201cdefault slot\u201d. Here is an example of how this can look in the component:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;div>\n    &lt;div id=\"header\">\n        &lt;h1>\n            &lt;slot name=\"header\">&lt;\/slot>\n        &lt;\/h1>\n    &lt;\/div>\n    &lt;div id=\"icon\">\n        &lt;slot name=\"icon\">&lt;\/slot>\n    &lt;\/div>\n    &lt;div id=\"content\">\n        &lt;slot>&lt;slot>\n    &lt;\/div>\n&lt;\/div><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This is an example of how this could look when used:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;app-notification-box>\n    &lt;p>Some Content&lt;\/p>\n    &lt;span slot=\"header\">A meaningful Header&lt;\/span>\n    &lt;img slot=\"icon\" src=\"...\" alt=\"notification icon\"\/>\n&lt;\/app-notification-box><\/pre>\n\n\n\n<p>You can see how the \u201cslot\u201d attribute is used here. The values have to match the \u201cname\u201d attributes of the slots within the component. Consequently, this is part of a component\u2019s public API and has to be documented accordingly.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Events<\/h2>\n\n\n\n<p>So far, we have only considered how data can be submitted to the components, but we have not yet looked at the opposite direction. In order to be truly interactive, developers must also be able to respond to certain events and accept data from the component.<\/p>\n\n\n\n<p>This is the purpose of HTML events. We are only going to take a brief look at this aspect in this post and address it in more detail later.<\/p>\n\n\n\n<p>Web components can generate both standard events and custom events.<\/p>\n\n\n\n<p>Standard events are useful if the type of event also appears with standard HTML elements and does not need to be invented, e.g. a <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/KeyboardEvent\" target=\"_blank\" rel=\"noreferrer noopener\">KeyboardEvent<\/a>. Custom events are useful if additional data are to be sent with the event as payload. For example, if we build our own interactive table component where the users can select individual lines, it may be advisable to trigger an event upon selection that contains the data from the selected line as payload.<\/p>\n\n\n\n<p>The mechanism for triggering an event is the same for all kinds of events. It can be seen in the following code block:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class InteractiveComponent extends HTMLElement {\n\n    triggerStandardEvent() {\n        const event = new Event(\"close\")\n        this.dispatchEvent(event)\n    }\n\n    triggerCustomEvent() {\n        const event = new CustomEvent(\"some-reason\", \n            { detail: { someData: \"...\" }}\n        )\n        this.dispatchEvent(event)\n    }\n}<\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To generate an event, you either generate an instance of \u201cevent\u201d or <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Event\" target=\"_blank\" rel=\"noreferrer noopener\">one of the other event classes<\/a> (one of which is \u201cCustomEvent\u201d). Every event constructor expects the first parameter to be the type of event. This type is later used to register listeners for these events as well.<\/p>\n\n\n\n<p>The second parameter is optional and constitutes a JavaScript object that configures the event. For CustomEvent, for example, the \u201cdetail\u201d field is provided to submit any desired payload data.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>This post gives a brief introduction to the topic of \u201cweb components\u201d, and with the methods shown, you can already build your own components. There are, of course, numerous other aspects that need to be considered in the development of web components. After all, this topic fills a number of reference books. In <a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/topic\/web-components\/\">this series of blog posts<\/a>, we want to focus on some of the pitfalls that can occur with individual issues, and examine how to avoid them. This series will also include a critical analysis of the web component API. The <a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-2\/\">next blog posts<\/a> are going to focus on the interaction with SPA frameworks in particular.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So-called \u201cweb components\u201d are one way of building reusable UI components for web applications. Unlike common single-page app frameworks such as React or Angular, the component model is based on web standards<\/p>\n","protected":false},"author":70,"featured_media":1182,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","footnotes":""},"categories":[8],"tags":[203,259,298,309,398,612,695,702,703],"topics":[701],"class_list":["post-1179","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web","tag-editorschoice","tag-angular-cli","tag-web-components","tag-react","tag-web","tag-web-application","tag-spa-frameworks","tag-web-applications","tag-ui-components","topics-web-components"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Web Components (Part 1) \u2013 Building Your Own Components - ZEISS Digital Innovation Blog<\/title>\n<meta name=\"description\" content=\"So-called \u201cweb components\u201d are one way of building reusable UI components for web applications. Unlike common single-page app frameworks such as React or Angular, the component model is based on web standards\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Web Components (Part 1) \u2013 Building Your Own Components - ZEISS Digital Innovation Blog\" \/>\n<meta property=\"og:description\" content=\"So-called \u201cweb components\u201d are one way of building reusable UI components for web applications. Unlike common single-page app frameworks such as React or Angular, the component model is based on web standards\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/\" \/>\n<meta property=\"og:site_name\" content=\"Digital Innovation Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-12-03T12:08:06+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-05-19T06:18:27+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2020\/11\/202011_WebComponents_1_fi.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1182\" \/>\n\t<meta property=\"og:image:height\" content=\"666\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Manuel Mauky\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manuel Mauky\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/\",\"name\":\"Web Components (Part 1) \u2013 Building Your Own Components - ZEISS Digital Innovation Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2020\/11\/202011_WebComponents_1_fi.png\",\"datePublished\":\"2020-12-03T12:08:06+00:00\",\"dateModified\":\"2021-05-19T06:18:27+00:00\",\"author\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/9ebfb0f3f562d20f6156630b4d1e5ff5\"},\"description\":\"So-called \u201cweb components\u201d are one way of building reusable UI components for web applications. Unlike common single-page app frameworks such as React or Angular, the component model is based on web standards\",\"breadcrumb\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/#primaryimage\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2020\/11\/202011_WebComponents_1_fi.png\",\"contentUrl\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2020\/11\/202011_WebComponents_1_fi.png\",\"width\":1182,\"height\":666},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web Components (Part 1) \u2013 Building Your Own Components\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/\",\"name\":\"Digital Innovation Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/9ebfb0f3f562d20f6156630b4d1e5ff5\",\"name\":\"Manuel Mauky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2024\/06\/Mauky_Manuel_Profilbild_300x300px-150x150.jpg\",\"contentUrl\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2024\/06\/Mauky_Manuel_Profilbild_300x300px-150x150.jpg\",\"caption\":\"Manuel Mauky\"},\"description\":\"Manuel has been working as a software developer at ZEISS Digital Innovation in G\u00f6rlitz since 2010. In addition to Java, he mainly deals with JavaScript and TypeScript and the development of modern web applications. He is also interested in functional programming and regularly gives lectures on these topics. Manuel studied computer science in G\u00f6rlitz and organizes the Java User Group G\u00f6rlitz.\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/author\/enmanuelmauky\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Web Components (Part 1) \u2013 Building Your Own Components - ZEISS Digital Innovation Blog","description":"So-called \u201cweb components\u201d are one way of building reusable UI components for web applications. Unlike common single-page app frameworks such as React or Angular, the component model is based on web standards","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/","og_locale":"en_US","og_type":"article","og_title":"Web Components (Part 1) \u2013 Building Your Own Components - ZEISS Digital Innovation Blog","og_description":"So-called \u201cweb components\u201d are one way of building reusable UI components for web applications. Unlike common single-page app frameworks such as React or Angular, the component model is based on web standards","og_url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/","og_site_name":"Digital Innovation Blog","article_published_time":"2020-12-03T12:08:06+00:00","article_modified_time":"2021-05-19T06:18:27+00:00","og_image":[{"width":1182,"height":666,"url":"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2020\/11\/202011_WebComponents_1_fi.png","type":"image\/png"}],"author":"Manuel Mauky","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Manuel Mauky","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/","name":"Web Components (Part 1) \u2013 Building Your Own Components - ZEISS Digital Innovation Blog","isPartOf":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/#primaryimage"},"image":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/#primaryimage"},"thumbnailUrl":"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2020\/11\/202011_WebComponents_1_fi.png","datePublished":"2020-12-03T12:08:06+00:00","dateModified":"2021-05-19T06:18:27+00:00","author":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/9ebfb0f3f562d20f6156630b4d1e5ff5"},"description":"So-called \u201cweb components\u201d are one way of building reusable UI components for web applications. Unlike common single-page app frameworks such as React or Angular, the component model is based on web standards","breadcrumb":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/#primaryimage","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2020\/11\/202011_WebComponents_1_fi.png","contentUrl":"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2020\/11\/202011_WebComponents_1_fi.png","width":1182,"height":666},{"@type":"BreadcrumbList","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/web-components-part-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/"},{"@type":"ListItem","position":2,"name":"Web Components (Part 1) \u2013 Building Your Own Components"}]},{"@type":"WebSite","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/","name":"Digital Innovation Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/9ebfb0f3f562d20f6156630b4d1e5ff5","name":"Manuel Mauky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/image\/","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2024\/06\/Mauky_Manuel_Profilbild_300x300px-150x150.jpg","contentUrl":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2024\/06\/Mauky_Manuel_Profilbild_300x300px-150x150.jpg","caption":"Manuel Mauky"},"description":"Manuel has been working as a software developer at ZEISS Digital Innovation in G\u00f6rlitz since 2010. In addition to Java, he mainly deals with JavaScript and TypeScript and the development of modern web applications. He is also interested in functional programming and regularly gives lectures on these topics. Manuel studied computer science in G\u00f6rlitz and organizes the Java User Group G\u00f6rlitz.","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/author\/enmanuelmauky\/"}]}},"author_meta":{"display_name":"Manuel Mauky","author_link":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/author\/enmanuelmauky\/"},"featured_img":"https:\/\/blogs.zeiss.com\/digital-innovation\/de\/wp-content\/uploads\/sites\/2\/2020\/11\/202011_WebComponents_1_fi-600x338.png","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Web<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">Web<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Editor&#039;s Choice<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Angular-CLI<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Web Components<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">React<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">web<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">web application<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">SPA-Frameworks<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">web applications<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">UI components<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">Editor&#039;s Choice<\/span>","<span class=\"advgb-post-tax-term\">Angular-CLI<\/span>","<span class=\"advgb-post-tax-term\">Web Components<\/span>","<span class=\"advgb-post-tax-term\">React<\/span>","<span class=\"advgb-post-tax-term\">web<\/span>","<span class=\"advgb-post-tax-term\">web application<\/span>","<span class=\"advgb-post-tax-term\">SPA-Frameworks<\/span>","<span class=\"advgb-post-tax-term\">web applications<\/span>","<span class=\"advgb-post-tax-term\">UI components<\/span>"]}},"comment_count":"0","relative_dates":{"created":"Posted 5 years ago","modified":"Updated 5 years ago"},"absolute_dates":{"created":"Posted on December 3, 2020","modified":"Updated on May 19, 2021"},"absolute_dates_time":{"created":"Posted on December 3, 2020 12:08 pm","modified":"Updated on May 19, 2021 6:18 am"},"featured_img_caption":"","series_order":"","_links":{"self":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts\/1179","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/users\/70"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/comments?post=1179"}],"version-history":[{"count":11,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts\/1179\/revisions"}],"predecessor-version":[{"id":1466,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts\/1179\/revisions\/1466"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/media\/1182"}],"wp:attachment":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/media?parent=1179"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/categories?post=1179"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/tags?post=1179"},{"taxonomy":"topics","embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/topics?post=1179"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}