<?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: Marvin</title>
    <description>The latest articles on DEV Community by Marvin (@marvinschopf).</description>
    <link>https://dev.to/marvinschopf</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%2F196974%2F23db826c-f475-4579-90ff-b3dab3f70708.png</url>
      <title>DEV Community: Marvin</title>
      <link>https://dev.to/marvinschopf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marvinschopf"/>
    <language>en</language>
    <item>
      <title>How to integrate Plausible into a Next.js project</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Wed, 17 Mar 2021 00:58:51 +0000</pubDate>
      <link>https://dev.to/marvinschopf/how-to-integrate-plausible-into-a-next-js-project-406g</link>
      <guid>https://dev.to/marvinschopf/how-to-integrate-plausible-into-a-next-js-project-406g</guid>
      <description>&lt;p&gt;&lt;a href="https://plausible.io"&gt;&lt;strong&gt;Plausible&lt;/strong&gt;&lt;/a&gt; is a new and &lt;strong&gt;privacy-friendly&lt;/strong&gt; analytics service that is an attractive alternative to Google Analytics. It only stores data that enables a &lt;strong&gt;simple analysis of visits&lt;/strong&gt; to your website. In doing so, Plausible does not track the user across multiple websites (does &lt;strong&gt;not&lt;/strong&gt; store cross-site cookies).&lt;/p&gt;

&lt;p&gt;In this article, I assume that you already have a functioning Next.js project running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;To include plausible in Next, we use the package &lt;code&gt;next-plausible&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So we install this first. Either with &lt;code&gt;yarn&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add next-plausible
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or using &lt;code&gt;npm&lt;/code&gt;:&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;next-plausible
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add Plausible to &lt;code&gt;_app.js&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Next, we extend the &lt;code&gt;_pages/app.js&lt;/code&gt; file (please read &lt;a href="https://nextjs.org/docs/advanced-features/custom-app"&gt;this article&lt;/a&gt; first if you do not already have this file).&lt;/p&gt;

&lt;p&gt;We wrap the existing &lt;code&gt;_app.js&lt;/code&gt; code with the &lt;code&gt;PlausibleProvider&lt;/code&gt;, which embeds the analysis script and makes it available to the rest of your project.&lt;/p&gt;

&lt;p&gt;Our code should now look like this:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../styles/globals.css&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;PlausibleProvider&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;next-plausible&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;({&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;pageProps&lt;/span&gt; &lt;span class="p"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PlausibleProvider&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR-DOMAIN-HERE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&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;pageProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/PlausibleProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&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;MyApp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please replace &lt;code&gt;YOUR-DOMAIN-HERE&lt;/code&gt; in the domain parameter with the &lt;strong&gt;domain&lt;/strong&gt; of your &lt;strong&gt;application&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Done!&lt;/em&gt;&lt;/strong&gt; The visits to your application are now tracked by Plausible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tracking goals
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Goals&lt;/strong&gt; can also be tracked with &lt;code&gt;next-plausible&lt;/code&gt;, for which a &lt;strong&gt;hook&lt;/strong&gt; is provided. This can be used as follows:&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;usePlausible&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;next-plausible&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Home&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;plausible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;usePlausible&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&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="nx"&gt;plausible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Button&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;Button&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;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;As soon as the button is pressed, an event is tracked at Plausible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's it!&lt;/strong&gt; Your Next.js application now tracks statistics and also goals with Plausible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Plausible is a &lt;strong&gt;great alternative&lt;/strong&gt; to &lt;strong&gt;Google Analytics&lt;/strong&gt;, which actually respects &lt;strong&gt;user privacy&lt;/strong&gt; and only tracks what is &lt;strong&gt;necessary&lt;/strong&gt; to provide you with &lt;strong&gt;simple analyses&lt;/strong&gt; of &lt;strong&gt;user behaviour&lt;/strong&gt; on your &lt;strong&gt;websit&lt;/strong&gt;e. With &lt;code&gt;next-plausible&lt;/code&gt; there is also a great solution to use Plausible with Next.js.&lt;/p&gt;

&lt;p&gt;You can learn more about &lt;code&gt;next-plausible&lt;/code&gt; in the related &lt;a href="https://github.com/4lejandrito/next-plausible"&gt;docs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>tutorial</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>How to embed DTube videos on a Hugo website</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Mon, 15 Feb 2021 18:03:28 +0000</pubDate>
      <link>https://dev.to/marvinschopf/how-to-embed-dtube-videos-on-a-hugo-website-57ph</link>
      <guid>https://dev.to/marvinschopf/how-to-embed-dtube-videos-on-a-hugo-website-57ph</guid>
      <description>&lt;p&gt;&lt;a href="https://gohugo.io"&gt;&lt;strong&gt;Hugo&lt;/strong&gt;&lt;/a&gt; is a fast and easy-to-use generator for static web pages, &lt;a href="https://d.tube"&gt;&lt;strong&gt;DTube&lt;/strong&gt;&lt;/a&gt; is a decentralised video streaming platform based on the Avalon blockchain, but originally launched on the Steem blockchain. Users are rewarded in the cryptocurrency &lt;a href="https://token.d.tube/"&gt;DTC&lt;/a&gt; (DTube Coin) for activities on the platform.&lt;/p&gt;

&lt;p&gt;Hugo already comes with a number of so-called &lt;a href="https://gohugo.io/content-management/shortcodes/"&gt;shortcodes&lt;/a&gt;, for example to easily embed YouTube videos.&lt;/p&gt;

&lt;p&gt;So in this post we will now look at how to develop your own reusable shortcode for embedding DTube videos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction to Hugo shortcodes&lt;/li&gt;
&lt;li&gt;Creating your own shortcodes&lt;/li&gt;
&lt;li&gt;DTube shortcode&lt;/li&gt;
&lt;li&gt;Full example&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a id="introduction-to-hugo-shortcodes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to Hugo shortcodes
&lt;/h2&gt;

&lt;p&gt;Hugo shortcodes allow frequently used, complex HTML snippets to be put into simple template files. For example, a YouTube video can simply be embedded with the following shortcode instead of the actual iFrame code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Example&lt;/span&gt;

{{&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nt"&gt;youtube&lt;/span&gt; &lt;span class="na"&gt;dQw4w9WgXcQ&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;This shortcode is then replaced in Hugo's build process by the YouTube embed iFrame, so that the embedded YouTube video then appears on the web page.&lt;/p&gt;

&lt;p&gt;&lt;a id="creating-your-own-shortcodes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating your own shortcodes
&lt;/h2&gt;

&lt;p&gt;Hugo searches for custom shortcodes in the following locations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;/layouts/shortcodes/&amp;lt;SHORTCODE&amp;gt;.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/themes/&amp;lt;THEME&amp;gt;/layouts/shortcodes/&amp;lt;SHORTCODE&amp;gt;.html&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first place is for when you want to add the shortcode to your project, the second place is for when you create a theme and want to include your custom shortcode with it.&lt;/p&gt;

&lt;p&gt;The name of the shortcode file is later also the name used to use the shortcode in a page.&lt;/p&gt;

&lt;p&gt;The format of the shortcode is simply an &lt;strong&gt;HTML file&lt;/strong&gt; that may contain some special parameters, such as the arguments like the ID of the video to be embedded. Of course, you can also use all the features of the Hugo/Go templating system.&lt;/p&gt;

&lt;p&gt;&lt;a id="dtube-shortcode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  DTube shortcode
&lt;/h2&gt;

&lt;p&gt;The normal iFrame embed code of a DTube video looks like this:&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;div&lt;/span&gt;
    &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt;
        &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;"&lt;/span&gt;
        &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://emb.d.tube/#!/&amp;lt;USERNAME&amp;gt;/&amp;lt;VIDEO ID&amp;gt;"&lt;/span&gt;
        &lt;span class="na"&gt;frameborder=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
        &lt;span class="na"&gt;allow=&lt;/span&gt;&lt;span class="s"&gt;"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"&lt;/span&gt;
        &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that &lt;strong&gt;two parameters&lt;/strong&gt; (as opposed to the one - the video ID - on YouTube) are required, the &lt;strong&gt;username&lt;/strong&gt; of the channel and the &lt;strong&gt;video ID&lt;/strong&gt;. So our shortcode now also has to accept two parameters instead of one like the YouTube shortcode.&lt;/p&gt;

&lt;p&gt;So all we really need to do is put this HTML code into a shortcode file and pass the arguments/parameters (username and video ID) to the iFrame.&lt;/p&gt;

&lt;p&gt;Arguments are passed to the shortcode in the &lt;code&gt;.Params&lt;/code&gt; array, so to get the first argument we have to use the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;{{ index .Params 0 }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So our shortcode should now look like this:&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;div&lt;/span&gt;
    &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt;
        &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;"&lt;/span&gt;
        &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://emb.d.tube/#!/{{ index .Params 0 }}/{{ index .Params 1 }}"&lt;/span&gt;
        &lt;span class="na"&gt;frameborder=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
        &lt;span class="na"&gt;allow=&lt;/span&gt;&lt;span class="s"&gt;"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"&lt;/span&gt;
        &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now save this file at &lt;code&gt;layouts/shortcodes/dtube.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;That's it!&lt;/em&gt;&lt;/strong&gt; We can now use the shortcode &lt;code&gt;{{&amp;lt;/* dtube USERNAME VIDEO_ID */&amp;gt;}}&lt;/code&gt; at any point on our page and the DTube video will be embedded at that point.&lt;/p&gt;

&lt;p&gt;&lt;a id="full-example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Full example
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;layouts/shortcodes/dtube.html&lt;/code&gt;&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;div&lt;/span&gt;
    &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt;
        &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;"&lt;/span&gt;
        &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://emb.d.tube/#!/{{ index .Params 0 }}/{{ index .Params 1 }}"&lt;/span&gt;
        &lt;span class="na"&gt;frameborder=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
        &lt;span class="na"&gt;allow=&lt;/span&gt;&lt;span class="s"&gt;"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"&lt;/span&gt;
        &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>dtube</category>
      <category>hugo</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Deploy Hugo site to Workers Sites using GitHub Actions</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Mon, 15 Feb 2021 02:07:42 +0000</pubDate>
      <link>https://dev.to/marvinschopf/how-to-deploy-hugo-sites-to-cloudflare-workers-sites-using-github-actions-2opg</link>
      <guid>https://dev.to/marvinschopf/how-to-deploy-hugo-sites-to-cloudflare-workers-sites-using-github-actions-2opg</guid>
      <description>&lt;p&gt;&lt;strong&gt;In this post we look at how to deploy Hugo sites to Cloudflare Workers Sites using GitHub Actions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cloudflare &lt;a href="https://developers.cloudflare.com/workers/platform/sites"&gt;Workers Sites&lt;/a&gt; is Cloudflare's service for hosting static websites directly on Cloudflare's edge nodes. &lt;a href="https://gohugo.io"&gt;Hugo&lt;/a&gt; is a program for generating static web pages easily and quickly.  &lt;/p&gt;

&lt;p&gt;If your static website is already in a repository on GitHub, using GitHub Actions is the best way to automate building your website, uploading to Workers Sites and so on, saving you a lot of manual work.&lt;/p&gt;

&lt;p&gt;This post already assumes that your Hugo site is on GitHub and also that an associated Workers Site &lt;a href="https://developers.cloudflare.com/workers/platform/sites/start-from-existing"&gt;has already been set up&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction to GitHub Actions&lt;/li&gt;
&lt;li&gt;Install Hugo and build site&lt;/li&gt;
&lt;li&gt;Publish to Cloudflare Workers Sites&lt;/li&gt;
&lt;li&gt;Full example&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a id="introduction-to-github-actions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to GitHub Actions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt; is a service from GitHub that automates regular tasks (e.g. building the software, publishing, testing, etc) into once-defined workflows, and then automates them, for example, when a release is created, when pushed to the main branch, when an issue is created, and so on.  &lt;/p&gt;

&lt;p&gt;The workflows are stored in the &lt;code&gt;.github/workflows&lt;/code&gt; folder and are written as &lt;code&gt;.yml&lt;/code&gt; files.&lt;/p&gt;

&lt;p&gt;For example, a simple workflow might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Workflow Example&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$default-branch&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$default-branch&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo Hello World!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This workflow simply checks out the latest version of the repository from the default branch and then prints &lt;code&gt;Hello World!&lt;/code&gt; to the console. The workflow runs on the latest Ubuntu version, &lt;code&gt;ubuntu-latest&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;All commands to be executed are specified under &lt;code&gt;steps&lt;/code&gt;. Actions created by other users can be specified with &lt;code&gt;uses&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a id="install-hugo-and-build-site"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Hugo and build site
&lt;/h2&gt;

&lt;p&gt;To install Hugo and build the page, we use an action developed by another user, &lt;a href="https://github.com/marketplace/actions/hugo-setup"&gt;&lt;code&gt;peaceiris/actions-hugo&lt;/code&gt;&lt;/a&gt;. We configure this action to always install the latest and extended version of Hugo.&lt;/p&gt;

&lt;p&gt;So now our steps section of the workflow configuration looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Hugo&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;peaceiris/actions-hugo@v2&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;hugo-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;latest'&lt;/span&gt;
    &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build site&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hugo --minify&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first step checks out the latest version of the repository, the second step installs Hugo, and the third step builds a minified version of the site.&lt;/p&gt;

&lt;p&gt;&lt;a id="publish-to-cloudflare-workers-sites"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Publish to Cloudflare Workers Sites
&lt;/h2&gt;

&lt;p&gt;As previously stated, this post assumes that a Cloudflare Workers Site has already been initialized &lt;a href="https://developers.cloudflare.com/workers/platform/sites/start-from-existing"&gt;as described here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To upload the built site to Cloudflare Workers Sites, we use the &lt;a href="https://github.com/marketplace/actions/deploy-to-cloudflare-workers-with-wrangler"&gt;cloudflare/wrangler-action&lt;/a&gt; officially provided by Cloudflare.  &lt;/p&gt;

&lt;p&gt;So now we add this step to the &lt;code&gt;steps&lt;/code&gt; section of our workflow as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Hugo&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;peaceiris/actions-hugo@v2&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;hugo-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;latest'&lt;/span&gt;
    &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build site&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hugo --minify&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish to Workers Sites&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cloudflare/wrangler-action@1.3.0&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;apiToken&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.CF_API_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the new step, there is now also a reference to a secret called &lt;code&gt;CF_API_TOKEN&lt;/code&gt;. We need to set this to a Cloudflare API token with some Workers permissions in our repository settings.&lt;/p&gt;

&lt;p&gt;This API key can be created in the Cloudflare settings under My Profile &amp;gt; API Tokens.&lt;/p&gt;

&lt;p&gt;The new API token must be assigned the following permissions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All accounts: Workers KV Storage:Edit, Workers Scripts:Edit, Account Settings:Read.&lt;/li&gt;
&lt;li&gt;All zones (or only the "zone" through which the website will later be accessible): Workers Routes:Edit&lt;/li&gt;
&lt;li&gt;All users: User Details:Read&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This key can now be stored in the repository settings in the section Secrets under the name &lt;code&gt;CF_API_TOKEN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a id="full-example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Full example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build &amp;amp; Publish&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$default-branch&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$default-branch&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Hugo&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;peaceiris/actions-hugo@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;hugo-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;latest'&lt;/span&gt;
        &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build site&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hugo --minify&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish to Workers Sites&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cloudflare/wrangler-action@1.3.0&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;apiToken&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.CF_API_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Done!&lt;/em&gt;&lt;/strong&gt; Now every time someone pushes to the main branch, the website is built using hugo and published to Cloudflare Workers Sites.&lt;/p&gt;

&lt;p&gt;&lt;a id="conclusion"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Hugo is one of the easiest and fastest tools to build static websites. Cloudflare Workers Sites is a relative newcomer to the static hosting market, but with Cloudflare's long established and fast network, your website is close to your users and speed is guaranteed.&lt;/p&gt;

&lt;p&gt;Using GitHub Actions, the manual building and publishing process can then also be automated, reducing manual effort to a minimum.&lt;/p&gt;

</description>
      <category>hugo</category>
      <category>tutorial</category>
      <category>cloudflare</category>
      <category>actions</category>
    </item>
    <item>
      <title>How to verify school email addresses in Node.js</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Sat, 13 Feb 2021 17:50:14 +0000</pubDate>
      <link>https://dev.to/marvinschopf/how-to-verify-school-email-addresses-in-node-js-2675</link>
      <guid>https://dev.to/marvinschopf/how-to-verify-school-email-addresses-in-node-js-2675</guid>
      <description>&lt;p&gt;&lt;strong&gt;In this post, we look at how school email addresses can be verified easily and quickly in Node.js.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is especially useful when a service wants to give certain perks or benefits to students or teachers. Often this is done using paid enterprise service providers, but in the vast majority of cases, verification can also be done quickly and free of charge using the user's email address.&lt;/p&gt;

&lt;p&gt;Unfortunately, one disadvantage of most modules for checking school emails is that they only check if the domain ends in ".edu", which eliminates all international educational institutions as they cannot use an ".edu" domain.  &lt;/p&gt;

&lt;p&gt;The module used in this article is based on the Jetbrains dataset, which contains thousands of international educational institutions and is constantly growing.  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; I am the developer of the module mainly used in this post.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;The only requirement to verify a user's student status is a confirmed email address (or more precisely, domain of the email address, for example) of the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;The installation of the required modules in an already initialised and set up Node.js project can easily be done with &lt;code&gt;npm&lt;/code&gt;:&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;swot-node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or using &lt;code&gt;yarn&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add swot-node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;First we import the installed library:&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;const&lt;/span&gt; &lt;span class="nx"&gt;swot&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="s2"&gt;swot-node&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;After that, the use is very simple. Any URL containing a domain can be entered as input. This does not necessarily have to be an email address, but it makes the most sense when verifying students, for example.&lt;/p&gt;

&lt;p&gt;The use is asynchronous via Promises or &lt;code&gt;async&lt;/code&gt; / &lt;code&gt;await&lt;/code&gt;:&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="nx"&gt;swot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isAcademic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example@stanford.edu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// The email belongs to an educational institution!&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="s2"&gt;The email belongs to an educational institution!&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// The email does not belong to an educational institution!&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="s2"&gt;The email does not belong to an educational institution!&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is also possible to get the name(s) of the educational institution:&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="nx"&gt;swot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getSchoolNames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example@stanford.edu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// URL does not belong to an academic institution&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="s2"&gt;URL does not belong to an academic institution&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&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;span class="c1"&gt;// URL ends on a TLD reserved for academic institutions, but has no entry of its own in the database&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="s2"&gt;URL ends on a TLD reserved for academic institutions, but has no entry of its own in the database&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Domain has an entry and there are also names in the database&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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// =&amp;gt; [ 'Stanford University' ]&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 exact possible return values of the functions can be found in the &lt;a href="https://swot.js.org"&gt;documentation&lt;/a&gt; of the library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full example
&lt;/h2&gt;



&lt;div class="highlight js-code-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;swot&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="s2"&gt;swot-node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="c1"&gt;// Just check if email belongs to an academic institution&lt;/span&gt;
&lt;span class="nx"&gt;swot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isAcademic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example@stanford.edu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// The email belongs to an educational institution!&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="s2"&gt;The email belongs to an educational institution!&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// The email does not belong to an educational institution!&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="s2"&gt;The email does not belong to an educational institution!&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="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Check if email belongs to an academic institution and get name(s) of institution&lt;/span&gt;
&lt;span class="nx"&gt;swot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getSchoolNames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example@stanford.edu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// URL does not belong to an academic institution&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="s2"&gt;URL does not belong to an academic institution&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&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;span class="c1"&gt;// URL ends on a TLD reserved for academic institutions, but has no entry of its own in the database&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="s2"&gt;URL ends on a TLD reserved for academic institutions, but has no entry of its own in the database&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Domain has an entry and there are also names in the database&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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// =&amp;gt; [ 'Stanford University' ]&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;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;To check in Node.js whether an email address belongs to a student, it is not necessary to use a paid commercial service.  &lt;/p&gt;

&lt;p&gt;Instead, you can simply use free open source software, which is maintained by the community and thus also guarantees a much larger and higher quality data set.  &lt;/p&gt;

&lt;p&gt;More about the library &lt;code&gt;swot-node&lt;/code&gt; can be found in the &lt;a href="https://swot.js.org"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>howto</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
