<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: sil-vio</title>
    <description>The latest articles on DEV Community by sil-vio (@silvio).</description>
    <link>https://dev.to/silvio</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F301288%2F08eabb42-e75f-46ae-9fa4-cb94f9708303.png</url>
      <title>DEV Community: sil-vio</title>
      <link>https://dev.to/silvio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/silvio"/>
    <language>en</language>
    <item>
      <title>How to Create a Web Component in Svelte</title>
      <dc:creator>sil-vio</dc:creator>
      <pubDate>Sun, 05 Jan 2020 09:55:25 +0000</pubDate>
      <link>https://dev.to/silvio/how-to-create-a-web-components-in-svelte-2g4j</link>
      <guid>https://dev.to/silvio/how-to-create-a-web-components-in-svelte-2g4j</guid>
      <description>&lt;p&gt;In this article we will see how to create a web components using the Svelte framework.&lt;br&gt;
Before we start writing the code, let's first see what a web components is.&lt;/p&gt;
&lt;h2&gt;
  
  
  Intro to Web Components
&lt;/h2&gt;

&lt;p&gt;Web components are a set of web platform APIs that allow you to create new custom, reusable and encapsulated HTML tags for use in web pages and web apps. Custom components and widgets are based on web component standards, work on modern browsers and they can be used with any HTML-compatible JavaScript library or framework.&lt;/p&gt;

&lt;p&gt;Web components are based on four main specifications:&lt;/p&gt;
&lt;h3&gt;
  
  
  Custom Elements
&lt;/h3&gt;

&lt;p&gt;Custom elements provide a way to build own fully-featured DOM elements. By defining a custom element, authors can inform the parser how to properly construct an element and how elements of that class should react to changes. Custom elements contain their own semantics, behaviors, markup and can be shared across frameworks and browsers.&lt;/p&gt;
&lt;h3&gt;
  
  
  Shadow DOM
&lt;/h3&gt;

&lt;p&gt;The shadow DOM specification defines how to use encapsulated style and markup in web components. Being able to keep the markup structure, style, and behavior hidden and separate from other code on the page so that different parts do not clash.&lt;/p&gt;
&lt;h3&gt;
  
  
  ES Modules
&lt;/h3&gt;

&lt;p&gt;The ES Modules specification defines the inclusion and reuse of JS documents in a standards based, modular, performant way. The JavaScript specification defines a syntax for modules, as well as some host-agnostic parts of their processing model. The specification defines the rest of their processing model: how the module system is bootstrapped, via the script element with type attribute set to "module", and how modules are fetched, resolved, and executed&lt;/p&gt;
&lt;h3&gt;
  
  
  HTML Template
&lt;/h3&gt;

&lt;p&gt;The HTML template element specification defines how to declare fragments of markup that go unused at page load, but can be instantiated later on at runtime. &lt;/p&gt;

&lt;p&gt;Web Components technology can be used independently or collectively.&lt;/p&gt;
&lt;h3&gt;
  
  
  How do I use a web component?
&lt;/h3&gt;

&lt;p&gt;Using a web components is very simple. For example, it is possible to use the component present in the library of web components released from polymer, such as the following component:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.webcomponents.org/element/@polymer/paper-button" rel="noopener noreferrer"&gt;https://www.webcomponents.org/element/@polymer/paper-button&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Starting from a simple web page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;This is the title of the webpage!&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Test Page&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is an example paragraph.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It's possible to import the script that contains the web components to start using the library component as if this were a simple html element.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;This is the title of the webpage!&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://npm-demos.appspot.com/@polymer/paper-button@3.0.1/paper-button.js?@polymer/paper-button@3.0.1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Test Page&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is an example paragraph.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;paper-button&lt;/span&gt; &lt;span class="na"&gt;raised&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"indigo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;button&lt;span class="nt"&gt;&amp;lt;/paper-button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  What is Svelte?
&lt;/h2&gt;

&lt;p&gt;Svelte is a JavaScript framework written by Rich Harris. Svelte applications do not include framework references. &lt;br&gt;
Whereas traditional frameworks like React, Vue or Angular do the bulk of their work in the browser, Svelte shifts that work into a compile step that happens when you build your app.&lt;br&gt;
Svelte generates code to manipulate the DOM, which may give better client run-time performance.&lt;/p&gt;

&lt;p&gt;Instead of using techniques like virtual DOM diffing, Svelte writes code that surgically updates the DOM when the state of your app changes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Svelte implementation of TodoMVC weighs 3.6kb zipped. For comparison, React plus ReactDOM without any app code weighs about 45kb zipped. It takes about 10x as long for the browser just to evaluate React as it does for Svelte to be up and running with an interactive TodoMVC.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introducing Svelte: Frameworks without the framework&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  How to make a simple svelte web applications
&lt;/h3&gt;

&lt;p&gt;To create a new svelte project we can start from the official template &lt;a href="https://github.com/sveltejs/template" rel="noopener noreferrer"&gt;https://github.com/sveltejs/template&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;To create a new project in the my-svelte-project directory, install its dependencies, and start a server you can type the following commands:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx degit sveltejs/template my-svelte-project
&lt;span class="nb"&gt;cd &lt;/span&gt;my-svelte-project
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;By accessing the url &lt;a href="http://localhost:5000" rel="noopener noreferrer"&gt;http://localhost:5000&lt;/a&gt; you will see the hello-world web app.&lt;/p&gt;

&lt;p&gt;For this example we will create a clock component, you can copy the content of the file app.svelte from this link: &lt;a href="https://svelte.dev/examples#clock" rel="noopener noreferrer"&gt;https://svelte.dev/examples#clock&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Compiling to a custom elements (aka web components)
&lt;/h3&gt;

&lt;p&gt;Svelte components can also be compiled to custom elements (aka web components) using the customElement: true compiler option. You should specify a tag name for the component using the &lt;a&gt;svelte:options&lt;/a&gt; element.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svelte:options&lt;/span&gt; &lt;span class="na"&gt;tag=&lt;/span&gt;&lt;span class="s"&gt;"my-element"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;By default custom elements are compiled with accessors: true, which means that any props are exposed as properties of the DOM element. To prevent this, add accessors={false} to &lt;a&gt;svelte:options&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To build to custom element we must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add customElement: true, to the rollup.config.js file:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nx"&gt;svelte&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;customElement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;add in App.svelte
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svelte:options&lt;/span&gt; &lt;span class="na"&gt;tag=&lt;/span&gt;&lt;span class="s"&gt;"svelte-clock"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In case you not define this svelte:option the compiler will warning you with the following message&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;svelte plugin: No custom element &lt;span class="s1"&gt;'tag'&lt;/span&gt; option was specified. To automatically register a custom element, specify a name with a hyphen &lt;span class="k"&gt;in &lt;/span&gt;it, e.g. &amp;lt;svelte:options &lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"my-thing"&lt;/span&gt;/&amp;gt;. To hide this warning, use &amp;lt;svelte:options &lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;null&lt;span class="o"&gt;}&lt;/span&gt;/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;run "npm run build"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During development (npm run dev), live reloading will be enabled. This means that any changes made to your custom-element or the HTML will be immediately reflected in the browser.&lt;/p&gt;

&lt;p&gt;Once the web components is ready we can run “npm run build” which will compile a minified, production-ready version of your custom element in the public/bundle.js file.&lt;br&gt;
The compiler will take care of creating the Shadow DOM, applying attributes/properties, and defining your custom element.&lt;/p&gt;

&lt;p&gt;To test the web components created we can utilize the http-server.&lt;br&gt;
To install we can execute the following command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;http-server &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then we can create in the public directory the index.html, importing the bundle.js and declaring the custom element “svelte-clock”:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;This is the title of the webpage!&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"bundle.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Test Page&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is an example paragraph.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;svelte-clock/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Executing the following command we can see the components in action:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; http-server &lt;span class="nt"&gt;-p&lt;/span&gt; 8080 &lt;span class="nt"&gt;-c-1&lt;/span&gt; public/
Starting up http-server, serving public/
Available on:
  http://127.0.0.1:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Svelte Web Components: Conclusion
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Properties
&lt;/h4&gt;

&lt;p&gt;Any props that your custom element accepts will automatically be transformed to element attributes at compile time. It is recommended to stick with lowercase attribute names as naming conventions like camelCase or PascalCase will not work in HTML.&lt;/p&gt;

&lt;p&gt;To test we can add a simple properties to the custom element.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;clocktitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Svelte Clock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
...
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{clocktitle}&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In our index.html we can now set the value&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svelte-clock&lt;/span&gt; &lt;span class="na"&gt;clocktitle=&lt;/span&gt;&lt;span class="s"&gt;"My Clock"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/svelte-clock&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Events
&lt;/h4&gt;

&lt;p&gt;Custom events emitted from within a Svelte 3 wrapped as a web-component do not bubble up to the web-component itself as normal DOM events (the custom event by default does not go past the boundaries of the shadowDom) and can not be handled in the usual manner within the template.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svelte-clock&lt;/span&gt; &lt;span class="na"&gt;custom-event=&lt;/span&gt;&lt;span class="s"&gt;"handler()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/sveltejs/svelte/issues/3119" rel="noopener noreferrer"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        Events are not emitted from components compiled to a custom element
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#3119&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/vogloblinsky" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars3.githubusercontent.com%2Fu%2F2841805%3Fv%3D4" alt="vogloblinsky avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/vogloblinsky" rel="noopener noreferrer"&gt;vogloblinsky&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/sveltejs/svelte/issues/3119" rel="noopener noreferrer"&gt;&lt;time&gt;Jun 26, 2019&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;The native Svelte syntax for listening events on:mycustomevent doesn't works with events dispatched by a Svelte component exported to Custom Element.&lt;/p&gt;
&lt;p&gt;May be related to this ? &lt;a href="https://github.com/sveltejs/svelte/blob/a0e0f0125aa554b3f79b0980922744ee11857069/src/runtime/internal/Component.ts#L162-L171" rel="noopener noreferrer"&gt;https://github.com/sveltejs/svelte/blob/a0e0f0125aa554b3f79b0980922744ee11857069/src/runtime/internal/Component.ts#L162-L171&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is a reproduction repository :&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/vogloblinsky/svelte-3-wc-debug" rel="noopener noreferrer"&gt;https://github.com/vogloblinsky/svelte-3-wc-debug&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;svelte3-raw&lt;/h2&gt;
&lt;p&gt;Example using just Svelte syntax. Inner component dispatch a custom event 'message'. App component listen to it using on:message&lt;/p&gt;
&lt;p&gt;It works !&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//Inner.svelte
&amp;lt;script&amp;gt;
    import { createEventDispatcher } from 'svelte';

    const dispatch = createEventDispatcher();

    function sayHello() {
        console.log('sayHello in child: ', 'Hello!');
        dispatch('message', {
            text: 'Hello!'
        });
    }
&amp;lt;/script&amp;gt;

&amp;lt;button on:click={sayHello}&amp;gt;
    Click to say hello
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//App.svelte
&amp;lt;script&amp;gt;
    import Inner from './Inner.svelte';

    function handleMessage(event) {
        console.log('handleMessage in parent: ', event.detail.text);
    }
&amp;lt;/script&amp;gt;

&amp;lt;Inner on:message={handleMessage}/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;svelte3-wc&lt;/h2&gt;
&lt;p&gt;Example using just Svelte syntax and exporting component to Web Components. Inner component dispatch a custom event 'message'. App component listen to it using on:message&lt;/p&gt;
&lt;p&gt;Same syntax doesn't work.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//Inner.svelte
&amp;lt;svelte:options tag="inner-btn"/&amp;gt;
&amp;lt;script&amp;gt;
    import { createEventDispatcher } from 'svelte';

    const dispatch = createEventDispatcher();

    function sayHello() {
        console.log('sayHello in child: ', 'Hello!');
        dispatch('message', {
            text: 'Hello!'
        });
    }
&amp;lt;/script&amp;gt;

&amp;lt;button on:click={sayHello}&amp;gt;
    Click to say hello
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//App.svelte
&amp;lt;svelte:options tag="my-app" /&amp;gt;
&amp;lt;script&amp;gt;
    import Inner from './Inner.svelte';

    function handleMessage(event) {
        console.log('handleMessage in parent: ', event.detail.text);
    }
&amp;lt;/script&amp;gt;

&amp;lt;inner-btn on:message={handleMessage}/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vanilla JS works fine in public/index.html&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const button = document
                    .querySelector('my-app')
                    .shadowRoot.querySelector('inner-btn');

                button.$on('message', e =&amp;gt; {
                    console.log('handleMessage in page');
                });
&lt;/code&gt;&lt;/pre&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sveltejs/svelte/issues/3119" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;To make it cross the boundaries of shadowDom we have to create a Custom Event as mentioned in the v2 docs for svelte. Custom events can be created in your Svelte component using the CustomEvent api. After defining a custom event, you can dispatch that event by calling this.dispatchEvent(event) in response to changes in your component.&lt;br&gt;
Custom events cannot be dispatched in response to lifecycle methods. For instance, if you try to dispatch a custom event in your onMount lifecycle method, your event will not be dispatched.&lt;/p&gt;

&lt;p&gt;To add a events we can add a button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="s"&gt;"{dispatchSavedDateEvent}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Save Date&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;when is clicked we can emit a custom event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;dispatchSavedDateEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[dispatchSecondIsElapsedEvent] time: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="c1"&gt;// 1. Create the custom event.&lt;/span&gt;
   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CustomEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;savedData&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;bubbles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;cancelable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;composed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// makes the event jump shadow DOM boundary&lt;/span&gt;
   &lt;span class="p"&gt;});&lt;/span&gt;

   &lt;span class="c1"&gt;// 2. Dispatch the custom event.&lt;/span&gt;
   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The read-only composed property of the Event interface returns a Boolean which indicates whether or not the event will propagate across the shadow DOM boundary into the standard DOM.&lt;/p&gt;

&lt;p&gt;An alternative method is to utilize createEventDispatcher&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createEventDispatcher&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createEventDispatcher&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;second&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10 seconds elapsed!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
     &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the index.html we must subscribe to the new event in the following way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;svelte-clock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;second&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[index.html][second]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Imports
&lt;/h4&gt;

&lt;p&gt;To import Svelte components we must declare each nested elements with the tag&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svelte:option&lt;/span&gt; &lt;span class="na"&gt;tag=&lt;/span&gt;&lt;span class="s"&gt;"my-nested-element”&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Declaring child components as custom elements, these elements are also available to the consumer.&lt;br&gt;
The nested element use the same Shadow DOM as the parent, there is no way to set the Shadow DOM mode to "closed" for the nested element.&lt;/p&gt;

&lt;p&gt;The main advantage in using Svelte.js for creating web components is that the final component has very small dimensions. In our small example the web component packaged in the bundle.js weighs only 7170 bytes, dimensions that if compared with web components created by other frameworks make our web components tens of times smaller and faster to be executed by the browser.&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>javascript</category>
      <category>web</category>
      <category>components</category>
    </item>
    <item>
      <title>How to make a PWA in Angular </title>
      <dc:creator>sil-vio</dc:creator>
      <pubDate>Thu, 26 Dec 2019 20:10:23 +0000</pubDate>
      <link>https://dev.to/silvio/how-to-make-a-pwa-in-angular-2003</link>
      <guid>https://dev.to/silvio/how-to-make-a-pwa-in-angular-2003</guid>
      <description>&lt;h2&gt;
  
  
  Progressive Web App
&lt;/h2&gt;

&lt;p&gt;A Progressive Web App (PWA) is a web application that uses modern Web features to offer users an experience very similar to a native app.&lt;/p&gt;

&lt;p&gt;Unlike traditional web apps, progressive web apps are a hybrid between regular web pages and mobile applications. The term "progressive" refers to the fact that initially they are perceived as normal websites but progressively behave more and more like cross-platform mobile apps.&lt;/p&gt;

&lt;p&gt;The basic technical criteria for a site to be considered a Progressive Web App by the browser are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are hosted in HTTPS;&lt;/li&gt;
&lt;li&gt;They can be loaded and executed even while the user's device is offline. To obtain this functionality, Progressive Web Apps require &lt;em&gt;Service Workers&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;We have a reference Web App &lt;em&gt;Manifest&lt;/em&gt; with at least four key properties: name, short_name, start_url, and display.&lt;/li&gt;
&lt;li&gt;Have an icon at least 144 × 144 pixels in png format.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Manifest e Service Workers
&lt;/h2&gt;

&lt;p&gt;The browser features that allow normal websites to become PWAs are the "manifest" and the "service workers".&lt;/p&gt;

&lt;h3&gt;
  
  
  Manifest
&lt;/h3&gt;

&lt;p&gt;It is a simple JSON file that defines the basic parameters of the PWA, to control how the app should look to the user and define its appearance at launch: icons, other basic features such as colors, fonts, screen orientation and possibility of being installed on the home screen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Service Workers
&lt;/h3&gt;

&lt;p&gt;Technically, Service Workers provide a network proxy implemented as JavaScript script in the web browser to manage web / HTTP requests programmatically. Service workers are interposed between the network connection and the terminal providing the content. They are able to use cache mechanisms efficiently and allow error-free behavior during long periods of offline use.&lt;br&gt;
Today, SWs already include features such as push notifications and background sync. The main function is the ability to intercept and manage network requests, including programmatic management of a response cache. It is an API that allows you to support offline experiences by giving developers complete control of the experience.&lt;/p&gt;
&lt;h4&gt;
  
  
  App Shell
&lt;/h4&gt;

&lt;p&gt;For fast loading, service workers store the basic interface or "shell" of the web application in Responsive Web Design mode. This shell provides an initial static frame, layout or architecture in which content can be loaded both progressively and dynamically, allowing users to interact with the app despite the different levels of connection quality they have. Technically, the shell is a code that is stored locally in the mobile terminal browser cache.&lt;/p&gt;
&lt;h2&gt;
  
  
  Angular &amp;amp; PWA
&lt;/h2&gt;

&lt;p&gt;To create a PWA in Angular we must first create a normal web application. To do this we have to create a new project through the CLI provided by Angular.&lt;/p&gt;

&lt;p&gt;To install the cli you can run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed you can check the version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~&lt;span class="nv"&gt;$ &lt;/span&gt;ng version

     _                      _                 ____ _     ___
    / &lt;span class="se"&gt;\ &lt;/span&gt;  _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ &lt;span class="se"&gt;\ &lt;/span&gt;| &lt;span class="s1"&gt;'_ \ / _` | | | | |/ _` | '&lt;/span&gt;__|   | |   | |    | |
  / ___ &lt;span class="se"&gt;\|&lt;/span&gt; | | | &lt;span class="o"&gt;(&lt;/span&gt;_| | |_| | | &lt;span class="o"&gt;(&lt;/span&gt;_| | |      | |___| |___ | |
 /_/   &lt;span class="se"&gt;\_\_&lt;/span&gt;| |_|&lt;span class="se"&gt;\_&lt;/span&gt;_, |&lt;span class="se"&gt;\_&lt;/span&gt;_,_|_|&lt;span class="se"&gt;\_&lt;/span&gt;_,_|_|       &lt;span class="se"&gt;\_&lt;/span&gt;___|_____|___|
                |___/


Angular CLI: 8.3.21
Node: 13.3.0
OS: linux x64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a new application, called my-pwa, you need to run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ng new my-pwa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During the creation process you will be asked whether to add the routing component and which stylesheet format we want to use in our project.&lt;/p&gt;

&lt;p&gt;Now we can move on to transforming our angular web app into a Progressive Web App.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to add a Service Worker
&lt;/h3&gt;

&lt;p&gt;To add a service worker to the project you can use the angular CLI using the ng add @ angular / pwa command. The CLI will take care of enabling the application to use a service worker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ng add @angular/pwa &lt;span class="nt"&gt;--project&lt;/span&gt; my-pwa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command will perform the following actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;adds the @ angular / service-worker package to the project in package.json&lt;/li&gt;
&lt;li&gt;enable service worker support at build time in angular.json&lt;/li&gt;
&lt;li&gt;import and register the service worker in app.module.ts&lt;/li&gt;
&lt;li&gt;Update the index.html file:

&lt;ul&gt;
&lt;li&gt;include the link to the manifest.json file&lt;/li&gt;
&lt;li&gt;adds the meta theme-color tag&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Create a folder to place icons to support PWA installation&lt;/li&gt;

&lt;li&gt;Create the service worker configuration file ngsw-config.json&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;the ngsw-config.json file generated by the CLI contains the configuration of the cache policies and resources to be cached. &lt;br&gt;
By default the cached resources are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;index.html.&lt;/li&gt;
&lt;li&gt;favicon.ico.&lt;/li&gt;
&lt;li&gt;Build artifact (JS and CSS bundles).&lt;/li&gt;
&lt;li&gt;The files in the assets folder.&lt;/li&gt;
&lt;li&gt;Image and font in the build path (e.g. ./dist/my-pwa/)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since the ng serve command is not compatible with the sw it is not possible to test the functionality of a PWA in development mode, but it is necessary to start an external http server to test our PWA locally.&lt;/p&gt;

&lt;p&gt;In order to test if the configuration was successful we must now build our application for the production profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ng build &lt;span class="nt"&gt;--prod&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a local server we will use http-server, given its ease of use.&lt;br&gt;
To install it you need to run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;http-server &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make PWA available we can now run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;http-server &lt;span class="nt"&gt;-p&lt;/span&gt; 8080 &lt;span class="nt"&gt;-c-1&lt;/span&gt; dist/my-pwa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the server is started, at the url &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;, we can access our application and, if everything went ok, we should see the "+" button for installation in the address bar of our browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsilvio-giannini.it%2Fimg%2Fmy-pwa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsilvio-giannini.it%2Fimg%2Fmy-pwa.png" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see from the image above, our web application is installable.&lt;/p&gt;

&lt;p&gt;Well! we created our first Progressive Web Application!😊&lt;/p&gt;

</description>
      <category>angular</category>
      <category>pwa</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
