[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-article-how-to-use-web-components-in-react":3},{"meta":4,"html":29,"authorName":30,"authorFacebookUrl":31,"authorProfileImage":32,"authorWebsite":33,"authorJobTitle":34,"authorTwitterUrl":35,"wordCount":36,"recommended":37},{"id":5,"slug":6,"type":7,"title":8,"excerpt":9,"metaTitle":10,"metaDescription":10,"canonicalUrl":10,"featureImage":11,"publishedAt":16,"createdAt":17,"updatedAt":18,"featured":19,"readingTime":20,"tags":21,"author":28,"recommendedSlugs":10},"63681e8972d57a060160cf48","how-to-use-web-components-in-react","post","How To Use Web Components in React","Web Components enable us to develop entirely independently of frontend frameworks. Here is how to use them in React.",null,{"url":12,"alt":13,"caption":8,"width":14,"height":15},"\u002Fblog\u002Fcontent\u002Fimages\u002F2023\u002F08\u002Freact.png","Shaking Hands with black transparent overlay showing React and Web Components Logo",900,530,"2022-11-06T21:18:45.000+00:00","2022-11-06T20:52:25.000+00:00","2024-09-19T19:13:10.000+00:00",false,5,[22,25],{"name":23,"slug":24},"Web Components","web-components",{"name":26,"slug":27},"React","react","marius-bongarts","\u003Cp>Many developers worry that Web Components might replace frontend frameworks and libraries.\u003C\u002Fp>\n\u003Cp>\n  In our eyes, that will not happen because they tackle different issues. The real key to a robust software architecture\n  is combining them.\n\u003C\u002Fp>\n\u003Cblockquote>\n  \u003Cem>“Most people who use React don’t use Web Components, but you may want to […].” — \u003C\u002Fem>\n  \u003Ca href=\"https:\u002F\u002Freactjs.org\u002Fdocs\u002Fweb-components.html\" rel=\"noopener ugc nofollow noopener noopener\">\n    \u003Cem>https:\u002F\u002Freactjs.org\u003C\u002Fem>\n  \u003C\u002Fa>\n\u003C\u002Fblockquote>\n\u003Cp>Before we dive into our example, let's look at the purpose of Web Components and React.\u003C\u002Fp>\n\u003Cfigure class=\"kg-card kg-bookmark-card\">\n  \u003Ca\n    class=\"kg-bookmark-container\"\n    href=\"https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fwill-web-components-replace-frontend-frameworks-they-are-built-to-solve-different-problems\u002F\"\n  >\n    \u003Cdiv class=\"kg-bookmark-content\">\n      \u003Cdiv class=\"kg-bookmark-title\">Will Web Components Replace Frontend Frameworks?\u003C\u002Fdiv>\n      \u003Cdiv class=\"kg-bookmark-description\">\n        Web Components will not replace frontend frameworks but they can enhance those frameworks by replacing their\n        component layer with a native solution.\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"kg-bookmark-metadata\">\n        \u003Cimg class=\"kg-bookmark-icon\" src=\"https:\u002F\u002Fweb-highlights.com\u002Ffavicon.ico\" alt=\"\" \u002F>\n        \u003Cspan class=\"kg-bookmark-author\">Web Highlights Blog\u003C\u002Fspan>\n        \u003Cspan class=\"kg-bookmark-publisher\">Marius Bongarts\u003C\u002Fspan>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"kg-bookmark-thumbnail\">\n      \u003Cimg src=\"\u002Fblog\u002Fcontent\u002Fimages\u002F2022\u002F10\u002Fwebcomponents.webp\" alt=\"\" \u002F>\n    \u003C\u002Fdiv>\n  \u003C\u002Fa>\n\u003C\u002Ffigure>\n\u003Ch2 id=\"purpose-of-web-components\">Purpose of Web Components\u003C\u002Fh2>\n\u003Cp>\n  Web Components are reusable client-side components based on official web standards and supported by all major\n  browsers. They are an excellent way of\n  \u003Cstrong>encapsulating\u003C\u002Fstrong>\n  functionality\n  \u003Cstrong>\u003C\u002Fstrong>\n  from the rest of our code. Not only that, but you can\n  \u003Cstrong>reuse\u003C\u002Fstrong>\n  them in every web application and web page.\n\u003C\u002Fp>\n\u003Cp>\n  Their purpose is to write strongly encapsulated custom elements to use everywhere. Web Components enable us to develop\n  entirely independently of frontend frameworks.\n\u003C\u002Fp>\n\u003Cblockquote>\n  \u003Cem>\n    The primary benefit of Web Components is that we can use them everywhere. With any framework, or even without a\n    framework. — \n  \u003C\u002Fem>\n  \u003Ca href=\"https:\u002F\u002Fv3.vuejs.org\u002Fguide\u002Fweb-components.html\" rel=\"noopener ugc nofollow noopener noopener\">\n    \u003Cem>vuejs.org\u003C\u002Fem>\n  \u003C\u002Fa>\n\u003C\u002Fblockquote>\n\u003Cp>\n  \u003Cstrong>It's really important to understand this point\u003C\u002Fstrong>\n  : Web Components are web standards that can be used anywhere and will always be relevant!\n\u003C\u002Fp>\n\u003Cp>\n  For example, when I started building my PDF &amp; Web Highlighter Chrome Extension five years ago, I chose to create\n  the core parts of my extension using Web Components.\n\u003C\u002Fp>\n\u003Cblockquote>\n  That doesn't mean you should build everything with Web Components. It's completely fine to\n  \u003Ca href=\"https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fhow-to-use-web-components-in-react\u002F\">mix Web Components with React\u003C\u002Fa>\n  or any other frontend framework.\n\u003C\u002Fblockquote>\n\u003Cp>\n  Over the years, I've switched out nearly every other technology—like moving from Vue 2 to Vue 3 and then from a\n  client-side Vue app to Nuxt 3, among many other changes.\n\u003C\u002Fp>\n\u003Cp>\n  The one thing that has remained stable throughout it all is the Web Components, which have been with me since the\n  start.\n\u003C\u002Fp>\n\u003Cp>\n  If you want to learn more about my tech stack, you can\n  \u003Ca\n    href=\"https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fthe-tech-stack-behind-web-highlights-a-chrome-extension-with-over-10-000-weekly-users\u002F\"\n  >\n    read more about it here\n  \u003C\u002Fa>\n  :\n\u003C\u002Fp>\n\u003Cfigure class=\"kg-card kg-bookmark-card\">\n  \u003Ca\n    class=\"kg-bookmark-container\"\n    href=\"https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fthe-tech-stack-behind-web-highlights-a-chrome-extension-with-over-10-000-weekly-users\u002F\"\n  >\n    \u003Cdiv class=\"kg-bookmark-content\">\n      \u003Cdiv class=\"kg-bookmark-title\">Web Highlights Tech Stack: Chrome Extension With 10k+ Users\u003C\u002Fdiv>\n      \u003Cdiv class=\"kg-bookmark-description\">\n        Explore the tech stack of Web Highlights, a Chrome extension using Web Components and Vue.js for saving and\n        highlighting web content easily.\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"kg-bookmark-metadata\">\n        \u003Cimg class=\"kg-bookmark-icon\" src=\"https:\u002F\u002Fweb-highlights.com\u002Ffavicon.ico\" alt=\"\" \u002F>\n        \u003Cspan class=\"kg-bookmark-author\">Web Highlights Blog\u003C\u002Fspan>\n        \u003Cspan class=\"kg-bookmark-publisher\">Marius Bongarts\u003C\u002Fspan>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"kg-bookmark-thumbnail\">\n      \u003Cimg\n        src=\"\u002Fblog\u002Fcontent\u002Fimages\u002F2023\u002F02\u002FYellow-Bold-Education-Course-Vlog-YouTube-Thumbnail.webp\"\n        alt=\"\"\n      \u002F>\n    \u003C\u002Fdiv>\n  \u003C\u002Fa>\n\u003C\u002Ffigure>\n\u003Ch2 id=\"purpose-of-react\">Purpose of React\u003C\u002Fh2>\n\u003Cp>\n  While Web Components provide strong encapsulation for reusable components, React provides a declarative library that\n  syncs the DOM with your data.\n\u003C\u002Fp>\n\u003Cblockquote>\n  \u003Cem>\n    As a developer, you are free to use React in your Web Components, or to use Web Components in React, or both. — \n  \u003C\u002Fem>\n  \u003Ca href=\"https:\u002F\u002Freactjs.org\u002Fdocs\u002Fweb-components.html\" rel=\"noopener ugc nofollow noopener noopener\">\n    \u003Cem>https:\u002F\u002Freactjs.org\u003C\u002Fem>\n  \u003C\u002Fa>\n\u003C\u002Fblockquote>\n\u003Cp>\n  The main difference between React components and Web Components is that React components can only be used inside a\n  React application. A Web Component, on the other hand, can be used anywhere.\n  \u003Ca href=\"https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fhow-to-use-web-components-in-react\u002F\">We can use it in React\u003C\u002Fa>\n  , Vue,\n  \u003Ca href=\"https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fhow-to-build-a-chrome-extension-using-angular\u002F\">Angular\u003C\u002Fa>\n  , or any other web application.\n\u003C\u002Fp>\n\u003Cp>\n  React, or other frameworks are the way to go when your components need to handle a lot of data that needs to be passed\n  down to child components.\n\u003C\u002Fp>\n\u003Cfigure class=\"kg-card kg-bookmark-card\">\n  \u003Ca class=\"kg-bookmark-container\" href=\"https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fhow-to-use-web-components-in-react\u002F\">\n    \u003Cdiv class=\"kg-bookmark-content\">\n      \u003Cdiv class=\"kg-bookmark-title\">How To Use Web Components in React\u003C\u002Fdiv>\n      \u003Cdiv class=\"kg-bookmark-description\">\n        Web Components enable us to develop entirely independently of frontend frameworks. Here is how to use them in\n        React.\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"kg-bookmark-metadata\">\n        \u003Cimg class=\"kg-bookmark-icon\" src=\"https:\u002F\u002Fweb-highlights.com\u002Ffavicon.ico\" alt=\"\" \u002F>\n        \u003Cspan class=\"kg-bookmark-author\">Web Highlights Blog\u003C\u002Fspan>\n        \u003Cspan class=\"kg-bookmark-publisher\">Marius Bongarts\u003C\u002Fspan>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"kg-bookmark-thumbnail\">\n      \u003Cimg src=\"\u002Fblog\u002Fcontent\u002Fimages\u002F2023\u002F08\u002Freact.webp\" alt=\"\" \u002F>\n    \u003C\u002Fdiv>\n  \u003C\u002Fa>\n\u003C\u002Ffigure>\n\u003Ch2 id=\"building-a-web-component\">Building a Web Component\u003C\u002Fh2>\n\u003Cp>Let's go ahead and build our first Web Component, which we will integrate into a React application.\u003C\u002Fp>\n\u003Cp>\n  We will keep things simple and create an effortless custom element. If you are interested in building more complex Web\n  Components, go through my series of articles:\n  \u003Ca href=\"https:\u002F\u002Fmedium.com\u002F@mariusbongarts11\u002Fthe-complete-web-component-guide-part-1-custom-elements-a627af805df8\">\n    The Complete Web Component Guide\n  \u003C\u002Fa>\n  .\n\u003C\u002Fp>\n\u003Cp>\n  Here is the JavaScript code for our\n  \u003Ccode>hello-world\u003C\u002Fcode>\n  custom element:\n\u003C\u002Fp>\n\u003C!--kg-card-begin: html-->\n\u003Cdiv class=\"gist-embed\">\u003Cdiv id=\"gist116466752\" class=\"gist\">\n    \u003Cdiv class=\"gist-file\" translate=\"no\" data-color-mode=\"light\" data-light-theme=\"light\">\n      \u003Cdiv class=\"gist-data\">\n        \n\u003Cdiv class=\"js-gist-file-update-container js-task-list-container\">\n      \u003Cdiv id=\"file-hello-world-component-js\" class=\"file my-2\">\n    \n    \u003Cdiv itemprop=\"text\"\n      class=\"Box-body p-0 blob-wrapper data type-javascript  \"\n      style=\"overflow: auto\" tabindex=\"0\" role=\"region\"\n      aria-label=\"hello-world-component.js content, created by MariusBongarts on 10:15AM on May 24, 2022.\"\n    >\n\n        \n\u003Cdiv class=\"js-check-hidden-unicode js-blob-code-container blob-code-content\">\n\n  \u003Ctemplate class=\"js-file-alert-template\">\n  \u003Cdiv data-view-component=\"true\" class=\"flash flash-warn flash-full d-flex flex-items-center\">\n  \u003Csvg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    \u003Cpath d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n    \u003Cspan>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      \u003Ca class=\"Link--inTextBlock\" href=\"https:\u002F\u002Fgithub.co\u002Fhiddenchars\" target=\"_blank\">Learn more about bidirectional Unicode characters\u003C\u002Fa>\n    \u003C\u002Fspan>\n\n\n  \u003Cdiv data-view-component=\"true\" class=\"flash-action\">        \u003Ca href=\"{{ revealButtonHref }}\" data-view-component=\"true\" class=\"btn-sm btn\">    Show hidden characters\n\u003C\u002Fa>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003C\u002Ftemplate>\n\u003Ctemplate class=\"js-line-alert-template\">\n  \u003Cspan aria-label=\"This line has hidden Unicode characters\" data-view-component=\"true\" class=\"line-alert tooltipped tooltipped-e\">\n    \u003Csvg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    \u003Cpath d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\u003C\u002Fspan>\u003C\u002Ftemplate>\n\n  \u003Ctable data-hpc class=\"highlight tab-size js-file-line-container\" data-tab-size=\"4\" data-paste-markdown-skip data-tagsearch-path=\"hello-world-component.js\">\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L1\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"1\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC1\" class=\"blob-code blob-code-inner js-file-line\">\u003Cspan class=pl-k>class\u003C\u002Fspan> \u003Cspan class=pl-v>HelloWorldComponent\u003C\u002Fspan> \u003Cspan class=pl-k>extends\u003C\u002Fspan> \u003Cspan class=pl-v>HTMLElement\u003C\u002Fspan> \u003Cspan class=pl-kos>{\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L2\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"2\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC2\" class=\"blob-code blob-code-inner js-file-line\">  \u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L3\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"3\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC3\" class=\"blob-code blob-code-inner js-file-line\">  \u003Cspan class=pl-en>constructor\u003C\u002Fspan>\u003Cspan class=pl-kos>(\u003C\u002Fspan>\u003Cspan class=pl-kos>)\u003C\u002Fspan> \u003Cspan class=pl-kos>{\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L4\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"4\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC4\" class=\"blob-code blob-code-inner js-file-line\">    \u003Cspan class=pl-smi>super\u003C\u002Fspan>\u003Cspan class=pl-kos>(\u003C\u002Fspan>\u003Cspan class=pl-kos>)\u003C\u002Fspan>\u003Cspan class=pl-kos>;\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L5\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"5\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC5\" class=\"blob-code blob-code-inner js-file-line\">  \u003Cspan class=pl-kos>}\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L6\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"6\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC6\" class=\"blob-code blob-code-inner js-file-line\">  \u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L7\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"7\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC7\" class=\"blob-code blob-code-inner js-file-line\">  \u003Cspan class=pl-en>connectedCallback\u003C\u002Fspan>\u003Cspan class=pl-kos>(\u003C\u002Fspan>\u003Cspan class=pl-kos>)\u003C\u002Fspan> \u003Cspan class=pl-kos>{\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L8\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"8\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC8\" class=\"blob-code blob-code-inner js-file-line\">    \u003Cspan class=pl-smi>this\u003C\u002Fspan>\u003Cspan class=pl-kos>.\u003C\u002Fspan>\u003Cspan class=pl-c1>innerHTML\u003C\u002Fspan> \u003Cspan class=pl-c1>=\u003C\u002Fspan> \u003Cspan class=pl-s>`&lt;h1&gt;Hello world!&lt;\u002Fh1&gt;`\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L9\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"9\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC9\" class=\"blob-code blob-code-inner js-file-line\">  \u003Cspan class=pl-kos>}\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L10\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"10\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC10\" class=\"blob-code blob-code-inner js-file-line\">\n\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L11\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"11\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC11\" class=\"blob-code blob-code-inner js-file-line\">\u003Cspan class=pl-kos>}\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L12\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"12\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC12\" class=\"blob-code blob-code-inner js-file-line\">\n\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-hello-world-component-js-L13\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"13\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-hello-world-component-js-LC13\" class=\"blob-code blob-code-inner js-file-line\">\u003Cspan class=pl-s1>customElements\u003C\u002Fspan>\u003Cspan class=pl-kos>.\u003C\u002Fspan>\u003Cspan class=pl-en>define\u003C\u002Fspan>\u003Cspan class=pl-kos>(\u003C\u002Fspan>\u003Cspan class=pl-s>&quot;hello-world&quot;\u003C\u002Fspan>\u003Cspan class=pl-kos>,\u003C\u002Fspan> \u003Cspan class=pl-v>HelloWorldComponent\u003C\u002Fspan>\u003Cspan class=pl-kos>)\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n  \u003C\u002Ftable>\n\u003C\u002Fdiv>\n\n\n    \u003C\u002Fdiv>\n\n  \u003C\u002Fdiv>\n\n\u003C\u002Fdiv>\n\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"gist-meta\">\n        \u003Ca href=\"https:\u002F\u002Fgist.github.com\u002FMariusBongarts\u002F47507e554476dde29630ab43f612f0fa\u002Fraw\u002F56968e3bd01601ec005daad3bc806993bd0b9ea4\u002Fhello-world-component.js\" style=\"float:right\" class=\"Link--inTextBlock\">view raw\u003C\u002Fa>\n        \u003Ca href=\"https:\u002F\u002Fgist.github.com\u002FMariusBongarts\u002F47507e554476dde29630ab43f612f0fa#file-hello-world-component-js\" class=\"Link--inTextBlock\">\n          hello-world-component.js\n        \u003C\u002Fa>\n        hosted with &#10084; by \u003Ca class=\"Link--inTextBlock\" href=\"https:\u002F\u002Fgithub.com\">GitHub\u003C\u002Fa>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C!--kg-card-end: html-->\n\u003Cp>Having this JavaScript code loaded in our HTML, we can easily include our component like this:\u003C\u002Fp>\n\u003Cp>\u003Ccode>&lt;hello-world&gt;&lt;\u002Fhello-world&gt;\u003C\u002Fcode>\u003C\u002Fp>\n\u003Cp>\n  That will show our \"\n  \u003Cstrong>Hello World!\"\u003C\u002Fstrong>\n  headline. Try it yourself. Here is the\n  \u003Ca href=\"https:\u002F\u002Fcodepen.io\u002Fmarius2502\u002Fpen\u002FZErXXLL\" rel=\"noopener\">CodePen\u003C\u002Fa>\n  .\n\u003C\u002Fp>\n\u003Cfigure class=\"kg-card kg-embed-card\">\n  \u003Ciframe\n    id=\"cp_embed_ZErXXLL\"\n    src=\"https:\u002F\u002Fcodepen.io\u002Fmarius2502\u002Fembed\u002Fpreview\u002FZErXXLL?default-tabs=js%2Cresult&amp;height=300&amp;host=https%3A%2F%2Fcodepen.io&amp;slug-hash=ZErXXLL\"\n    title=\"Hello World Web Component\"\n    scrolling=\"no\"\n    frameborder=\"0\"\n    height=\"300\"\n    allowtransparency=\"true\"\n    class=\"cp_embed_iframe\"\n    style=\"width: 100%; overflow: hidden\"\n  >\u003C\u002Fiframe>\n\u003C\u002Ffigure>\n\u003Ch2 id=\"integrate-a-web-component-in-react\">Integrate a Web Component in React\u003C\u002Fh2>\n\u003Cp>\n  Let's include our Web Component in a running React application. To make it easy, we will use a React starter project\n  on\n  \u003Ca href=\"https:\u002F\u002Fstackblitz.com\u002Fedit\u002Freact-ts\" rel=\"noopener\">Stackblitz\u003C\u002Fa>\n  . After that, we create the file\n  \u003Ccode>hello-world.js\u003C\u002Fcode>\n  and put the code of our Web Component from above in it.\n\u003C\u002Fp>\n\u003Cp>Next, we go into our React component and import our Javascript file, including the code of our Web Component:\u003C\u002Fp>\n\u003Cp>\u003Ccode>import .\u002Fhello-world\u003C\u002Fcode>\u003C\u002Fp>\n\u003Cp>And voila! The preview displays our Web Component. We successfully integrated a custom element into React.\u003C\u002Fp>\n\u003Cp>Still, there is an error in the editor:\u003C\u002Fp>\n\u003Cfigure class=\"kg-card kg-image-card kg-card-hascaption\">\n  \u003Cimg\n    src=\"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F1600\u002F1*5i-H6iqiBJsrdPWUK1jX5g.png\"\n    class=\"kg-image\"\n    alt=\"Property ‘hello-world’ does not exist on type ‘JSX.IntrinsicElements’.\"\n    loading=\"lazy\"\n  \u002F>\n  \u003Cfigcaption>Property does not exist&nbsp;error\u003C\u002Ffigcaption>\n\u003C\u002Ffigure>\n\u003Cp>\n  It says, \"\n  \u003Cem>Property 'hello-world' does not exist on type 'JSX.IntrinsicElements'\"\u003C\u002Fem>\n  . The error occurs because React components should always start with an uppercase letter. Our component's name begins\n  with a lowercase letter. So, should we change our custom tag to begin with an uppercase letter?\n\u003C\u002Fp>\n\u003Cp>Let's try this:\u003C\u002Fp>\n\u003Cfigure class=\"kg-card kg-image-card kg-card-hascaption\">\n  \u003Cimg\n    src=\"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F1600\u002F1*mdRp-QzldV-4myWT2pBmww.png\"\n    class=\"kg-image\"\n    alt=\"Not a valid custom element name\"\n    loading=\"lazy\"\n  \u002F>\n  \u003Cfigcaption>Not a valid custom element&nbsp;name\u003C\u002Ffigcaption>\n\u003C\u002Ffigure>\n\u003Cp>\n  As you can see, I changed our custom tag to\n  \u003Ccode>Hello-world\u003C\u002Fcode>\n  . But, when calling\n  \u003Ccode>customElements.define(\"Hello-world\")\u003C\u002Fcode>\n  the browser throws an exception because we are violating one of two rules to be followed for the element's tag name:\n\u003C\u002Fp>\n\u003Cul>\n  \u003Cli>\n    \u003Cem>Name has to\u003C\u002Fem>\n    \u003Cstrong>\u003Cem>start with a lowercase ASCII character\u003C\u002Fem>\u003C\u002Fstrong>\n    \u003Cem>. It cannot have an uppercase ASCII character anywhere.\u003C\u002Fem>\n  \u003C\u002Fli>\n  \u003Cli>\n    \u003Cstrong>\u003Cem>Name must contain a dash\u003C\u002Fem>\u003C\u002Fstrong>\n    \u003Cem> — character. This dash character helps the browser to distinguish custom elements from regular elements.\u003C\u002Fem>\n  \u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\n  We are only allowed to use lowercase characters, and the component needs to contain at least one dash. So, how to fix\n  the error? Typescript gives us the possibility to declare our own types. To fix the error, we can define our custom\n  element type by extending React's\n  \u003Ccode>IntrinsicElements\u003C\u002Fcode>\n  interface like this:\n\u003C\u002Fp>\n\u003C!--kg-card-begin: html-->\n\u003Cdiv class=\"gist-embed\">\u003Cdiv id=\"gist116523561\" class=\"gist\">\n    \u003Cdiv class=\"gist-file\" translate=\"no\" data-color-mode=\"light\" data-light-theme=\"light\">\n      \u003Cdiv class=\"gist-data\">\n        \n\u003Cdiv class=\"js-gist-file-update-container js-task-list-container\">\n      \u003Cdiv id=\"file-app-tsx\" class=\"file my-2\">\n    \n    \u003Cdiv itemprop=\"text\"\n      class=\"Box-body p-0 blob-wrapper data type-tsx  \"\n      style=\"overflow: auto\" tabindex=\"0\" role=\"region\"\n      aria-label=\"App.tsx content, created by MariusBongarts on 09:14PM on May 26, 2022.\"\n    >\n\n        \n\u003Cdiv class=\"js-check-hidden-unicode js-blob-code-container blob-code-content\">\n\n  \u003Ctemplate class=\"js-file-alert-template\">\n  \u003Cdiv data-view-component=\"true\" class=\"flash flash-warn flash-full d-flex flex-items-center\">\n  \u003Csvg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    \u003Cpath d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n    \u003Cspan>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      \u003Ca class=\"Link--inTextBlock\" href=\"https:\u002F\u002Fgithub.co\u002Fhiddenchars\" target=\"_blank\">Learn more about bidirectional Unicode characters\u003C\u002Fa>\n    \u003C\u002Fspan>\n\n\n  \u003Cdiv data-view-component=\"true\" class=\"flash-action\">        \u003Ca href=\"{{ revealButtonHref }}\" data-view-component=\"true\" class=\"btn-sm btn\">    Show hidden characters\n\u003C\u002Fa>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003C\u002Ftemplate>\n\u003Ctemplate class=\"js-line-alert-template\">\n  \u003Cspan aria-label=\"This line has hidden Unicode characters\" data-view-component=\"true\" class=\"line-alert tooltipped tooltipped-e\">\n    \u003Csvg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    \u003Cpath d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\u003C\u002Fspan>\u003C\u002Ftemplate>\n\n  \u003Ctable data-hpc class=\"highlight tab-size js-file-line-container\" data-tab-size=\"4\" data-paste-markdown-skip data-tagsearch-path=\"App.tsx\">\n        \u003Ctr>\n          \u003Ctd id=\"file-app-tsx-L1\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"1\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-app-tsx-LC1\" class=\"blob-code blob-code-inner js-file-line\">\u003Cspan class=pl-k>declare\u003C\u002Fspan> global \u003Cspan class=pl-kos>{\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-app-tsx-L2\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"2\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-app-tsx-LC2\" class=\"blob-code blob-code-inner js-file-line\">  \u003Cspan class=pl-k>namespace\u003C\u002Fspan> \u003Cspan class=pl-c1>JSX\u003C\u002Fspan> \u003Cspan class=pl-kos>{\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-app-tsx-L3\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"3\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-app-tsx-LC3\" class=\"blob-code blob-code-inner js-file-line\">    \u003Cspan class=pl-k>interface\u003C\u002Fspan> \u003Cspan class=pl-smi>IntrinsicElements\u003C\u002Fspan> \u003Cspan class=pl-kos>{\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-app-tsx-L4\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"4\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-app-tsx-LC4\" class=\"blob-code blob-code-inner js-file-line\">      \u003Cspan class=pl-s>&#39;hello-world&#39;\u003C\u002Fspan>: \u003Cspan class=pl-v>React\u003C\u002Fspan>\u003Cspan class=pl-kos>.\u003C\u002Fspan>\u003Cspan class=pl-smi>DetailedHTMLProps\u003C\u002Fspan>\u003Cspan class=pl-c1>&lt;\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-app-tsx-L5\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"5\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-app-tsx-LC5\" class=\"blob-code blob-code-inner js-file-line\">        \u003Cspan class=pl-v>React\u003C\u002Fspan>\u003Cspan class=pl-kos>.\u003C\u002Fspan>\u003Cspan class=pl-smi>HTMLAttributes\u003C\u002Fspan>\u003Cspan class=pl-c1>&lt;\u003C\u002Fspan>\u003Cspan class=pl-smi>HTMLElement\u003C\u002Fspan>\u003Cspan class=pl-c1>&gt;\u003C\u002Fspan>\u003Cspan class=pl-kos>,\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-app-tsx-L6\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"6\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-app-tsx-LC6\" class=\"blob-code blob-code-inner js-file-line\">        \u003Cspan class=pl-smi>HTMLElement\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-app-tsx-L7\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"7\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-app-tsx-LC7\" class=\"blob-code blob-code-inner js-file-line\">      \u003Cspan class=pl-c1>&gt;\u003C\u002Fspan>\u003Cspan class=pl-kos>;\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-app-tsx-L8\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"8\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-app-tsx-LC8\" class=\"blob-code blob-code-inner js-file-line\">    \u003Cspan class=pl-kos>}\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-app-tsx-L9\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"9\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-app-tsx-LC9\" class=\"blob-code blob-code-inner js-file-line\">  \u003Cspan class=pl-kos>}\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n        \u003Ctr>\n          \u003Ctd id=\"file-app-tsx-L10\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"10\">\u003C\u002Ftd>\n          \u003Ctd id=\"file-app-tsx-LC10\" class=\"blob-code blob-code-inner js-file-line\">\u003Cspan class=pl-kos>}\u003C\u002Fspan>\u003C\u002Ftd>\n        \u003C\u002Ftr>\n  \u003C\u002Ftable>\n\u003C\u002Fdiv>\n\n\n    \u003C\u002Fdiv>\n\n  \u003C\u002Fdiv>\n\n\u003C\u002Fdiv>\n\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"gist-meta\">\n        \u003Ca href=\"https:\u002F\u002Fgist.github.com\u002FMariusBongarts\u002F02075e843c3628700438b1803cd56fa9\u002Fraw\u002Fab7cbf254ed267bbc04ff9b3bfa68f0756d2ba3e\u002FApp.tsx\" style=\"float:right\" class=\"Link--inTextBlock\">view raw\u003C\u002Fa>\n        \u003Ca href=\"https:\u002F\u002Fgist.github.com\u002FMariusBongarts\u002F02075e843c3628700438b1803cd56fa9#file-app-tsx\" class=\"Link--inTextBlock\">\n          App.tsx\n        \u003C\u002Fa>\n        hosted with &#10084; by \u003Ca class=\"Link--inTextBlock\" href=\"https:\u002F\u002Fgithub.com\">GitHub\u003C\u002Fa>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C!--kg-card-end: html-->\n\u003Cp>\n  Finally, we have successfully integrated our custom element to React without any errors. Here is the\n  \u003Ca href=\"https:\u002F\u002Fstackblitz.com\u002Fedit\u002Freact-ts-t3gf2k?file=App.tsx\" rel=\"noopener\">final Stackblitz\u003C\u002Fa>\n  of the example:\n\u003C\u002Fp>\n\u003Cfigure class=\"kg-card kg-embed-card\">\n  \u003Ciframe src=\"https:\u002F\u002Fstackblitz.com\u002Fedit\u002Freact-ts-t3gf2k?embed=1&amp;file=App.tsx\" height=\"400\" width=\"745\">\u003C\u002Fiframe>\n\u003C\u002Ffigure>\n\u003Ch2 id=\"final-thoughts\">Final Thoughts\u003C\u002Fh2>\n\u003Cp>\n  Using Web Components in React is easy. Building reusable components that are usable throughout frontend frameworks\n  brings many benefits. We have learned that we should use Web Components when creating reusable components to use\n  everywhere. When it comes to handling a lot of data, React is the way to go.\n\u003C\u002Fp>\n\u003Cp>\n  I hope you enjoyed reading this article. I am always happy to answer questions, and I am open to criticism. Feel free\n  to contact me at any time 😊\n\u003C\u002Fp>\n\u003Cp>\n  Get in touch with me via\n  \u003Cstrong>\u003C\u002Fstrong>\n  \u003Ca\n    href=\"https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fmarius-bongarts-6b3638171\u002F\"\n    rel=\"noopener ugc nofollow noopener noopener noopener\"\n  >\n    \u003Cstrong>LinkedIn\u003C\u002Fstrong>\n  \u003C\u002Fa>\n  \u003Cstrong>\u003C\u002Fstrong>\n  or follow me on\n  \u003Ca href=\"https:\u002F\u002Ftwitter.com\u002FMariusBongarts\" rel=\"noopener ugc nofollow noopener noopener noopener\">\n    \u003Cstrong>Twitter\u003C\u002Fstrong>\n  \u003C\u002Fa>\n  .\n\u003C\u002Fp>\n\u003Ch3 id=\"looking-for-productivity-browser-extensions\">Looking for Productivity Browser Extensions?\u003C\u002Fh3>\n\u003Cp>\n  At\n  \u003Ca href=\"https:\u002F\u002Fweb-highlights.com\u002Fbrowser-tools\u002F\">Tooltivity\u003C\u002Fa>\n  , we review the top productivity browser extensions. Read our detailed reviews here:\n\u003C\u002Fp>\n\u003Cfigure class=\"kg-card kg-bookmark-card\">\n  \u003Ca class=\"kg-bookmark-container\" href=\"https:\u002F\u002Fweb-highlights.com\u002Fbrowser-tools\">\n    \u003Cdiv class=\"kg-bookmark-content\">\n      \u003Cdiv class=\"kg-bookmark-title\">Best Productivity Browser Extensions | Tooltivity\u003C\u002Fdiv>\n      \u003Cdiv class=\"kg-bookmark-description\">\n        Discover and compare the best productivity browser extensions at Tooltivity. Explore our in-depth reviews of top\n        tools to boost your browsing experience.\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"kg-bookmark-metadata\">\n        \u003Cimg class=\"kg-bookmark-icon\" src=\"https:\u002F\u002Fweb-highlights.com\u002Ffavicon.ico\" alt=\"\" \u002F>\n        \u003Cspan class=\"kg-bookmark-author\">Best Productivity Browser Extensions | Tooltivity\u003C\u002Fspan>\n        \u003Cspan class=\"kg-bookmark-publisher\">Marius Bongarts\u003C\u002Fspan>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"kg-bookmark-thumbnail\">\n      \u003Cimg src=\"https:\u002F\u002Fweb-highlights.com\u002Fbrowser-tools\u002Fimages\u002Ftooltivity-og-image.png\" alt=\"\" \u002F>\n    \u003C\u002Fdiv>\n  \u003C\u002Fa>\n\u003C\u002Ffigure>\n","Marius Bongarts","https:\u002F\u002Fwww.facebook.com\u002FMariusBongartsWeb","\u002Fblog\u002Fcontent\u002Fimages\u002F2022\u002F08\u002FIMG_7861_Square.jpeg","https:\u002F\u002Fmarius-bongarts.de\u002F","Founder & Software Engineer","https:\u002F\u002Ftwitter.com\u002FMariusBongarts",1241,[38,70,94],{"id":39,"slug":40,"title":41,"description":42,"url":43,"publishedAt":44,"createdAt":45,"updatedAt":44,"featured":19,"readingTime":46,"tags":47,"imageUrl":52,"imageAlt":53,"faviconUrl":54,"publishedAtString":44,"category":55,"readTimeString":69},"4c4f3f6e07b8d087c330193b","best-bookmark-manager-chrome-extensions","Top 12 Chrome Bookmark Manager Extensions: The Great Comparison","Compare the 12 best Chrome bookmark manager extensions. We tested Web Highlights, Raindrop.io, Session Buddy, Toby and more to find the top pick.","https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fbest-bookmark-manager-chrome-extensions\u002F","2026-07-28T15:00:00.000+00:00","2026-07-28T14:30:00.000+00:00",26,[48,49,50,51],"Chrome Extension","comparison","Productivity","Tools","https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fcontent\u002Fimages\u002F2026\u002F07\u002Fchrome-bookmark-manager-extensions-the-great-comparison.jpg","Top 12 Chrome Bookmark Manager Extensions","https:\u002F\u002Fweb-highlights.com\u002Ffavicon.ico",[56,63],{"type":57,"title":58,"shortTitle":59,"icon":60,"description":61,"excerpt":62},"bookmarks","Bookmarks, Clips & Save-for-Later","Bookmarks","bookmark","Organize bookmarks, export from Chrome, and capture pages with less chaos. Web Highlights helps you save smarter than the default bookmark bar.","Exporting and organizing bookmarks is a huge search topic for a reason: browser defaults don’t scale. Web Highlights adds structure—tags, notes, and highlights—so saved pages stay findable, whether you’re migrating from Pocket or just tired of duplicate folders.",{"type":64,"title":65,"shortTitle":50,"icon":66,"description":67,"excerpt":68},"productivity","Browser Productivity & Chrome Extensions","command","Curated extension lists, focus workflows, and tips for getting more from Chrome—always with an eye toward reading, capture, and learning.","Productivity isn’t only task managers. These articles cover the browser layer: extensions that protect focus, comparisons that save you from dead-end tools, and setup tips that keep your reading and capture stack lightweight but powerful.","26 min read",{"id":71,"slug":72,"title":73,"description":74,"url":75,"publishedAt":76,"createdAt":77,"updatedAt":76,"featured":19,"readingTime":78,"tags":79,"imageUrl":83,"imageAlt":84,"faviconUrl":54,"publishedAtString":76,"category":85,"readTimeString":93},"6a61e89d909b7209ced49b2f","top-chrome-language-learning-extensions-the-great-comparison","Top 10 Chrome Extensions For Language Learning: The Great Comparison","Compare the 10 best Chrome language learning extensions — popup dictionaries, AI translators, subtitle tools and flashcard trainers tested, rated and ranked.","https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Ftop-chrome-language-learning-extensions-the-great-comparison\u002F","2026-07-23T12:05:50.000+00:00","2026-07-23T10:10:37.000+00:00",27,[48,80,81,82],"Learning","students","Flashcard Learning","https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fcontent\u002Fimages\u002F2026\u002F07\u002Fchrome-language-learning-extensions-the-great-comparison.jpg","Top 10 Chrome Language Learning Extensions",[86,92],{"type":87,"title":88,"shortTitle":80,"icon":89,"description":90,"excerpt":91},"learning","Retain What You Read with Web Highlights","repeat","Most of what we read is forgotten within days. Web Highlights turns your highlights into spaced repetition flashcards so you can actively review and lock knowledge into long-term memory.","Spaced repetition and active recall beat passive re-reading. Web Highlights connects what you highlight on the web and in PDFs to short review sessions, so quotes and facts resurface when your brain needs them—not only when you remember to open the source again.",{"type":64,"title":65,"shortTitle":50,"icon":66,"description":67,"excerpt":68},"27 min read",{"id":95,"slug":96,"title":97,"description":98,"url":99,"publishedAt":100,"createdAt":101,"updatedAt":102,"featured":19,"readingTime":20,"tags":103,"imageUrl":106,"imageAlt":107,"faviconUrl":54,"publishedAtString":100,"category":108,"readTimeString":116},"6a5e332c909b7209ced49ae1","turn-youtube-videos-into-flashcards-youll-remember","Turn YouTube Videos into Flashcards You’ll Remember","You watched the whole talk and kept almost none of it. Highlight the transcript, let on-device AI write the cards — free, private, no signup.","https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fturn-youtube-videos-into-flashcards-youll-remember\u002F","2026-07-20T19:00:23.000+00:00","2026-07-20T14:39:40.000+00:00","2026-07-21T06:19:27.000+00:00",[104,82,80,105],"Youtube","AI","https:\u002F\u002Fweb-highlights.com\u002Fblog\u002Fcontent\u002Fimages\u002F2026\u002F07\u002Fturn-youtube-videos-into-flashcards.webp","Title: Turn YouTube Videos into Flashcards You’ll Remember; Subtitle: You watched the whole talk and kept almost none of it.",[109,110],{"type":87,"title":88,"shortTitle":80,"icon":89,"description":90,"excerpt":91},{"type":111,"title":112,"shortTitle":113,"icon":111,"description":114,"excerpt":115},"youtube","YouTube Notes, Transcripts & AI Summaries","YouTube","Turn videos into notes: transcripts, AI summaries, and highlights. See how Web Highlights fits into a modern YouTube learning stack.","Video is a top learning channel, but it’s hard to revisit. Web Highlights helps you pull the signal out of long videos—structured notes and summaries you can link back to the moment that mattered—without juggling five single-purpose extensions.","5 min read"]