<?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: Lorenzo Millucci</title>
    <description>The latest articles on DEV Community by Lorenzo Millucci (@lmillucci).</description>
    <link>https://dev.to/lmillucci</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%2F292356%2F6c191a52-6bf3-4e3f-a698-42980656b320.jpeg</url>
      <title>DEV Community: Lorenzo Millucci</title>
      <link>https://dev.to/lmillucci</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lmillucci"/>
    <language>en</language>
    <item>
      <title>JavaScript: How to decode the GreenPass QR code</title>
      <dc:creator>Lorenzo Millucci</dc:creator>
      <pubDate>Thu, 15 Jul 2021 06:58:15 +0000</pubDate>
      <link>https://dev.to/lmillucci/javascript-how-to-decode-the-greenpass-qr-code-3dh0</link>
      <guid>https://dev.to/lmillucci/javascript-how-to-decode-the-greenpass-qr-code-3dh0</guid>
      <description>&lt;p&gt;The holidays are upon us and thanks to the advancement of vaccinations against the coronavirus pandemic it is finally possible to travel abroad.&lt;br&gt;
In particular, starting from July 1st, it is be possible to travel freely within the borders of the European Union thanks to the release of the so-called "green pass".&lt;/p&gt;

&lt;p&gt;But what is contained in the QR code that is sent to users? Thanks to the publication of &lt;a href="https://ec.europa.eu/health/sites/default/files/ehealth/docs/digital-green-certificates_dt-specifications_en.pdf"&gt;all the specifications of the vaccination pass&lt;/a&gt;, I had some fun creating a script in JavaScript to read its contents.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But before explaining how I read the QR code of the green pass, let me introduce myself: I'm Lorenzo Millucci and I'm a software engineer who loves working with Symfony. You can read all my post on &lt;a href="https://www.lorenzomillucci.it"&gt;my blog&lt;/a&gt; (in Italian)&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Reading the QR code
&lt;/h2&gt;

&lt;p&gt;In order to create a script to decode the QR code of the green pass, the first thing to do is to prepare the environment by installing some dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install base45 cbor jpeg-js jsqr pako
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point you are ready to import them into a script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const base45 = require('base45');
const cbor = require('cbor');
const fs = require('fs')
const jpeg = require('jpeg-js');
const jsQR = require("jsqr");
const pako = require('pako');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can start decoding the file containing the green pass. In this example I'm using the image file called &lt;code&gt;greenpass.jpg&lt;/code&gt; that I've downloaded directly from the Italian app &lt;code&gt;IO&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; if you used a different name or saved the file in another location, adjust the code accordingly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const greenpassJpeg = fs.readFileSync(__ dirname + '/greenpass.jpg');
const greenpassImageData = jpeg.decode(greenpassJpeg, {useTArray: true});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOTE 2: the &lt;code&gt;useTArray&lt;/code&gt; option passed to the decoder is used to make sure that the image is decoded as Uint8Array&lt;/p&gt;

&lt;p&gt;Once this is done you can pass the file to the QR code decoder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const decodedGreenpass = jsQR(greenpassImageData.data, greenpassImageData.width, greenpassImageData.height);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The string you get from this code is something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HC1: 6BFOXM% TS3DHPVO13J /G-/2YKVA.R/K86PP2FC1J9M$DI9C3 [....] CS62GMVR + B1YM K5MJ1K: K: 2JZLT6KM + DTVKPDUG $ E7F06FA3O6I-VA126Y0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To proceed with the decoding of the green pass you have to remove the first 4 characters of the string (which indicate the use of the &lt;a href="https://github.com/ehn-dcc-development/hcert-spec"&gt;HCERT protocol&lt;/a&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const greenpassBody = decodedGreenpass.data.substr(4);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, in order to have the data in readable format, you must first decode the string from the Base45 format and then decompress it using &lt;code&gt;zlib&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const decodedData = base45.decode(greenpassBody);
const output = pako.inflate(decodedData);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the certificate is encrypted using the &lt;a href="https://www.iana.org/assignments/cose/cose.xhtml"&gt;COSE format (CBOR Object Signing and Encryption)&lt;/a&gt; you have to decrypt it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const results = cbor.decodeAllSync(output);
[headers1, headers2, cbor_data, signature] = results[0].value;

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

&lt;/div&gt;



&lt;p&gt;The certificate contains various types of data useful to guarantee its validity but the part that contains the user's data is that contained in the variable cbor_data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const greenpassData = cbor.decodeAllSync(cbor_data);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, finally, it is possible to print the JSON with the user data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log (JSON.stringify(greenpassData[0].get(-260).get (1), null, 2));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example this is the content of my green pass:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "t": [
    {
      "sc": "2021-06- []",
      "but": "1606",
      "tt": "LP217198-3",
      "co": "IT",
      "tc": "Dr. [....]",
      "there": "[....]",
      "is": "Ministry of Health",
      "tg": "840539006",
      "tr": "26041 [....]"
    }
  ],
  "nam": {
    "fnt": "MILLUCCI",
    "fn": "MILLUCCI",
    "gnt": "LORENZO",
    "gn": "LORENZO"
  },
  "ver": "1.0.0",
  "dob": "1992-08-10"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sc&lt;/code&gt; indicates the date and time of the test
but it indicates "Marketing Authorization Holder" which simply indicates the body that put the test on the market&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tt&lt;/code&gt; indicates the type of test&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tc&lt;/code&gt; indicates the place where the test was performed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ci&lt;/code&gt; the unique certificate number (Unique Certificate Identifier or UVCI)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;is&lt;/code&gt; the entity that issued the certificate&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tg&lt;/code&gt; is the type of agent against which the vaccine acts (at the moment the only allowed value is 840539006 and that is COVID-19)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tr&lt;/code&gt; is the test result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To get all the details on the meaning of these acronyms you can read the &lt;a href="https://raw.githubusercontent.com/ehn-dcc-development/ehn-dcc-schema/release/1.3.0/DCC.combined-schema.json"&gt;official JSON Schema&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; my vaccination pass was obtained for having done the rapid test and therefore the data contained in it refers to an antigen test. The data contained in a green pass issued after a vaccine shot are different.&lt;/p&gt;

&lt;p&gt;The complete script can be read below or can be &lt;a href="https://gist.github.com/lmillucci/48804b0598553689fc5054da10e63231"&gt;found here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const base45 = require('base45');
const cbor = require('cbor');
const fs = require('fs')
const jpeg = require('jpeg-js');
const jsQR = require("jsqr");
const pako = require('pako');

// Set the path to the green pass QR
const FILE_PATH = __dirname + '/greenpass.jpg';

// Read image file
const greenpassJpeg = fs.readFileSync(FILE_PATH);
const greenpassImageData = jpeg.decode(greenpassJpeg, {useTArray: true});

// Decode QR
const decodedGreenpass = jsQR(greenpassImageData.data, greenpassImageData.width, greenpassImageData.height);

// Remove `HC1:` from the string
const greenpassBody = decodedGreenpass.data.substr(4);

// Data is Base45 encoded
const decodedData = base45.decode(greenpassBody);

// And zipped
const output = pako.inflate(decodedData);

const results = cbor.decodeAllSync(output);

[headers1, headers2, cbor_data, signature] = results[0].value;

const greenpassData = cbor.decodeAllSync(cbor_data);

console.log(JSON.stringify(greenpassData[0].get(-260).get(1), null, 2));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>greenpass</category>
    </item>
    <item>
      <title>Building a Vue 3 component with Typescript</title>
      <dc:creator>Lorenzo Millucci</dc:creator>
      <pubDate>Mon, 09 Mar 2020 17:45:48 +0000</pubDate>
      <link>https://dev.to/lmillucci/building-a-vue-3-component-with-typescript-4pge</link>
      <guid>https://dev.to/lmillucci/building-a-vue-3-component-with-typescript-4pge</guid>
      <description>&lt;p&gt;The alpha version of &lt;a href="https://github.com/vuejs/vue-next"&gt;Vue 3&lt;/a&gt; has been available for some time now!&lt;br&gt;
While I’m writing this post the alpha 8 version has just been released.&lt;/p&gt;

&lt;p&gt;The new version of Vue will bring with it an avalanche of enhancements and improvements but the most significant changes in the new version will be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Composition API: this is a much discussed feature inspired by the React hooks.&lt;/li&gt;
&lt;li&gt;Portals: render certain content outside the current component.&lt;/li&gt;
&lt;li&gt;Fragments: allows multiple root nodes.&lt;/li&gt;
&lt;li&gt;Updated v-model-API: it now accepts multiple models.&lt;/li&gt;
&lt;li&gt;Suspense: is a special component that renders a fallback content instead of your component until a condition is met (mostly for UX stuff).&lt;/li&gt;
&lt;li&gt;TypeScript: Vue now has full TypeScript support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since Vue 3 is still under active development some of its components may still have bugs or some API may change but it is already possible to start writing a simple application to start playing with the new features.&lt;/p&gt;

&lt;p&gt;Because I’m a big fan of TypeScript in this article I will describe you the steps that I followed to to create a new application with Vue 3 using TypeScript.&lt;br&gt;
But talk is cheap, let’s start setting up a new app 🙂&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up the project
&lt;/h2&gt;

&lt;p&gt;The first thing to do is to initialize a new application using the command on the next line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, add the dependencies needed by the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add vue@3.0.0-alpha.8
yarn add --dev yarn vue-loader@v16.0.0-alpha.3 webpack-cli webpack webpack-dev-server typescript ts-loader @vue/compiler-sfc@v3.0.0-alpha.8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now you have to define a simple webpack configuration creating the file &lt;code&gt;webpack.config.js&lt;/code&gt; and adding the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;VueLoaderPlugin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&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="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prod&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;devtool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prod&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;source-map&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cheap-module-eval-source-map&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/main.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;publicPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/dist/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&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;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;vue$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-loader&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;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;ts$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ts-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;appendTsSuffixTo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;vue$/&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&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;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vue/runtime-dom&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;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;VueLoaderPlugin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;devServer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;inline&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;hot&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;stats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;minimal&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;contentBase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;overlay&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="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So far so good, our setup is coming together, but it won’t compile TypeScript just yet, for that we need to add a &lt;code&gt;tsconfig.json&lt;/code&gt; file with the following rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allowJs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allowSyntheticDefaultImports"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"declaration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"experimentalDecorators"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es2015"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noImplicitAny"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noLib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sourceMap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strictPropertyInitialization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"suppressImplicitAnyIndexErrors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es2015"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"baseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exclude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"./node_modules"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"include"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"./src/**/*.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"./src/**/*.vue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After configuring Typescript and Webpack it is time to add a shortcut to start your application adding a new script to the &lt;code&gt;package.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="err"&gt;//...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Dependencies&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//...&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webpack-dev-server"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NOTE:&lt;/em&gt; to avoid error when you will import &lt;code&gt;*.vue&lt;/code&gt; files you have to add the following &lt;code&gt;shims-vue.d.ts&lt;/code&gt; file in &lt;code&gt;./src&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineComponent&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="s2"&gt;vue&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;Component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;defineComponent&lt;/span&gt;&lt;span class="o"&gt;&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="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Component&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;To test that the infrastructure built so far is working correctly you will need some things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have a simple &lt;code&gt;index.html&lt;/code&gt; in the root of the project
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello Vue 3!&lt;span class="nt"&gt;&amp;lt;/h1&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;"/dist/main.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Have a &lt;code&gt;/src&lt;/code&gt; folder &lt;/li&gt;
&lt;li&gt;Have &lt;code&gt;main.ts&lt;/code&gt; file to the project as follows:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/main.ts&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world from Typescript!&lt;/span&gt;&lt;span class="dl"&gt;'&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;Run the web server with &lt;code&gt;yarn dev&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If everything is working then connecting to &lt;code&gt;http://localhost:8080&lt;/code&gt; you should see the page we have just created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--byqNRz3P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ye1ijcbx5ug854u5z3rh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--byqNRz3P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ye1ijcbx5ug854u5z3rh.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To recap, at the end of these steps you should have the following architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── index.html
├── package.json
├── tsconfig.json
├── webpack.config.js
├── src
│    ├── shims-vue.d.ts
│    └── main.ts
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Let’s build a component
&lt;/h2&gt;

&lt;p&gt;Now that the environment needed to build the application is finally ready you can start creating your first Vue 3 component.&lt;/p&gt;

&lt;p&gt;First of all, add a new file called &lt;code&gt;App.vue&lt;/code&gt; inside the &lt;code&gt;src&lt;/code&gt; folder as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;This is a Vue 3 component!&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"increase"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Clicked {{ count }} times.&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&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="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&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;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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;increase&lt;/span&gt; &lt;span class="o"&gt;=&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;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, compared to Vue 2 in which to create a new Vue component it was necessary to create a Typescript class and extend Vue using &lt;code&gt;class MyClass extends Vue {}&lt;/code&gt;, now Vue 3 offers a &lt;code&gt;defineComponent()&lt;/code&gt; function.&lt;br&gt;
Inside the &lt;code&gt;defineComponent()&lt;/code&gt; function you can see a &lt;code&gt;setup&lt;/code&gt; function, which takes the props as the first argument. Since in this case the App component will be a top level component, no props will be passed (so I have omitted to pass them on).&lt;br&gt;
Also, as you can see from the code, whatever is returned by the &lt;code&gt;setup()&lt;/code&gt; method, it is then accessible from the template.&lt;/p&gt;

&lt;p&gt;Now that the Vue component has been created, you just have to import it into the &lt;code&gt;main.ts&lt;/code&gt; file as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&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;createApp&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&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;./App.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Also in this case you can see how compared to the previous version of Vue it is no longer necessary to initialize the new application with &lt;code&gt;const app = new Vue (....).$Mount('# app')&lt;/code&gt; but with Vue 3 it is possible to use the function &lt;code&gt;createApp()&lt;/code&gt; and the &lt;code&gt;mount()&lt;/code&gt; method to bind the application to a DOM selector.&lt;/p&gt;

&lt;p&gt;Finally, the last step is to edit the &lt;code&gt;index.html&lt;/code&gt; file to include the selector specified to Vue in the previous step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello Vue 3!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&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;"/dist/main.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;At this point, relaunching the application with &lt;code&gt;yarn dev&lt;/code&gt; you can start playing with the new Vue component just created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y0_jWGGq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ri6iqdvbnp6jo2bgzog3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y0_jWGGq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ri6iqdvbnp6jo2bgzog3.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;In this post I showed you how to create a very simple component using Vue 3, the composition API and Typescript. Obviously I have scratched just the tip of the iceberg and there are a thousand other features to try in Vue 3 but already with this simple component it is possible to appreciate the new "functional" approach with which it is possible to define the components in the next release of Vue.&lt;/p&gt;

&lt;p&gt;PS: All the code is available on &lt;a href="https://github.com/lmillucci/vue3-typescript-component"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Feel free to reach out to me! &lt;a href="https://www.lorenzomillucci.it/"&gt;Blog (in italian)&lt;/a&gt; || &lt;a href="https://twitter.com/LorenzoMillu"&gt;Twitter&lt;/a&gt; || &lt;a href="https://github.com/lmillucci"&gt;GitHub&lt;/a&gt; || &lt;a href="https://www.linkedin.com/in/lorenzo-millucci/"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>vue3</category>
    </item>
    <item>
      <title>Firefox: Installing Self-Signed certificate on Ubuntu</title>
      <dc:creator>Lorenzo Millucci</dc:creator>
      <pubDate>Mon, 16 Dec 2019 13:12:34 +0000</pubDate>
      <link>https://dev.to/lmillucci/firefox-installing-self-signed-certificate-on-ubuntu-4f11</link>
      <guid>https://dev.to/lmillucci/firefox-installing-self-signed-certificate-on-ubuntu-4f11</guid>
      <description>&lt;p&gt;While developing webapps you may need to use HTTPS to match production environment. &lt;br&gt;
For local purposes you may not need a real certificate and a self-signed SSL certificate could be enough.&lt;/p&gt;

&lt;p&gt;A self-signed certificate is a SSL certificate which is not signed by any of the recognized certification authorities. &lt;/p&gt;

&lt;p&gt;If you want you can create &lt;a href="https://dev.to/kauresss/2-minute-self-signed-ssl-certificate-for-localhost-5817"&gt;your self-signed certificate in 2 minutes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Browsers do not trust self-signed certificate by default and display an error message that warns the user that the site you are connecting to does not have a recognized certificate and that this could be a potential security risk.&lt;/p&gt;

&lt;p&gt;For local development these warnings could be pretty annoying so you may want to ensure that your browser recognizes your certificate as valid.&lt;/p&gt;

&lt;p&gt;Let's see how to add a self-signed certificate to Firefox!&lt;/p&gt;
&lt;h1&gt;
  
  
  Finding Firefox profile folder
&lt;/h1&gt;

&lt;p&gt;All the customizations you make in Firefox are stored in a special folder called &lt;code&gt;profile&lt;/code&gt;.&lt;br&gt;
To add a certificate the first thing to do is to find out where your proile is stored. You can find it simply by typing &lt;code&gt;about:profiles&lt;/code&gt; in Firefox’s address bar, and then press Enter. &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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F226fvl2ze0mhsnil5neu.jpg" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F226fvl2ze0mhsnil5neu.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The folder you are looking for is the one with label &lt;code&gt;Root Directory&lt;/code&gt;.&lt;br&gt;
For example my profile is stored at &lt;code&gt;/home/lorenzo/.mozilla/firefox/57w4ghfg.default-1394286602246-1560669052441&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Installing the certificate
&lt;/h1&gt;

&lt;p&gt;To install the certificate you have to ensure that &lt;code&gt;certutil&lt;/code&gt; is installed on your system.&lt;/p&gt;

&lt;p&gt;In case it is missing you can install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install libnss3-tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you are ready to add the certificate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;certutil -A -n "&amp;lt;CERT_NICKNAME&amp;gt;" -t "TC,," -i &amp;lt;PATH_FILE_CRT&amp;gt; -d sql:&amp;lt;FIREFOX_PROFILE_PATH&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CERT_NICKNAME: is an alias for the certificate&lt;/li&gt;
&lt;li&gt;PATH_FILE_CRT: is the path of the certificate you want to add &lt;/li&gt;
&lt;li&gt;FIREFOX_PROFILE_PATH: is the path where your Firefox profile is stored&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NOTE: if you want to know what &lt;code&gt;trustargs&lt;/code&gt; are you can &lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Reference/NSS_tools_:_certutil" rel="noopener noreferrer"&gt;read the documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example to add the certificate on my PC I have to use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;certutil -A -n "slope" -t "TC,," -i ~/Downloads/slope.crt -d sql:/home/lorenzo/.mozilla/firefox/57w4ghfg.default-1394286602246-1560669052441 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOTE: after you installed the certificate you have to restart Firefox for these changes to take effect.&lt;/p&gt;

&lt;h1&gt;
  
  
  Displaying installed certificates
&lt;/h1&gt;

&lt;p&gt;To ensure that the certificate is added correctly you can display all the installed certificates using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; certutil -d sql:&amp;lt;FIREFOX_PROFILE_PATH&amp;gt; -L      
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Removing a certificate
&lt;/h1&gt;

&lt;p&gt;If you need to remove an installed certificate you can do it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;certutil  -D -n "&amp;lt;CERT_NICKNAME&amp;gt;"  -d sql:&amp;lt;FIREFOX_PROFILE_PATH&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And voila! You're all done, ready and up and running!&lt;/p&gt;




&lt;p&gt;Feel free to reach out to me! &lt;a href="https://www.lorenzomillucci.it/" rel="noopener noreferrer"&gt;Blog (in italian)&lt;/a&gt; || &lt;a href="https://twitter.com/LorenzoMillu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; || &lt;a href="https://github.com/lmillucci" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; || &lt;a href="https://www.linkedin.com/in/lorenzo-millucci/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>ubuntu</category>
      <category>firefox</category>
      <category>ssl</category>
    </item>
  </channel>
</rss>
