<?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: Louis Bayard</title>
    <description>The latest articles on DEV Community by Louis Bayard (@bayardlouis470).</description>
    <link>https://dev.to/bayardlouis470</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%2F349557%2F043d0e18-e9ee-4c3b-b15f-1c304c40d08d.jpeg</url>
      <title>DEV Community: Louis Bayard</title>
      <link>https://dev.to/bayardlouis470</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bayardlouis470"/>
    <language>en</language>
    <item>
      <title>Create Chrome Extension in React</title>
      <dc:creator>Louis Bayard</dc:creator>
      <pubDate>Thu, 19 Mar 2020 11:56:41 +0000</pubDate>
      <link>https://dev.to/bayardlouis470/create-chrome-extension-in-react-3pna</link>
      <guid>https://dev.to/bayardlouis470/create-chrome-extension-in-react-3pna</guid>
      <description>&lt;p&gt;When I moved to Edge weeks ago, I found there's no built-in strong password generator in Edge. Then I decide write one for it.&lt;/p&gt;

&lt;p&gt;Most of the extensions on marketplace are write many years ago, and they were written in raw HTML, CSS and JavaScript. But we have React and UI component libraries now, life should be easier.&lt;/p&gt;

&lt;p&gt;The problem I soon found is there's almost no tutorial for a React extension anywhere. That's why I decide to share everything here. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The source code is origin from my side project &lt;a href="https://10converters.com/tools/strong-password-generator"&gt;10converters.com&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;Repo on Github &lt;a href="https://github.com/bayardlouis470/strongpassword"&gt;strong password generator&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;Edge Extension Addons Store: &lt;a href="https://microsoftedge.microsoft.com/addons/detail/kbgpmjeanbjhhnappoclfgcaogkbehad"&gt;Strong Password Generator&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Star the repo on Github or leave a review on Edge Addons Store are both welcome!&lt;/p&gt;

&lt;h1&gt;
  
  
  Features of the extension
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wx02Nojc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8ltrw07xv7dq82w8q5w2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wx02Nojc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8ltrw07xv7dq82w8q5w2.png" alt="Strong Password Generator Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It generates a 15 characters long password with lowercased letters, uppercased letters, numbers and symbols.&lt;/p&gt;

&lt;p&gt;But it won't like Chrome built-in password manager, it doesn't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;copy to clipboard automatically&lt;/li&gt;
&lt;li&gt;fill in the password/confirm field in web page&lt;/li&gt;
&lt;li&gt;manage/backup your password somewhere, not in cloud, not even do it locally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keep everything running in client side, that means no server at all&lt;/li&gt;
&lt;li&gt;manual copy to clipboard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I tried to make it as simple as a one-day-job. Anyone who follows this tutorial could submit your own extension to Chrome Web Store or Microsoft Edge Extension Addons(what a long name) in a single day(but from my experience, Microsoft need 2-3 days to approve your submission).&lt;/p&gt;

&lt;h1&gt;
  
  
  Extension Basic
&lt;/h1&gt;

&lt;p&gt;Before dive into the details, I want to explain a little the basic structure of an extension of chromium based browser.&lt;/p&gt;

&lt;p&gt;This extension structure works on Chrome, Edge and Brave, and maybe other Chromium based browsers I don't know.&lt;/p&gt;

&lt;p&gt;There're several key parts of an extension:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p4YzsKsN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8ms6nlmnok1xivt1unzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p4YzsKsN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8ms6nlmnok1xivt1unzg.png" alt="Strong Password Generator Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  manifest
&lt;/h3&gt;

&lt;p&gt;manifest describes what's in the source package. It specified where browser could find background, content script, popup and option pages. As well as it describes permissions required by the extension.&lt;/p&gt;

&lt;h3&gt;
  
  
  background
&lt;/h3&gt;

&lt;p&gt;A piece of code which is launched when the extension launched, and won't be terminated until extension removed or browser shutdown.&lt;/p&gt;

&lt;p&gt;Background code has access to all chrome APIs, other parts are limited. But background doesn't have an UI and can not access DOM.&lt;/p&gt;

&lt;h3&gt;
  
  
  popup
&lt;/h3&gt;

&lt;p&gt;The UI which is popped up while user click on 'browser action' which is your extension icon button right to the browser address bar.&lt;/p&gt;

&lt;p&gt;Most extensions need a popup as entry.&lt;/p&gt;

&lt;h3&gt;
  
  
  options
&lt;/h3&gt;

&lt;p&gt;It's an optional part of the extension. Not all extensions has an options page. It is used as a configuration UI for the extension. Your extension has to provide an entry for it.&lt;/p&gt;

&lt;p&gt;If you have some something complicated to be configured, you need this.&lt;/p&gt;

&lt;h3&gt;
  
  
  content script
&lt;/h3&gt;

&lt;p&gt;Content script is a piece of JavaScript which runs in a tab with specific URL. the URL pattern is defined in manifest.json. If the URL matched with which is specified in manifest.json, browser will launch the content script. It will be terminated while the URL changed, or tab closed.&lt;/p&gt;

&lt;p&gt;If you want to manipulate DOM, you need content script.&lt;/p&gt;

&lt;p&gt;So you should already have idea of what these parts are doing now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which parts involved in Strong Password Generator extension
&lt;/h3&gt;

&lt;p&gt;Background, not in this tutorial, but there's an empty background.js in repo, just for future use.&lt;/p&gt;

&lt;p&gt;Popup, yes. That's the focus of this article. I will show you how to write a Popup in React + Material.&lt;/p&gt;

&lt;p&gt;Options, no.&lt;/p&gt;

&lt;p&gt;Content script, no.&lt;/p&gt;

&lt;h1&gt;
  
  
  Start from scratch
&lt;/h1&gt;

&lt;p&gt;Here're 5 steps to create an extension in React from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: create a react app
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$npx create-react-app extension
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a regular react app. Everything else are growing from this seed app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Modify public/manifest.json
&lt;/h2&gt;

&lt;p&gt;You've already had a public/manifest.json after CRA(create-react-app). Change the file as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "name": "Strong Password Generator",
    "version": "1.0.0",
    "manifest_version": 2,
    "description": "Strong password generator",
    "icons": {
        "512": "logo512.png"
    },
    "browser_action": {
        "default_icon": "logo512.png",
        "default_popup": "popup.html"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Create a build script(script/build.sh)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

build() {
    echo 'building react'

    rm -rf dist/*

    export INLINE_RUNTIME_CHUNK=false
    export GENERATE_SOURCEMAP=false

    react-scripts build

    mkdir -p dist
    cp -r build/* dist

    mv dist/index.html dist/popup.html
}

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

&lt;/div&gt;



&lt;p&gt;There're 2 things did in this script:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build react app with some specific environment variables set&lt;/li&gt;
&lt;li&gt;renamed index.html into popup.html&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;INLINE_RUNTIME_CHUNK=false disabled webpack generating inline JavaScript in HTML. Normally webpack will put its own runtime into HTML inline script. But inline script is not allowed by browser extension.&lt;/p&gt;

&lt;p&gt;Rename index.html into popup.html because it is required to be popup.html in manifest.json.&lt;/p&gt;

&lt;p&gt;After create script/build.sh, don't forget add x permission:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod +x script/build.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Modify package.json
&lt;/h2&gt;

&lt;p&gt;modify scripts like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"scripts": {
    "start": "react-scripts start",
    "build": "./script/build.sh",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Build and load into Chrome(or Edge)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you will get a 'dist' directory. Load it as unpacked extension in Chrome or Edge. You would see:&lt;/p&gt;

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

&lt;p&gt;The React extension is running.&lt;/p&gt;

&lt;h1&gt;
  
  
  To be continue
&lt;/h1&gt;

&lt;p&gt;There're still pending issues for a serious extension, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to handle Options page? It's another page rather than Popup, but CRA created a SPA.&lt;/li&gt;
&lt;li&gt;Is there any performance issue to write extension in React?&lt;/li&gt;
&lt;li&gt;My content script is going to inject some UI component into host pages, can React be applied in this scenario?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And maybe some other topics not related to React too much but still important for a serious extension:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to obfuscate source code, especially background.js&lt;/li&gt;
&lt;li&gt;I'm going to introduce Firebase in my extension, any tips?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All the above will be discussed in the next post if someone interests into these questions. Leave a comment below if you have any other questions, suggestions, any feedback are welcome.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>showdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Grade Calculator: Next.js Static HTML App</title>
      <dc:creator>Louis Bayard</dc:creator>
      <pubDate>Thu, 12 Mar 2020 07:33:06 +0000</pubDate>
      <link>https://dev.to/bayardlouis470/grade-calculator-next-js-static-html-app-4pnb</link>
      <guid>https://dev.to/bayardlouis470/grade-calculator-next-js-static-html-app-4pnb</guid>
      <description>&lt;p&gt;I worked on &lt;a href="https://10converters.com/calculators/grade-calculator"&gt;10converters.com&lt;/a&gt; as my React practice in past month. After some research I found next.js static HTML app is the best way for the project. Hope the sharing could help someone here.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Static HTML
&lt;/h1&gt;

&lt;p&gt;Static HTML is the best way for small websites, like blogs and online tools. The benefits of serverless includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;easy to deploy, static HTML + cloud functions(if necessary)&lt;/li&gt;
&lt;li&gt;cloud vendors manages scaling&lt;/li&gt;
&lt;li&gt;benefit global CDN of hosting vendor&lt;/li&gt;
&lt;li&gt;SEO friendly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But also I found some problems of it, I will mention that later.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Next.js
&lt;/h1&gt;

&lt;p&gt;I started this project from simply React + Material UI components. Soon I found search engines doesn't like this pure React because most search engine bots can't handle JavaScripts. &lt;/p&gt;

&lt;p&gt;Then I turned into static HTML, tried several solutions like react-snap, react-snapshot. None of them could render every page correctly, until I found Next.js.&lt;/p&gt;

&lt;p&gt;Next.js is not limited to SSR(server-side-rendering), it also could 'export' the whole site into static HTML, and it works perfect for all my pages.&lt;/p&gt;

&lt;p&gt;What you have to do is just write your app follows Next.js instruction, and then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;next export
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then you get everything you want. I assume you already know something about Next.js. Now, let's dive into only the part of static HTML exporting stuff.&lt;/p&gt;

&lt;h1&gt;
  
  
  getInitialProps
&lt;/h1&gt;

&lt;p&gt;Next.js use getInitialProps() to generate dehydrate data. I will show you that it is not mandatory for static HTML apps.&lt;/p&gt;

&lt;p&gt;in SSR mode, getInitialProps() will be called in case of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;in server side, if the app is not loaded by browser yet(a new request to your app)&lt;/li&gt;
&lt;li&gt;in client side, if the app is already loaded, and navigating to a new page via next/Link component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in static HTML mode, getInitialProps() will be called in case of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;while 'next export' is executing, that's also server side rendering, but not in runtime, but during transpiling.&lt;/li&gt;
&lt;li&gt;in client side, if the app is already loaded, and navigating to a new page via next/Link component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For SSR, getInitialProps() works perfect, but not in static HTML mode.&lt;/p&gt;

&lt;p&gt;The reason is in static HTML mode, getInitialProps() is called during transpiling, and then dehydrate data are generated before deploy. &lt;/p&gt;

&lt;p&gt;If your page renders depends on URL parameters or depends on something related to realtime stuff, like timestamp, user properties, getInitialProps() won't help.&lt;/p&gt;

&lt;p&gt;It could be executed in client side, but only if the app is already loaded and navigating to new page via next/Link component.&lt;/p&gt;

&lt;h1&gt;
  
  
  Links
&lt;/h1&gt;

&lt;p&gt;Never forget that we have static HTML apps for better search engine bot experience, not for better user experience.&lt;/p&gt;

&lt;p&gt;Links are essential feature of web, only &amp;lt;a&amp;gt; tag could be recognized by bots. &lt;/p&gt;

&lt;p&gt;For example, if you want to put a button which will navigate to another page, do like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Link href="/to-another-page" passHref&amp;gt;
    &amp;lt;Button component="a"&amp;gt;Another Page&amp;lt;/Button&amp;gt;
&amp;lt;/Link&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;make sure replace default &amp;lt;div&amp;gt; tag as &amp;lt;a&amp;gt; tag.&lt;/p&gt;

&lt;p&gt;Even for bots which could handle JavaScript, they won't 'CLICK' on your page, they just do rendering. If your link is not a &amp;lt;a&amp;gt; tag and depends on for example JavaScript history API, bots won't know them.&lt;/p&gt;

&lt;h1&gt;
  
  
  next/Link vs Material-UI Link
&lt;/h1&gt;

&lt;p&gt;For links in my &lt;a href="https://10converters.com/calculators/grade-calculator"&gt;Grade Calculator&lt;/a&gt; page the links below is just rendered by Material-UI link:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Link from '@material-ui/core/Link';

&amp;lt;Link href="/calculators/final-grade-calculator"&amp;gt;
    Final Grade Calculator
&amp;lt;/Link&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;next/Link is generally implemented by a push history API, as we mentioned above, search engines doesn't like it.&lt;/p&gt;

&lt;p&gt;Using @material-ui/core/Link components lost some of the benefits of Single Page App. for next/Link, relevant pages will be packed together, but if it's a @material-ui/core/Link used in Next.js app, linked pages(JavaScript sources) won't be packed together.&lt;/p&gt;

&lt;p&gt;The con using @material-ui/core/Link is all resources have to be reloaded each time user navigate to a new page. Pro is the size of single page is smaller.&lt;/p&gt;

&lt;p&gt;As this grade calculator is a small online tool, I assume people will not navigate to other pages. That's why I simply employed Link from Material-UI.&lt;/p&gt;

&lt;p&gt;If you are in other cases, try to find some other better solutions.&lt;/p&gt;

&lt;h1&gt;
  
  
  Error Page
&lt;/h1&gt;

&lt;p&gt;Next.js has a /page/_error.js for error page handling. It works in server side rendering well. _error.js could get HTTP state code via getInitialProps().&lt;/p&gt;

&lt;p&gt;In static HTML mode, like we said above in getInitialProps(), _error.js doesn't know what exact error is, is it a 404 or something else. But fortunately, because the app is static HTML, the only possible error is 404.&lt;/p&gt;

&lt;p&gt;So always render 404 in _error.js is fine.&lt;/p&gt;

&lt;h1&gt;
  
  
  NoSSR
&lt;/h1&gt;

&lt;p&gt;If some part of your app really depends on runtime user requests, like URL parameter. use NoSSR for the page or for components on the page.&lt;/p&gt;

&lt;p&gt;There're many NoSSR components available, I'm using Material-UI, so I use the NoSSR component comes with Material-UI.&lt;/p&gt;

&lt;h1&gt;
  
  
  At The End
&lt;/h1&gt;

&lt;p&gt;Even it is a very basic practice, I'd like to share the whole journey later about not only programming, but also deployment and many others. &lt;/p&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>javascript</category>
      <category>firebase</category>
    </item>
  </channel>
</rss>
